s4:auth: Check return value of talloc_reference()
[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-2010
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 "auth/credentials/credentials.h"
27 #include "param/param.h"
28 #include "auth/auth.h" /* for auth_user_info_dc */
29 #include "auth/session.h"
30 #include "auth/system_session_proto.h"
31
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_AUTH
34
35 /*
36   prevent the static system session being freed
37  */
38 static int system_session_destructor(struct auth_session_info *info)
39 {
40         return -1;
41 }
42
43 /* Create a security token for a session SYSTEM (the most
44  * trusted/privileged account), including the local machine account as
45  * the off-host credentials
46  */ 
47 _PUBLIC_ struct auth_session_info *system_session(struct loadparm_context *lp_ctx)
48 {
49         static struct auth_session_info *static_session;
50         NTSTATUS nt_status;
51
52         if (static_session) {
53                 return static_session;
54         }
55
56         /*
57          * Use NULL here, not the autofree context for this
58          * static pointer. The destructor prevents freeing this
59          * memory anyway.
60          */
61         nt_status = auth_system_session_info(NULL,
62                                              lp_ctx,
63                                              &static_session);
64         if (!NT_STATUS_IS_OK(nt_status)) {
65                 TALLOC_FREE(static_session);
66                 return NULL;
67         }
68         talloc_set_destructor(static_session, system_session_destructor);
69         return static_session;
70 }
71
72 NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 
73                                   struct loadparm_context *lp_ctx,
74                                   struct auth_session_info **_session_info) 
75 {
76         NTSTATUS nt_status;
77         struct auth_user_info_dc *user_info_dc = NULL;
78         struct auth_session_info *session_info = NULL;
79         TALLOC_CTX *mem_ctx = NULL;
80         bool ok;
81
82         mem_ctx = talloc_new(parent_ctx);
83         if (mem_ctx == NULL) {
84                 return NT_STATUS_NO_MEMORY;
85         }
86         
87         nt_status = auth_system_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx),
88                                             &user_info_dc);
89         if (!NT_STATUS_IS_OK(nt_status)) {
90                 talloc_free(mem_ctx);
91                 return nt_status;
92         }
93
94         /* references the user_info_dc into the session_info */
95         nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info);
96         talloc_free(mem_ctx);
97
98         NT_STATUS_NOT_OK_RETURN(nt_status);
99
100         session_info->credentials = cli_credentials_init(session_info);
101         if (!session_info->credentials) {
102                 return NT_STATUS_NO_MEMORY;
103         }
104
105         ok = cli_credentials_set_conf(session_info->credentials, lp_ctx);
106         if (!ok) {
107                 return NT_STATUS_INTERNAL_ERROR;
108         }
109
110         cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx);
111         *_session_info = session_info;
112
113         return NT_STATUS_OK;
114 }
115
116 NTSTATUS auth_system_user_info_dc(TALLOC_CTX *mem_ctx, const char *netbios_name,
117                                  struct auth_user_info_dc **_user_info_dc)
118 {
119         struct auth_user_info_dc *user_info_dc;
120         struct auth_user_info *info;
121
122         user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc);
123         NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
124
125         /* This returns a pointer to a struct dom_sid, which is the
126          * same as a 1 element list of struct dom_sid */
127         user_info_dc->num_sids = 1;
128         user_info_dc->sids = talloc(user_info_dc, struct auth_SidAttr);
129         if (user_info_dc->sids == NULL) {
130                 talloc_free(user_info_dc);
131                 return NT_STATUS_NO_MEMORY;
132         }
133
134         user_info_dc->sids->sid = global_sid_System;
135         user_info_dc->sids->attrs = SE_GROUP_DEFAULT_FLAGS;
136
137         /* annoying, but the Anonymous really does have a session key, 
138            and it is all zeros! */
139         user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
140         if (user_info_dc->user_session_key.data == NULL) {
141                 talloc_free(user_info_dc);
142                 return NT_STATUS_NO_MEMORY;
143         }
144
145         user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
146         if (user_info_dc->lm_session_key.data == NULL) {
147                 talloc_free(user_info_dc);
148                 return NT_STATUS_NO_MEMORY;
149         }
150
151         data_blob_clear(&user_info_dc->user_session_key);
152         data_blob_clear(&user_info_dc->lm_session_key);
153
154         user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
155         if (user_info_dc->info == NULL) {
156                 talloc_free(user_info_dc);
157                 return NT_STATUS_NO_MEMORY;
158         };
159
160         info->account_name = talloc_strdup(info, "SYSTEM");
161         if (info->account_name == NULL) {
162                 talloc_free(user_info_dc);
163                 return NT_STATUS_NO_MEMORY;
164         };
165
166         info->domain_name = talloc_strdup(info, "NT AUTHORITY");
167         if (info->domain_name == NULL) {
168                 talloc_free(user_info_dc);
169                 return NT_STATUS_NO_MEMORY;
170         };
171
172         info->full_name = talloc_strdup(info, "System");
173         if (info->full_name == NULL) {
174                 talloc_free(user_info_dc);
175                 return NT_STATUS_NO_MEMORY;
176         };
177
178         info->logon_script = talloc_strdup(info, "");
179         if (info->logon_script == NULL) {
180                 talloc_free(user_info_dc);
181                 return NT_STATUS_NO_MEMORY;
182         };
183
184         info->profile_path = talloc_strdup(info, "");
185         if (info->profile_path == NULL) {
186                 talloc_free(user_info_dc);
187                 return NT_STATUS_NO_MEMORY;
188         };
189
190         info->home_directory = talloc_strdup(info, "");
191         if (info->home_directory == NULL) {
192                 talloc_free(user_info_dc);
193                 return NT_STATUS_NO_MEMORY;
194         };
195
196         info->home_drive = talloc_strdup(info, "");
197         if (info->home_drive == NULL) {
198                 talloc_free(user_info_dc);
199                 return NT_STATUS_NO_MEMORY;
200         };
201
202         info->logon_server = talloc_strdup(info, netbios_name);
203         if (info->logon_server == NULL) {
204                 talloc_free(user_info_dc);
205                 return NT_STATUS_NO_MEMORY;
206         };
207
208         info->last_logon = 0;
209         info->last_logoff = 0;
210         info->acct_expiry = 0;
211         info->last_password_change = 0;
212         info->allow_password_change = 0;
213         info->force_password_change = 0;
214
215         info->logon_count = 0;
216         info->bad_password_count = 0;
217
218         info->acct_flags = ACB_NORMAL;
219
220         info->user_flags = 0;
221
222         *_user_info_dc = user_info_dc;
223
224         return NT_STATUS_OK;
225 }
226
227
228 static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx,
229                                               const char *netbios_name,
230                                               const char *domain_name,
231                                               struct dom_sid *domain_sid,
232                                               struct auth_user_info_dc **_user_info_dc)
233 {
234         struct auth_user_info_dc *user_info_dc;
235         struct auth_user_info *info;
236
237         user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc);
238         NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
239
240         user_info_dc->num_sids = 8;
241         user_info_dc->sids = talloc_array(user_info_dc, struct auth_SidAttr, user_info_dc->num_sids);
242
243         user_info_dc->sids[PRIMARY_USER_SID_INDEX].sid = *domain_sid;
244         sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX].sid, DOMAIN_RID_ADMINISTRATOR);
245         user_info_dc->sids[PRIMARY_USER_SID_INDEX].attrs = SE_GROUP_DEFAULT_FLAGS;
246
247         user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].sid = *domain_sid;
248         sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].sid, DOMAIN_RID_USERS);
249         user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].attrs = SE_GROUP_DEFAULT_FLAGS;
250
251         /* Add the primary group again. */
252         user_info_dc->sids[2] = user_info_dc->sids[PRIMARY_GROUP_SID_INDEX];
253
254         user_info_dc->sids[3].sid = global_sid_Builtin_Administrators;
255         user_info_dc->sids[3].attrs = SE_GROUP_DEFAULT_FLAGS;
256
257         user_info_dc->sids[4].sid = *domain_sid;
258         sid_append_rid(&user_info_dc->sids[4].sid, DOMAIN_RID_ADMINS);
259         user_info_dc->sids[4].attrs = SE_GROUP_DEFAULT_FLAGS;
260         user_info_dc->sids[5].sid = *domain_sid;
261         sid_append_rid(&user_info_dc->sids[5].sid, DOMAIN_RID_ENTERPRISE_ADMINS);
262         user_info_dc->sids[5].attrs = SE_GROUP_DEFAULT_FLAGS;
263         user_info_dc->sids[6].sid = *domain_sid;
264         sid_append_rid(&user_info_dc->sids[6].sid, DOMAIN_RID_POLICY_ADMINS);
265         user_info_dc->sids[6].attrs = SE_GROUP_DEFAULT_FLAGS;
266         user_info_dc->sids[7].sid = *domain_sid;
267         sid_append_rid(&user_info_dc->sids[7].sid, DOMAIN_RID_SCHEMA_ADMINS);
268         user_info_dc->sids[7].attrs = SE_GROUP_DEFAULT_FLAGS;
269
270         /* What should the session key be?*/
271         user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
272         if (user_info_dc->user_session_key.data == NULL) {
273                 talloc_free(user_info_dc);
274                 return NT_STATUS_NO_MEMORY;
275         };
276
277         user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
278         if (user_info_dc->lm_session_key.data == NULL) {
279                 talloc_free(user_info_dc);
280                 return NT_STATUS_NO_MEMORY;
281         };
282
283         data_blob_clear(&user_info_dc->user_session_key);
284         data_blob_clear(&user_info_dc->lm_session_key);
285
286         user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
287         if (user_info_dc->info == NULL) {
288                 talloc_free(user_info_dc);
289                 return NT_STATUS_NO_MEMORY;
290         };
291
292         info->account_name = talloc_strdup(info, "Administrator");
293         if (info->account_name == NULL) {
294                 talloc_free(user_info_dc);
295                 return NT_STATUS_NO_MEMORY;
296         };
297
298         info->domain_name = talloc_strdup(info, domain_name);
299         if (info->domain_name == NULL) {
300                 talloc_free(user_info_dc);
301                 return NT_STATUS_NO_MEMORY;
302         };
303
304         info->full_name = talloc_strdup(info, "Administrator");
305         if (info->full_name == NULL) {
306                 talloc_free(user_info_dc);
307                 return NT_STATUS_NO_MEMORY;
308         };
309
310         info->logon_script = talloc_strdup(info, "");
311         if (info->logon_script == NULL) {
312                 talloc_free(user_info_dc);
313                 return NT_STATUS_NO_MEMORY;
314         };
315
316         info->profile_path = talloc_strdup(info, "");
317         if (info->profile_path == NULL) {
318                 talloc_free(user_info_dc);
319                 return NT_STATUS_NO_MEMORY;
320         };
321
322         info->home_directory = talloc_strdup(info, "");
323         if (info->home_directory == NULL) {
324                 talloc_free(user_info_dc);
325                 return NT_STATUS_NO_MEMORY;
326         };
327
328         info->home_drive = talloc_strdup(info, "");
329         if (info->home_drive == NULL) {
330                 talloc_free(user_info_dc);
331                 return NT_STATUS_NO_MEMORY;
332         };
333
334         info->logon_server = talloc_strdup(info, netbios_name);
335         if (info->logon_server == NULL) {
336                 talloc_free(user_info_dc);
337                 return NT_STATUS_NO_MEMORY;
338         };
339
340         info->last_logon = 0;
341         info->last_logoff = 0;
342         info->acct_expiry = 0;
343         info->last_password_change = 0;
344         info->allow_password_change = 0;
345         info->force_password_change = 0;
346
347         info->logon_count = 0;
348         info->bad_password_count = 0;
349
350         info->acct_flags = ACB_NORMAL;
351
352         info->user_flags = 0;
353
354         *_user_info_dc = user_info_dc;
355
356         return NT_STATUS_OK;
357 }
358
359 static NTSTATUS auth_domain_admin_session_info(TALLOC_CTX *parent_ctx,
360                                                struct loadparm_context *lp_ctx,
361                                                struct dom_sid *domain_sid,
362                                                struct auth_session_info **session_info)
363 {
364         NTSTATUS nt_status;
365         struct auth_user_info_dc *user_info_dc = NULL;
366         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
367
368         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
369
370         nt_status = auth_domain_admin_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx),
371                                                   lpcfg_workgroup(lp_ctx), domain_sid,
372                                                   &user_info_dc);
373         if (!NT_STATUS_IS_OK(nt_status)) {
374                 talloc_free(mem_ctx);
375                 return nt_status;
376         }
377
378         nt_status = auth_generate_session_info(mem_ctx, NULL, NULL, user_info_dc,
379                                                AUTH_SESSION_INFO_SIMPLE_PRIVILEGES|AUTH_SESSION_INFO_AUTHENTICATED|AUTH_SESSION_INFO_DEFAULT_GROUPS,
380                                                session_info);
381         /* There is already a reference between the session_info and user_info_dc */
382         if (NT_STATUS_IS_OK(nt_status)) {
383                 talloc_steal(parent_ctx, *session_info);
384         }
385         talloc_free(mem_ctx);
386         return nt_status;
387 }
388
389 _PUBLIC_ struct auth_session_info *admin_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct dom_sid *domain_sid)
390 {
391         NTSTATUS nt_status;
392         struct auth_session_info *session_info = NULL;
393         nt_status = auth_domain_admin_session_info(mem_ctx,
394                                                    lp_ctx,
395                                                    domain_sid,
396                                                    &session_info);
397         if (!NT_STATUS_IS_OK(nt_status)) {
398                 return NULL;
399         }
400         return session_info;
401 }
402
403 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 
404                                               struct loadparm_context *lp_ctx,
405                                               struct auth_session_info **_session_info) 
406 {
407         NTSTATUS nt_status;
408         struct auth_user_info_dc *user_info_dc = NULL;
409         struct auth_session_info *session_info = NULL;
410         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
411         bool ok;
412         
413         nt_status = auth_anonymous_user_info_dc(mem_ctx,
414                                                lpcfg_netbios_name(lp_ctx),
415                                                &user_info_dc);
416         if (!NT_STATUS_IS_OK(nt_status)) {
417                 talloc_free(mem_ctx);
418                 return nt_status;
419         }
420
421         /* references the user_info_dc into the session_info */
422         nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info);
423         talloc_free(mem_ctx);
424
425         NT_STATUS_NOT_OK_RETURN(nt_status);
426
427         session_info->credentials = cli_credentials_init(session_info);
428         if (!session_info->credentials) {
429                 return NT_STATUS_NO_MEMORY;
430         }
431
432         ok = cli_credentials_set_conf(session_info->credentials, lp_ctx);
433         if (!ok) {
434                 return NT_STATUS_INTERNAL_ERROR;
435         }
436         cli_credentials_set_anonymous(session_info->credentials);
437         
438         *_session_info = session_info;
439
440         return NT_STATUS_OK;
441 }
442
443 _PUBLIC_ NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx,
444                                     const char *netbios_name,
445                                     struct auth_user_info_dc **_user_info_dc)
446 {
447         struct auth_user_info_dc *user_info_dc;
448         struct auth_user_info *info;
449         user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc);
450         NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
451
452         /* This returns a pointer to a struct dom_sid, which is the
453          * same as a 1 element list of struct dom_sid */
454         user_info_dc->num_sids = 1;
455         user_info_dc->sids = talloc(user_info_dc, struct auth_SidAttr);
456         if (user_info_dc->sids == NULL) {
457                 talloc_free(user_info_dc);
458                 return NT_STATUS_NO_MEMORY;
459         };
460
461         user_info_dc->sids->sid = global_sid_Anonymous;
462         user_info_dc->sids->attrs = SE_GROUP_DEFAULT_FLAGS;
463
464         /* annoying, but the Anonymous really does have a session key... */
465         user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
466         if (user_info_dc->user_session_key.data == NULL) {
467                 talloc_free(user_info_dc);
468                 return NT_STATUS_NO_MEMORY;
469         };
470
471         user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
472         if (user_info_dc->lm_session_key.data == NULL) {
473                 talloc_free(user_info_dc);
474                 return NT_STATUS_NO_MEMORY;
475         };
476
477         /*  and it is all zeros! */
478         data_blob_clear(&user_info_dc->user_session_key);
479         data_blob_clear(&user_info_dc->lm_session_key);
480
481         user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
482         if (user_info_dc->info == NULL) {
483                 talloc_free(user_info_dc);
484                 return NT_STATUS_NO_MEMORY;
485         };
486
487         info->account_name = talloc_strdup(info, "ANONYMOUS LOGON");
488         if (info->account_name == NULL) {
489                 talloc_free(user_info_dc);
490                 return NT_STATUS_NO_MEMORY;
491         };
492
493         info->domain_name = talloc_strdup(info, "NT AUTHORITY");
494         if (info->domain_name == NULL) {
495                 talloc_free(user_info_dc);
496                 return NT_STATUS_NO_MEMORY;
497         };
498
499         info->full_name = talloc_strdup(info, "Anonymous Logon");
500         if (info->full_name == NULL) {
501                 talloc_free(user_info_dc);
502                 return NT_STATUS_NO_MEMORY;
503         };
504
505         info->logon_script = talloc_strdup(info, "");
506         if (info->logon_script == NULL) {
507                 talloc_free(user_info_dc);
508                 return NT_STATUS_NO_MEMORY;
509         };
510
511         info->profile_path = talloc_strdup(info, "");
512         if (info->profile_path == NULL) {
513                 talloc_free(user_info_dc);
514                 return NT_STATUS_NO_MEMORY;
515         };
516
517         info->home_directory = talloc_strdup(info, "");
518         if (info->home_directory == NULL) {
519                 talloc_free(user_info_dc);
520                 return NT_STATUS_NO_MEMORY;
521         };
522
523         info->home_drive = talloc_strdup(info, "");
524         if (info->home_drive == NULL) {
525                 talloc_free(user_info_dc);
526                 return NT_STATUS_NO_MEMORY;
527         };
528
529         info->logon_server = talloc_strdup(info, netbios_name);
530         if (info->logon_server == NULL) {
531                 talloc_free(user_info_dc);
532                 return NT_STATUS_NO_MEMORY;
533         };
534
535         info->last_logon = 0;
536         info->last_logoff = 0;
537         info->acct_expiry = 0;
538         info->last_password_change = 0;
539         info->allow_password_change = 0;
540         info->force_password_change = 0;
541
542         info->logon_count = 0;
543         info->bad_password_count = 0;
544
545         info->acct_flags = ACB_NORMAL;
546
547         /* The user is not authenticated. */
548         info->user_flags = NETLOGON_GUEST;
549
550         *_user_info_dc = user_info_dc;
551
552         return NT_STATUS_OK;
553 }
554