Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-wsgi
[samba.git] / source4 / auth / system_session.c
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         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
238         NT_STATUS_HAVE_NO_MEMORY(server_info);
239
240         server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_SYSTEM);
241         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
242
243         /* is this correct? */
244         server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_ADMINISTRATORS);
245         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
246
247         server_info->n_domain_groups = 0;
248         server_info->domain_groups = NULL;
249
250         /* annoying, but the Anonymous really does have a session key, 
251            and it is all zeros! */
252         server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
253         NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
254
255         server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
256         NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
257
258         data_blob_clear(&server_info->user_session_key);
259         data_blob_clear(&server_info->lm_session_key);
260
261         server_info->account_name = talloc_strdup(server_info, "SYSTEM");
262         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
263
264         server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY");
265         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
266
267         server_info->full_name = talloc_strdup(server_info, "System");
268         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
269
270         server_info->logon_script = talloc_strdup(server_info, "");
271         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
272
273         server_info->profile_path = talloc_strdup(server_info, "");
274         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
275
276         server_info->home_directory = talloc_strdup(server_info, "");
277         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
278
279         server_info->home_drive = talloc_strdup(server_info, "");
280         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
281
282         server_info->logon_server = talloc_strdup(server_info, netbios_name);
283         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
284
285         server_info->last_logon = 0;
286         server_info->last_logoff = 0;
287         server_info->acct_expiry = 0;
288         server_info->last_password_change = 0;
289         server_info->allow_password_change = 0;
290         server_info->force_password_change = 0;
291
292         server_info->logon_count = 0;
293         server_info->bad_password_count = 0;
294
295         server_info->acct_flags = ACB_NORMAL;
296
297         server_info->authenticated = true;
298
299         *_server_info = server_info;
300
301         return NT_STATUS_OK;
302 }
303
304