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