~zulcss/samba/samab-3.4-test

« back to all changes in this revision

Viewing changes to source4/auth/system_session.c

  • Committer: Chuck Short
  • Date: 2010-05-20 18:57:13 UTC
  • Revision ID: zulcss@ubuntu.com-20100520185713-hwqvf9t50z830wck
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
   Authentication utility functions
 
4
   Copyright (C) Andrew Tridgell 1992-1998
 
5
   Copyright (C) Andrew Bartlett 2001
 
6
   Copyright (C) Jeremy Allison 2000-2001
 
7
   Copyright (C) Rafal Szczesniak 2002
 
8
   Copyright (C) Stefan Metzmacher 2005
 
9
 
 
10
   This program is free software; you can redistribute it and/or modify
 
11
   it under the terms of the GNU General Public License as published by
 
12
   the Free Software Foundation; either version 3 of the License, or
 
13
   (at your option) any later version.
 
14
   
 
15
   This program is distributed in the hope that it will be useful,
 
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
   GNU General Public License for more details.
 
19
   
 
20
   You should have received a copy of the GNU General Public License
 
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
22
*/
 
23
 
 
24
#include "includes.h"
 
25
#include "libcli/security/security.h"
 
26
#include "libcli/auth/libcli_auth.h"
 
27
#include "auth/credentials/credentials.h"
 
28
#include "param/param.h"
 
29
#include "auth/auth.h" /* for auth_serversupplied_info */
 
30
#include "auth/session.h"
 
31
#include "auth/system_session_proto.h"
 
32
 
 
33
/**
 
34
 * Create the SID list for this user. 
 
35
 *
 
36
 * @note Specialised version for system sessions that doesn't use the SAM.
 
37
 */
 
38
static NTSTATUS create_token(TALLOC_CTX *mem_ctx, 
 
39
                               struct dom_sid *user_sid,
 
40
                               struct dom_sid *group_sid, 
 
41
                               int n_groupSIDs,
 
42
                               struct dom_sid **groupSIDs, 
 
43
                               bool is_authenticated,
 
44
                               struct security_token **token)
 
45
{
 
46
        struct security_token *ptoken;
 
47
        int i;
 
48
 
 
49
        ptoken = security_token_initialise(mem_ctx);
 
50
        NT_STATUS_HAVE_NO_MEMORY(ptoken);
 
51
 
 
52
        ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 5);
 
53
        NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
 
54
 
 
55
        ptoken->user_sid = talloc_reference(ptoken, user_sid);
 
56
        ptoken->group_sid = talloc_reference(ptoken, group_sid);
 
57
        ptoken->privilege_mask = 0;
 
58
 
 
59
        ptoken->sids[0] = ptoken->user_sid;
 
60
        ptoken->sids[1] = ptoken->group_sid;
 
61
 
 
62
        /*
 
63
         * Finally add the "standard" SIDs.
 
64
         * The only difference between guest and "anonymous"
 
65
         * is the addition of Authenticated_Users.
 
66
         */
 
67
        ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD);
 
68
        NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]);
 
69
        ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK);
 
70
        NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]);
 
71
        ptoken->num_sids = 4;
 
72
 
 
73
        if (is_authenticated) {
 
74
                ptoken->sids[4] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS);
 
75
                NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]);
 
76
                ptoken->num_sids++;
 
77
        }
 
78
 
 
79
        for (i = 0; i < n_groupSIDs; i++) {
 
80
                size_t check_sid_idx;
 
81
                for (check_sid_idx = 1; 
 
82
                     check_sid_idx < ptoken->num_sids; 
 
83
                     check_sid_idx++) {
 
84
                        if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) {
 
85
                                break;
 
86
                        }
 
87
                }
 
88
 
 
89
                if (check_sid_idx == ptoken->num_sids) {
 
90
                        ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]);
 
91
                }
 
92
        }
 
93
 
 
94
        *token = ptoken;
 
95
 
 
96
        /* Shortcuts to prevent recursion and avoid lookups */
 
97
        if (ptoken->user_sid == NULL) {
 
98
                ptoken->privilege_mask = 0;
 
99
                return NT_STATUS_OK;
 
100
        } 
 
101
        
 
102
        if (security_token_is_system(ptoken)) {
 
103
                ptoken->privilege_mask = ~0;
 
104
                return NT_STATUS_OK;
 
105
        } 
 
106
        
 
107
        if (security_token_is_anonymous(ptoken)) {
 
108
                ptoken->privilege_mask = 0;
 
109
                return NT_STATUS_OK;
 
110
        }
 
111
 
 
112
        DEBUG(0, ("Created token was not system or anonymous token!"));
 
113
        *token = NULL;
 
114
        return NT_STATUS_INTERNAL_ERROR;
 
115
}
 
116
 
 
117
static NTSTATUS generate_session_info(TALLOC_CTX *mem_ctx, 
 
118
                                    struct auth_serversupplied_info *server_info, 
 
119
                                    struct auth_session_info **_session_info) 
 
120
{
 
121
        struct auth_session_info *session_info;
 
122
        NTSTATUS nt_status;
 
123
 
 
124
        session_info = talloc(mem_ctx, struct auth_session_info);
 
125
        NT_STATUS_HAVE_NO_MEMORY(session_info);
 
126
 
 
127
        session_info->server_info = talloc_reference(session_info, server_info);
 
128
 
 
129
        /* unless set otherwise, the session key is the user session
 
130
         * key from the auth subsystem */ 
 
131
        session_info->session_key = server_info->user_session_key;
 
132
 
 
133
        nt_status = create_token(session_info,
 
134
                                          server_info->account_sid,
 
135
                                          server_info->primary_group_sid,
 
136
                                          server_info->n_domain_groups,
 
137
                                          server_info->domain_groups,
 
138
                                          server_info->authenticated,
 
139
                                          &session_info->security_token);
 
140
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
141
 
 
142
        session_info->credentials = NULL;
 
143
 
 
144
        *_session_info = session_info;
 
145
        return NT_STATUS_OK;
 
146
}
 
147
 
 
148
 
 
149
 
 
150
/* Create a security token for a session SYSTEM (the most
 
151
 * trusted/prvilaged account), including the local machine account as
 
152
 * the off-host credentials
 
153
 */ 
 
154
_PUBLIC_ struct auth_session_info *system_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 
 
155
{
 
156
        NTSTATUS nt_status;
 
157
        struct auth_session_info *session_info = NULL;
 
158
        nt_status = auth_system_session_info(mem_ctx,
 
159
                                             lp_ctx,
 
160
                                             &session_info);
 
161
        if (!NT_STATUS_IS_OK(nt_status)) {
 
162
                return NULL;
 
163
        }
 
164
        return session_info;
 
165
}
 
166
 
 
167
static NTSTATUS _auth_system_session_info(TALLOC_CTX *parent_ctx, 
 
168
                                          struct loadparm_context *lp_ctx,
 
169
                                          bool anonymous_credentials, 
 
170
                                          struct auth_session_info **_session_info) 
 
171
{
 
172
        NTSTATUS nt_status;
 
173
        struct auth_serversupplied_info *server_info = NULL;
 
174
        struct auth_session_info *session_info = NULL;
 
175
        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
 
176
        
 
177
        nt_status = auth_system_server_info(mem_ctx, lp_netbios_name(lp_ctx),
 
178
                                            &server_info);
 
179
        if (!NT_STATUS_IS_OK(nt_status)) {
 
180
                talloc_free(mem_ctx);
 
181
                return nt_status;
 
182
        }
 
183
 
 
184
        /* references the server_info into the session_info */
 
185
        nt_status = generate_session_info(parent_ctx, server_info, &session_info);
 
186
        talloc_free(mem_ctx);
 
187
 
 
188
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
189
 
 
190
        session_info->credentials = cli_credentials_init(session_info);
 
191
        if (!session_info->credentials) {
 
192
                return NT_STATUS_NO_MEMORY;
 
193
        }
 
194
 
 
195
        cli_credentials_set_conf(session_info->credentials, lp_ctx);
 
196
 
 
197
        if (anonymous_credentials) {
 
198
                cli_credentials_set_anonymous(session_info->credentials);
 
199
        } else {
 
200
                cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx);
 
201
        }
 
202
        *_session_info = session_info;
 
203
 
 
204
        return NT_STATUS_OK;
 
205
}
 
206
 
 
207
/*
 
208
  Create a system session, but with anonymous credentials (so we do not need to open secrets.ldb)
 
209
*/
 
210
_PUBLIC_ struct auth_session_info *system_session_anon(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 
 
211
{
 
212
        NTSTATUS nt_status;
 
213
        struct auth_session_info *session_info = NULL;
 
214
        nt_status = _auth_system_session_info(mem_ctx, lp_ctx, false, &session_info);
 
215
        if (!NT_STATUS_IS_OK(nt_status)) {
 
216
                return NULL;
 
217
        }
 
218
        return session_info;
 
219
}
 
220
 
 
221
 
 
222
 
 
223
_PUBLIC_ NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 
 
224
                                           struct loadparm_context *lp_ctx,
 
225
                                           struct auth_session_info **_session_info) 
 
226
{
 
227
        return _auth_system_session_info(parent_ctx, 
 
228
                        lp_ctx,
 
229
                        lp_parm_bool(lp_ctx, NULL, "system", "anonymous", false), 
 
230
                        _session_info);
 
231
}
 
232
 
 
233
NTSTATUS auth_system_server_info(TALLOC_CTX *mem_ctx, const char *netbios_name, 
 
234
                                 struct auth_serversupplied_info **_server_info) 
 
235
{
 
236
        struct auth_serversupplied_info *server_info;
 
237
 
 
238
        server_info = talloc(mem_ctx, struct auth_serversupplied_info);
 
239
        NT_STATUS_HAVE_NO_MEMORY(server_info);
 
240
 
 
241
        server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_SYSTEM);
 
242
        NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
 
243
 
 
244
        /* is this correct? */
 
245
        server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_ADMINISTRATORS);
 
246
        NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
 
247
 
 
248
        server_info->n_domain_groups = 0;
 
249
        server_info->domain_groups = NULL;
 
250
 
 
251
        /* annoying, but the Anonymous really does have a session key, 
 
252
           and it is all zeros! */
 
253
        server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
 
254
        NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
 
255
 
 
256
        server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
 
257
        NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
 
258
 
 
259
        data_blob_clear(&server_info->user_session_key);
 
260
        data_blob_clear(&server_info->lm_session_key);
 
261
 
 
262
        server_info->account_name = talloc_strdup(server_info, "SYSTEM");
 
263
        NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
 
264
 
 
265
        server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY");
 
266
        NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
 
267
 
 
268
        server_info->full_name = talloc_strdup(server_info, "System");
 
269
        NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
 
270
 
 
271
        server_info->logon_script = talloc_strdup(server_info, "");
 
272
        NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
 
273
 
 
274
        server_info->profile_path = talloc_strdup(server_info, "");
 
275
        NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
 
276
 
 
277
        server_info->home_directory = talloc_strdup(server_info, "");
 
278
        NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
 
279
 
 
280
        server_info->home_drive = talloc_strdup(server_info, "");
 
281
        NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
 
282
 
 
283
        server_info->logon_server = talloc_strdup(server_info, netbios_name);
 
284
        NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
 
285
 
 
286
        server_info->last_logon = 0;
 
287
        server_info->last_logoff = 0;
 
288
        server_info->acct_expiry = 0;
 
289
        server_info->last_password_change = 0;
 
290
        server_info->allow_password_change = 0;
 
291
        server_info->force_password_change = 0;
 
292
 
 
293
        server_info->logon_count = 0;
 
294
        server_info->bad_password_count = 0;
 
295
 
 
296
        server_info->acct_flags = ACB_NORMAL;
 
297
 
 
298
        server_info->authenticated = true;
 
299
 
 
300
        *_server_info = server_info;
 
301
 
 
302
        return NT_STATUS_OK;
 
303
}
 
304
 
 
305