r16141: Dummy commit to make the build farm re-test against Samba4 16140
[ira/wip.git] / source3 / auth / auth_util.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) Volker Lendecke 2006
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 2 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, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
29
30 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
31                                                    const DOM_SID *user_sid,
32                                                    const DOM_SID *group_sid,
33                                                    BOOL is_guest,
34                                                    int num_groupsids,
35                                                    const DOM_SID *groupsids);
36
37 /****************************************************************************
38  Create a UNIX user on demand.
39 ****************************************************************************/
40
41 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
42 {
43         pstring add_script;
44         int ret;
45
46         pstrcpy(add_script, lp_adduser_script());
47         if (! *add_script)
48                 return -1;
49         all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
50         if (domain)
51                 all_string_sub(add_script, "%D", domain, sizeof(pstring));
52         if (homedir)
53                 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
54         ret = smbrun(add_script,NULL);
55         flush_pwnam_cache();
56         DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
57         return ret;
58 }
59
60 /****************************************************************************
61  Create an auth_usersupplied_data structure
62 ****************************************************************************/
63
64 static NTSTATUS make_user_info(auth_usersupplied_info **user_info, 
65                                const char *smb_name, 
66                                const char *internal_username,
67                                const char *client_domain, 
68                                const char *domain,
69                                const char *wksta_name, 
70                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
71                                DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
72                                DATA_BLOB *plaintext, 
73                                BOOL encrypted)
74 {
75
76         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
77
78         *user_info = SMB_MALLOC_P(auth_usersupplied_info);
79         if (*user_info == NULL) {
80                 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
81                 return NT_STATUS_NO_MEMORY;
82         }
83
84         ZERO_STRUCTP(*user_info);
85
86         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
87
88         (*user_info)->smb_name = SMB_STRDUP(smb_name);
89         if ((*user_info)->smb_name == NULL) { 
90                 free_user_info(user_info);
91                 return NT_STATUS_NO_MEMORY;
92         }
93         
94         (*user_info)->internal_username = SMB_STRDUP(internal_username);
95         if ((*user_info)->internal_username == NULL) { 
96                 free_user_info(user_info);
97                 return NT_STATUS_NO_MEMORY;
98         }
99
100         (*user_info)->domain = SMB_STRDUP(domain);
101         if ((*user_info)->domain == NULL) { 
102                 free_user_info(user_info);
103                 return NT_STATUS_NO_MEMORY;
104         }
105
106         (*user_info)->client_domain = SMB_STRDUP(client_domain);
107         if ((*user_info)->client_domain == NULL) { 
108                 free_user_info(user_info);
109                 return NT_STATUS_NO_MEMORY;
110         }
111
112         (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
113         if ((*user_info)->wksta_name == NULL) { 
114                 free_user_info(user_info);
115                 return NT_STATUS_NO_MEMORY;
116         }
117
118         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
119
120         if (lm_pwd)
121                 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
122         if (nt_pwd)
123                 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
124         if (lm_interactive_pwd)
125                 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
126         if (nt_interactive_pwd)
127                 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
128
129         if (plaintext)
130                 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
131
132         (*user_info)->encrypted = encrypted;
133
134         (*user_info)->logon_parameters = 0;
135
136         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
137
138         return NT_STATUS_OK;
139 }
140
141 /****************************************************************************
142  Create an auth_usersupplied_data structure after appropriate mapping.
143 ****************************************************************************/
144
145 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, 
146                             const char *smb_name, 
147                             const char *client_domain, 
148                             const char *wksta_name, 
149                             DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
150                             DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
151                             DATA_BLOB *plaintext, 
152                             BOOL encrypted)
153 {
154         const char *domain;
155         NTSTATUS result;
156         BOOL was_mapped;
157         fstring internal_username;
158         fstrcpy(internal_username, smb_name);
159         was_mapped = map_username(internal_username); 
160         
161         DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
162               client_domain, smb_name, wksta_name));
163         
164         /* don't allow "" as a domain, fixes a Win9X bug 
165            where it doens't supply a domain for logon script
166            'net use' commands.                                 */
167
168         if ( *client_domain )
169                 domain = client_domain;
170         else
171                 domain = lp_workgroup();
172
173         /* do what win2k does.  Always map unknown domains to our own
174            and let the "passdb backend" handle unknown users. */
175
176         if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) 
177                 domain = my_sam_name();
178         
179         /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
180         
181         result = make_user_info(user_info, smb_name, internal_username, 
182                               client_domain, domain, wksta_name, 
183                               lm_pwd, nt_pwd,
184                               lm_interactive_pwd, nt_interactive_pwd,
185                               plaintext, encrypted);
186         if (NT_STATUS_IS_OK(result)) {
187                 (*user_info)->was_mapped = was_mapped;
188         }
189         return result;
190 }
191
192 /****************************************************************************
193  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
194  Decrypt and encrypt the passwords.
195 ****************************************************************************/
196
197 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
198                                      const char *smb_name, 
199                                      const char *client_domain, 
200                                      const char *wksta_name, 
201                                      uint32 logon_parameters,
202                                      const uchar *lm_network_pwd,
203                                      int lm_pwd_len,
204                                      const uchar *nt_network_pwd,
205                                      int nt_pwd_len)
206 {
207         BOOL ret;
208         NTSTATUS status;
209         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
210         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
211
212         status = make_user_info_map(user_info,
213                                     smb_name, client_domain, 
214                                     wksta_name, 
215                                     lm_pwd_len ? &lm_blob : NULL, 
216                                     nt_pwd_len ? &nt_blob : NULL,
217                                     NULL, NULL, NULL,
218                                     True);
219
220         if (NT_STATUS_IS_OK(status)) {
221                 (*user_info)->logon_parameters = logon_parameters;
222         }
223         ret = NT_STATUS_IS_OK(status) ? True : False;
224
225         data_blob_free(&lm_blob);
226         data_blob_free(&nt_blob);
227         return ret;
228 }
229
230 /****************************************************************************
231  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
232  Decrypt and encrypt the passwords.
233 ****************************************************************************/
234
235 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
236                                          const char *smb_name, 
237                                          const char *client_domain, 
238                                          const char *wksta_name, 
239                                          uint32 logon_parameters,
240                                          const uchar chal[8], 
241                                          const uchar lm_interactive_pwd[16], 
242                                          const uchar nt_interactive_pwd[16], 
243                                          const uchar *dc_sess_key)
244 {
245         char lm_pwd[16];
246         char nt_pwd[16];
247         unsigned char local_lm_response[24];
248         unsigned char local_nt_response[24];
249         unsigned char key[16];
250         
251         ZERO_STRUCT(key);
252         memcpy(key, dc_sess_key, 8);
253         
254         if (lm_interactive_pwd)
255                 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
256
257         if (nt_interactive_pwd)
258                 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
259         
260 #ifdef DEBUG_PASSWORD
261         DEBUG(100,("key:"));
262         dump_data(100, (char *)key, sizeof(key));
263         
264         DEBUG(100,("lm owf password:"));
265         dump_data(100, lm_pwd, sizeof(lm_pwd));
266         
267         DEBUG(100,("nt owf password:"));
268         dump_data(100, nt_pwd, sizeof(nt_pwd));
269 #endif
270         
271         if (lm_interactive_pwd)
272                 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
273         
274         if (nt_interactive_pwd)
275                 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
276         
277 #ifdef DEBUG_PASSWORD
278         DEBUG(100,("decrypt of lm owf password:"));
279         dump_data(100, lm_pwd, sizeof(lm_pwd));
280         
281         DEBUG(100,("decrypt of nt owf password:"));
282         dump_data(100, nt_pwd, sizeof(nt_pwd));
283 #endif
284         
285         if (lm_interactive_pwd)
286                 SMBOWFencrypt((const unsigned char *)lm_pwd, chal,
287                               local_lm_response);
288
289         if (nt_interactive_pwd)
290                 SMBOWFencrypt((const unsigned char *)nt_pwd, chal,
291                               local_nt_response);
292         
293         /* Password info paranoia */
294         ZERO_STRUCT(key);
295
296         {
297                 BOOL ret;
298                 NTSTATUS nt_status;
299                 DATA_BLOB local_lm_blob;
300                 DATA_BLOB local_nt_blob;
301
302                 DATA_BLOB lm_interactive_blob;
303                 DATA_BLOB nt_interactive_blob;
304                 
305                 if (lm_interactive_pwd) {
306                         local_lm_blob = data_blob(local_lm_response,
307                                                   sizeof(local_lm_response));
308                         lm_interactive_blob = data_blob(lm_pwd,
309                                                         sizeof(lm_pwd));
310                         ZERO_STRUCT(lm_pwd);
311                 }
312                 
313                 if (nt_interactive_pwd) {
314                         local_nt_blob = data_blob(local_nt_response,
315                                                   sizeof(local_nt_response));
316                         nt_interactive_blob = data_blob(nt_pwd,
317                                                         sizeof(nt_pwd));
318                         ZERO_STRUCT(nt_pwd);
319                 }
320
321                 nt_status = make_user_info_map(
322                         user_info, 
323                         smb_name, client_domain, wksta_name, 
324                         lm_interactive_pwd ? &local_lm_blob : NULL,
325                         nt_interactive_pwd ? &local_nt_blob : NULL,
326                         lm_interactive_pwd ? &lm_interactive_blob : NULL,
327                         nt_interactive_pwd ? &nt_interactive_blob : NULL,
328                         NULL, True);
329
330                 if (NT_STATUS_IS_OK(nt_status)) {
331                         (*user_info)->logon_parameters = logon_parameters;
332                 }
333
334                 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
335                 data_blob_free(&local_lm_blob);
336                 data_blob_free(&local_nt_blob);
337                 data_blob_free(&lm_interactive_blob);
338                 data_blob_free(&nt_interactive_blob);
339                 return ret;
340         }
341 }
342
343
344 /****************************************************************************
345  Create an auth_usersupplied_data structure
346 ****************************************************************************/
347
348 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
349                               const char *smb_name, 
350                               const char *client_domain,
351                               const uint8 chal[8],
352                               DATA_BLOB plaintext_password)
353 {
354
355         DATA_BLOB local_lm_blob;
356         DATA_BLOB local_nt_blob;
357         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
358                         
359         /*
360          * Not encrypted - do so.
361          */
362         
363         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
364                  "format.\n"));
365         
366         if (plaintext_password.data) {
367                 unsigned char local_lm_response[24];
368                 
369 #ifdef DEBUG_PASSWORD
370                 DEBUG(10,("Unencrypted password (len %d):\n",
371                           (int)plaintext_password.length));
372                 dump_data(100, (const char *)plaintext_password.data,
373                           plaintext_password.length);
374 #endif
375
376                 SMBencrypt( (const char *)plaintext_password.data,
377                             (const uchar*)chal, local_lm_response);
378                 local_lm_blob = data_blob(local_lm_response, 24);
379                 
380                 /* We can't do an NT hash here, as the password needs to be
381                    case insensitive */
382                 local_nt_blob = data_blob(NULL, 0); 
383                 
384         } else {
385                 local_lm_blob = data_blob(NULL, 0); 
386                 local_nt_blob = data_blob(NULL, 0); 
387         }
388         
389         ret = make_user_info_map(
390                 user_info, smb_name, client_domain, 
391                 get_remote_machine_name(),
392                 local_lm_blob.data ? &local_lm_blob : NULL,
393                 local_nt_blob.data ? &local_nt_blob : NULL,
394                 NULL, NULL,
395                 plaintext_password.data ? &plaintext_password : NULL, 
396                 False);
397         
398         data_blob_free(&local_lm_blob);
399         return NT_STATUS_IS_OK(ret) ? True : False;
400 }
401
402 /****************************************************************************
403  Create an auth_usersupplied_data structure
404 ****************************************************************************/
405
406 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
407                                       const char *smb_name,
408                                       const char *client_domain, 
409                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
410 {
411         return make_user_info_map(user_info, smb_name, 
412                                   client_domain, 
413                                   get_remote_machine_name(), 
414                                   lm_resp.data ? &lm_resp : NULL, 
415                                   nt_resp.data ? &nt_resp : NULL, 
416                                   NULL, NULL, NULL,
417                                   True);
418 }
419
420 /****************************************************************************
421  Create a guest user_info blob, for anonymous authenticaion.
422 ****************************************************************************/
423
424 BOOL make_user_info_guest(auth_usersupplied_info **user_info) 
425 {
426         NTSTATUS nt_status;
427
428         nt_status = make_user_info(user_info, 
429                                    "","", 
430                                    "","", 
431                                    "", 
432                                    NULL, NULL, 
433                                    NULL, NULL, 
434                                    NULL,
435                                    True);
436                               
437         return NT_STATUS_IS_OK(nt_status) ? True : False;
438 }
439
440 /****************************************************************************
441  prints a NT_USER_TOKEN to debug output.
442 ****************************************************************************/
443
444 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
445 {
446         size_t     i;
447         
448         if (!token) {
449                 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
450                 return;
451         }
452         
453         DEBUGC(dbg_class, dbg_lev,
454                ("NT user token of user %s\n",
455                 sid_string_static(&token->user_sids[0]) ));
456         DEBUGADDC(dbg_class, dbg_lev,
457                   ("contains %lu SIDs\n", (unsigned long)token->num_sids));
458         for (i = 0; i < token->num_sids; i++)
459                 DEBUGADDC(dbg_class, dbg_lev,
460                           ("SID[%3lu]: %s\n", (unsigned long)i, 
461                            sid_string_static(&token->user_sids[i])));
462
463         dump_se_priv( dbg_class, dbg_lev, &token->privileges );
464 }
465
466 /****************************************************************************
467  prints a UNIX 'token' to debug output.
468 ****************************************************************************/
469
470 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
471                            int n_groups, gid_t *groups)
472 {
473         int     i;
474         DEBUGC(dbg_class, dbg_lev,
475                ("UNIX token of user %ld\n", (long int)uid));
476
477         DEBUGADDC(dbg_class, dbg_lev,
478                   ("Primary group is %ld and contains %i supplementary "
479                    "groups\n", (long int)gid, n_groups));
480         for (i = 0; i < n_groups; i++)
481                 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i, 
482                         (long int)groups[i]));
483 }
484
485 /******************************************************************************
486  Create a token for the root user to be used internally by smbd.
487  This is similar to running under the context of the LOCAL_SYSTEM account
488  in Windows.  This is a read-only token.  Do not modify it or free() it.
489  Create a copy if your need to change it.
490 ******************************************************************************/
491
492 NT_USER_TOKEN *get_root_nt_token( void )
493 {
494         static NT_USER_TOKEN *token = NULL;
495         DOM_SID u_sid, g_sid;
496         struct passwd *pw;
497         
498         if ( token )
499                 return token;
500                 
501         if ( !(pw = sys_getpwnam( "root" )) ) {
502                 DEBUG(0,("get_root_nt_token: getpwnam\"root\") failed!\n"));
503                 return NULL;
504         }
505         
506         /* get the user and primary group SIDs; although the 
507            BUILTIN\Administrators SId is really the one that matters here */
508            
509         uid_to_sid(&u_sid, pw->pw_uid);
510         gid_to_sid(&g_sid, pw->pw_gid);
511
512         token = create_local_nt_token(NULL, &u_sid, &g_sid, False,
513                                       1, &global_sid_Builtin_Administrators);
514         return token;
515 }
516
517 static int server_info_dtor(void *p)
518 {
519         auth_serversupplied_info *server_info =
520                 talloc_get_type_abort(p, auth_serversupplied_info);
521
522         if (server_info->sam_account != NULL) {
523                 TALLOC_FREE(server_info->sam_account);
524         }
525
526         ZERO_STRUCTP(server_info);
527         return 0;
528 }
529
530 /***************************************************************************
531  Make a server_info struct. Free with TALLOC_FREE().
532 ***************************************************************************/
533
534 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
535 {
536         struct auth_serversupplied_info *result;
537
538         result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
539         if (result == NULL) {
540                 DEBUG(0, ("talloc failed\n"));
541                 return NULL;
542         }
543
544         talloc_set_destructor(result, server_info_dtor);
545
546         /* Initialise the uid and gid values to something non-zero
547            which may save us from giving away root access if there
548            is a bug in allocating these fields. */
549
550         result->uid = -1;
551         result->gid = -1;
552         return result;
553 }
554
555 /***************************************************************************
556  Make (and fill) a user_info struct from a struct samu
557 ***************************************************************************/
558
559 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, 
560                               struct samu *sampass)
561 {
562         NTSTATUS status;
563         struct passwd *pwd;
564         gid_t *gids;
565         auth_serversupplied_info *result;
566
567         if ( !(pwd = getpwnam_alloc(NULL, pdb_get_username(sampass))) ) {
568                 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
569                           pdb_get_username(sampass)));
570                 return NT_STATUS_NO_SUCH_USER;
571         }
572
573         if ( !(result = make_server_info(NULL)) ) {
574                 TALLOC_FREE(pwd);
575                 return NT_STATUS_NO_MEMORY;
576         }
577
578         result->sam_account = sampass;
579         result->unix_name = talloc_strdup(result, pwd->pw_name);
580         result->gid = pwd->pw_gid;
581         result->uid = pwd->pw_uid;
582         
583         TALLOC_FREE(pwd);
584
585         status = pdb_enum_group_memberships(result, sampass,
586                                             &result->sids, &gids,
587                                             &result->num_sids);
588
589         if (!NT_STATUS_IS_OK(status)) {
590                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
591                            nt_errstr(status)));
592                 result->sam_account = NULL; /* Don't free on error exit. */
593                 TALLOC_FREE(result);
594                 return status;
595         }
596
597         /* For now we throw away the gids and convert via sid_to_gid
598          * later. This needs fixing, but I'd like to get the code straight and
599          * simple first. */
600         TALLOC_FREE(gids);
601
602         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
603                  pdb_get_username(sampass), result->unix_name));
604
605         *server_info = result;
606
607         return NT_STATUS_OK;
608 }
609
610 /*
611  * Add alias SIDs from memberships within the partially created token SID list
612  */
613
614 static NTSTATUS add_aliases(TALLOC_CTX *tmp_ctx, const DOM_SID *domain_sid,
615                             struct nt_user_token *token)
616 {
617         uint32 *aliases;
618         size_t i, num_aliases;
619         NTSTATUS status;
620
621         aliases = NULL;
622         num_aliases = 0;
623
624         status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
625                                             token->user_sids,
626                                             token->num_sids,
627                                             &aliases, &num_aliases);
628
629         if (!NT_STATUS_IS_OK(status)) {
630                 DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
631                            nt_errstr(status)));
632                 return status;
633         }
634
635         for (i=0; i<num_aliases; i++) {
636                 DOM_SID alias_sid;
637                 sid_compose(&alias_sid, domain_sid, aliases[i]);
638                 add_sid_to_array_unique(token, &alias_sid,
639                                         &token->user_sids,
640                                         &token->num_sids);
641                 if (token->user_sids == NULL) {
642                         DEBUG(0, ("add_sid_to_array failed\n"));
643                         return NT_STATUS_NO_MEMORY;
644                 }
645         }
646
647         return NT_STATUS_OK;
648 }
649
650 static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
651 {
652         char *command;
653         char *group_sidstr;
654         size_t i;
655
656         if ((lp_log_nt_token_command() == NULL) ||
657             (strlen(lp_log_nt_token_command()) == 0)) {
658                 return NT_STATUS_OK;
659         }
660
661         group_sidstr = talloc_strdup(tmp_ctx, "");
662         for (i=1; i<token->num_sids; i++) {
663                 group_sidstr = talloc_asprintf(
664                         tmp_ctx, "%s %s", group_sidstr,
665                         sid_string_static(&token->user_sids[i]));
666         }
667
668         command = talloc_string_sub(
669                 tmp_ctx, lp_log_nt_token_command(),
670                 "%s", sid_string_static(&token->user_sids[0]));
671         command = talloc_string_sub(tmp_ctx, command, "%t", group_sidstr);
672
673         if (command == NULL) {
674                 return NT_STATUS_NO_MEMORY;
675         }
676
677         DEBUG(8, ("running command: [%s]\n", command));
678         if (smbrun(command, NULL) != 0) {
679                 DEBUG(0, ("Could not log NT token\n"));
680                 return NT_STATUS_ACCESS_DENIED;
681         }
682
683         return NT_STATUS_OK;
684 }
685
686 /*******************************************************************
687 *******************************************************************/
688
689 static NTSTATUS add_builtin_administrators( TALLOC_CTX *ctx, struct nt_user_token *token )
690 {
691         return NT_STATUS_OK;
692 }
693
694 /*******************************************************************
695 *******************************************************************/
696
697 static NTSTATUS create_builtin_users( void )
698 {
699         NTSTATUS status;
700         DOM_SID dom_users;
701
702         status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_USERS );
703         if ( !NT_STATUS_IS_OK(status) ) {
704                 DEBUG(0,("create_builtin_users: Failed to create Users\n"));
705                 return status;
706         }
707         
708         /* add domain users */
709         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 
710                 && secrets_fetch_domain_sid(lp_workgroup(), &dom_users))
711         {
712                 sid_append_rid(&dom_users, DOMAIN_GROUP_RID_USERS );
713                 status = pdb_add_aliasmem( &global_sid_Builtin_Users, &dom_users);
714                 if ( !NT_STATUS_IS_OK(status) ) {
715                         DEBUG(0,("create_builtin_administrators: Failed to add Domain Users to"
716                                 " Users\n"));
717                         return status;
718                 }
719         }
720                         
721         return NT_STATUS_OK;
722 }               
723
724 /*******************************************************************
725 *******************************************************************/
726
727 static NTSTATUS create_builtin_administrators( void )
728 {
729         NTSTATUS status;
730         DOM_SID dom_admins, root_sid;
731         fstring root_name;
732         enum SID_NAME_USE type;         
733         TALLOC_CTX *ctx;
734         BOOL ret;
735
736         status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
737         if ( !NT_STATUS_IS_OK(status) ) {
738                 DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
739                 return status;
740         }
741         
742         /* add domain admins */
743         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 
744                 && secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
745         {
746                 sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
747                 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
748                 if ( !NT_STATUS_IS_OK(status) ) {
749                         DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
750                                 " Administrators\n"));
751                         return status;
752                 }
753         }
754                         
755         /* add root */
756         if ( (ctx = talloc_init(NULL)) == NULL ) {
757                 return NT_STATUS_NO_MEMORY;
758         }
759         fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
760         ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
761         TALLOC_FREE( ctx );
762
763         if ( ret ) {
764                 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
765                 if ( !NT_STATUS_IS_OK(status) ) {
766                         DEBUG(0,("create_builtin_administrators: Failed to add root"
767                                 " Administrators\n"));
768                         return status;
769                 }
770         }
771         
772         return NT_STATUS_OK;
773 }               
774
775 /*******************************************************************
776  Create a NT token for the user, expanding local aliases
777 *******************************************************************/
778
779 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
780                                                    const DOM_SID *user_sid,
781                                                    const DOM_SID *group_sid,
782                                                    BOOL is_guest,
783                                                    int num_groupsids,
784                                                    const DOM_SID *groupsids)
785 {
786         TALLOC_CTX *tmp_ctx;
787         struct nt_user_token *result = NULL;
788         int i;
789         NTSTATUS status;
790         gid_t gid;
791
792         tmp_ctx = talloc_new(mem_ctx);
793         if (tmp_ctx == NULL) {
794                 DEBUG(0, ("talloc_new failed\n"));
795                 return NULL;
796         }
797
798         result = TALLOC_ZERO_P(tmp_ctx, NT_USER_TOKEN);
799         if (result == NULL) {
800                 DEBUG(0, ("talloc failed\n"));
801                 goto done;
802         }
803
804         /* Add the user and primary group sid */
805
806         add_sid_to_array(result, user_sid,
807                          &result->user_sids, &result->num_sids);
808         add_sid_to_array(result, group_sid,
809                          &result->user_sids, &result->num_sids);
810                          
811         /* Add in BUILTIN sids */
812         
813         add_sid_to_array(result, &global_sid_World,
814                          &result->user_sids, &result->num_sids);
815         add_sid_to_array(result, &global_sid_Network,
816                          &result->user_sids, &result->num_sids);
817
818         if (is_guest) {
819                 add_sid_to_array(result, &global_sid_Builtin_Guests,
820                                  &result->user_sids, &result->num_sids);
821         } else {
822                 add_sid_to_array(result, &global_sid_Authenticated_Users,
823                                  &result->user_sids, &result->num_sids);
824         }
825         
826         /* Now the SIDs we got from authentication. These are the ones from
827          * the info3 struct or from the pdb_enum_group_memberships, depending
828          * on who authenticated the user. */
829
830         for (i=0; i<num_groupsids; i++) {
831                 add_sid_to_array_unique(result, &groupsids[i],
832                                         &result->user_sids, &result->num_sids);
833         }
834         
835         /* Deal with the BUILTIN\Administrators group.  If the SID can
836            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
837            handled it. */
838
839         if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
840                 /* We can only create a mapping if winbind is running 
841                    and the nested group functionality has been enabled */
842                    
843                 if ( lp_winbind_nested_groups() && winbind_ping() ) {
844                         become_root();
845                         status = create_builtin_administrators( );
846                         if ( !NT_STATUS_IS_OK(status) ) {
847                                 DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
848                                 /* don't fail, just log the message */
849                         }
850                         unbecome_root();
851                 }
852                 else {
853                         status = add_builtin_administrators( tmp_ctx, result ); 
854                         if ( !NT_STATUS_IS_OK(status) ) {                       
855                                 result = NULL;
856                                 goto done;
857                         }                       
858                 }               
859         }
860
861         /* Deal with the BUILTIN\Users group.  If the SID can
862            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
863            handled it. */
864
865         if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
866                 /* We can only create a mapping if winbind is running 
867                    and the nested group functionality has been enabled */
868                    
869                 if ( lp_winbind_nested_groups() && winbind_ping() ) {
870                         become_root();
871                         status = create_builtin_users( );
872                         if ( !NT_STATUS_IS_OK(status) ) {
873                                 DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
874                                 /* don't fail, just log the message */
875                         }
876                         unbecome_root();
877                 }
878         }
879
880         /* Deal with local groups */
881         
882         if (lp_winbind_nested_groups()) {
883
884                 /* Now add the aliases. First the one from our local SAM */
885
886                 status = add_aliases(tmp_ctx, get_global_sam_sid(), result);
887
888                 if (!NT_STATUS_IS_OK(status)) {
889                         result = NULL;
890                         goto done;
891                 }
892
893                 /* Finally the builtin ones */
894
895                 status = add_aliases(tmp_ctx, &global_sid_Builtin, result);
896
897                 if (!NT_STATUS_IS_OK(status)) {
898                         result = NULL;
899                         goto done;
900                 }
901         } 
902
903
904         get_privileges_for_sids(&result->privileges, result->user_sids,
905                                 result->num_sids);
906
907         talloc_steal(mem_ctx, result);
908
909  done:
910         TALLOC_FREE(tmp_ctx);
911         return result;
912 }
913
914 /*
915  * Create the token to use from server_info->sam_account and
916  * server_info->sids (the info3/sam groups). Find the unix gids.
917  */
918
919 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
920 {
921         TALLOC_CTX *mem_ctx;
922         NTSTATUS status;
923         size_t i;
924         
925
926         mem_ctx = talloc_new(NULL);
927         if (mem_ctx == NULL) {
928                 DEBUG(0, ("talloc_new failed\n"));
929                 return NT_STATUS_NO_MEMORY;
930         }
931
932         if (server_info->was_mapped) {
933                 status = create_token_from_username(server_info,
934                                                     server_info->unix_name,
935                                                     server_info->guest,
936                                                     &server_info->uid,
937                                                     &server_info->gid,
938                                                     &server_info->unix_name,
939                                                     &server_info->ptok);
940                 
941         } else {
942                 server_info->ptok = create_local_nt_token(
943                         server_info,
944                         pdb_get_user_sid(server_info->sam_account),
945                         pdb_get_group_sid(server_info->sam_account),
946                         server_info->guest,
947                         server_info->num_sids, server_info->sids);
948                 status = server_info->ptok ?
949                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
950         }
951
952         if (!NT_STATUS_IS_OK(status)) {
953                 TALLOC_FREE(mem_ctx);
954                 return status;
955         }
956         
957         /* Convert the SIDs to gids. */
958
959         server_info->n_groups = 0;
960         server_info->groups = NULL;
961
962         /* Start at index 1, where the groups start. */
963
964         for (i=1; i<server_info->ptok->num_sids; i++) {
965                 gid_t gid;
966                 DOM_SID *sid = &server_info->ptok->user_sids[i];
967
968                 if (!sid_to_gid(sid, &gid)) {
969                         DEBUG(10, ("Could not convert SID %s to gid, "
970                                    "ignoring it\n", sid_string_static(sid)));
971                         continue;
972                 }
973                 add_gid_to_array_unique(server_info, gid, &server_info->groups,
974                                         &server_info->n_groups);
975         }
976         
977         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
978
979         status = log_nt_token(mem_ctx, server_info->ptok);
980
981         TALLOC_FREE(mem_ctx);
982         return status;
983 }
984
985 /*
986  * Create an artificial NT token given just a username. (Initially indended
987  * for force user)
988  *
989  * We go through lookup_name() to avoid problems we had with 'winbind use
990  * default domain'.
991  *
992  * We have 3 cases:
993  *
994  * unmapped unix users: Go directly to nss to find the user's group.
995  *
996  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
997  *
998  * If the user is provided by winbind, the primary gid is set to "domain
999  * users" of the user's domain. For an explanation why this is necessary, see
1000  * the thread starting at
1001  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
1002  */
1003
1004 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
1005                                     BOOL is_guest,
1006                                     uid_t *uid, gid_t *gid,
1007                                     char **found_username,
1008                                     struct nt_user_token **token)
1009 {
1010         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
1011         TALLOC_CTX *tmp_ctx;
1012         DOM_SID user_sid;
1013         enum SID_NAME_USE type;
1014         gid_t *gids;
1015         DOM_SID primary_group_sid;
1016         DOM_SID *group_sids;
1017         size_t num_group_sids;
1018
1019         tmp_ctx = talloc_new(NULL);
1020         if (tmp_ctx == NULL) {
1021                 DEBUG(0, ("talloc_new failed\n"));
1022                 return NT_STATUS_NO_MEMORY;
1023         }
1024
1025         if (!lookup_name(tmp_ctx, username, LOOKUP_NAME_ALL,
1026                          NULL, NULL, &user_sid, &type)) {
1027                 DEBUG(1, ("lookup_name for %s failed\n", username));
1028                 goto done;
1029         }
1030
1031         if (type != SID_NAME_USER) {
1032                 DEBUG(1, ("%s is a %s, not a user\n", username,
1033                           sid_type_lookup(type)));
1034                 goto done;
1035         }
1036
1037         if (!sid_to_uid(&user_sid, uid)) {
1038                 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
1039                           username, sid_string_static(&user_sid)));
1040                 goto done;
1041         }
1042
1043         if (sid_check_is_in_unix_users(&user_sid)) {
1044
1045                 /* This is a unix user not in passdb. We need to ask nss
1046                  * directly, without consulting passdb */
1047
1048                 struct passwd *pass;
1049                 size_t i;
1050
1051                 pass = getpwuid_alloc(tmp_ctx, *uid);
1052                 if (pass == NULL) {
1053                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
1054                                   *uid, username));
1055                         goto done;
1056                 }
1057
1058                 *gid = pass->pw_gid;
1059                 gid_to_sid(&primary_group_sid, pass->pw_gid);
1060
1061                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
1062                                          &gids, &num_group_sids)) {
1063                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
1064                                   username));
1065                         goto done;
1066                 }
1067
1068                 group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids);
1069                 if (group_sids == NULL) {
1070                         DEBUG(1, ("talloc_array failed\n"));
1071                         result = NT_STATUS_NO_MEMORY;
1072                         goto done;
1073                 }
1074
1075                 for (i=0; i<num_group_sids; i++) {
1076                         gid_to_sid(&group_sids[i], gids[i]);
1077                 }
1078                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
1079
1080         } else if (sid_check_is_in_our_domain(&user_sid)) {
1081
1082                 /* This is a passdb user, so ask passdb */
1083
1084                 struct samu *sam_acct = NULL;
1085
1086                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
1087                         goto done;
1088                 }
1089
1090                 if (!pdb_getsampwsid(sam_acct, &user_sid)) {
1091                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
1092                                   sid_string_static(&user_sid), username));
1093                         result = NT_STATUS_NO_SUCH_USER;
1094                         goto done;
1095                 }
1096
1097                 sid_copy(&primary_group_sid, pdb_get_group_sid(sam_acct));
1098
1099                 if (!sid_to_gid(&primary_group_sid, gid)) {
1100                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1101                                   sid_string_static(&primary_group_sid)));
1102                         goto done;
1103                 }
1104
1105                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
1106                                                     &group_sids, &gids,
1107                                                     &num_group_sids);
1108                 if (!NT_STATUS_IS_OK(result)) {
1109                         DEBUG(10, ("enum_group_memberships failed for %s\n",
1110                                    username));
1111                         goto done;
1112                 }
1113
1114                 *found_username = talloc_strdup(mem_ctx,
1115                                                 pdb_get_username(sam_acct));
1116
1117         } else {
1118
1119                 /* This user is from winbind, force the primary gid to the
1120                  * user's "domain users" group. Under certain circumstances
1121                  * (user comes from NT4), this might be a loss of
1122                  * information. But we can not rely on winbind getting the
1123                  * correct info. AD might prohibit winbind looking up that
1124                  * information. */
1125
1126                 uint32 dummy;
1127
1128                 sid_copy(&primary_group_sid, &user_sid);
1129                 sid_split_rid(&primary_group_sid, &dummy);
1130                 sid_append_rid(&primary_group_sid, DOMAIN_GROUP_RID_USERS);
1131
1132                 if (!sid_to_gid(&primary_group_sid, gid)) {
1133                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1134                                   sid_string_static(&primary_group_sid)));
1135                         goto done;
1136                 }
1137
1138                 num_group_sids = 0;
1139                 group_sids = NULL;
1140
1141                 *found_username = talloc_strdup(mem_ctx, username);
1142         }
1143
1144         *token = create_local_nt_token(mem_ctx, &user_sid, &primary_group_sid,
1145                                        is_guest, num_group_sids, group_sids);
1146
1147         if ((*token == NULL) || (*found_username == NULL)) {
1148                 result = NT_STATUS_NO_MEMORY;
1149                 goto done;
1150         }
1151
1152         result = NT_STATUS_OK;
1153  done:
1154         TALLOC_FREE(tmp_ctx);
1155         return result;
1156 }
1157
1158 /***************************************************************************
1159  Build upon create_token_from_username:
1160
1161  Expensive helper function to figure out whether a user given its name is
1162  member of a particular group.
1163 ***************************************************************************/
1164 BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
1165 {
1166         NTSTATUS status;
1167         uid_t uid;
1168         gid_t gid;
1169         char *found_username;
1170         struct nt_user_token *token;
1171         BOOL result;
1172
1173         TALLOC_CTX *mem_ctx;
1174
1175         mem_ctx = talloc_new(NULL);
1176         if (mem_ctx == NULL) {
1177                 DEBUG(0, ("talloc_new failed\n"));
1178                 return False;
1179         }
1180
1181         status = create_token_from_username(mem_ctx, username, False,
1182                                             &uid, &gid, &found_username,
1183                                             &token);
1184
1185         if (!NT_STATUS_IS_OK(status)) {
1186                 DEBUG(10, ("could not create token for %s\n", username));
1187                 return False;
1188         }
1189
1190         result = nt_token_check_sid(group_sid, token);
1191
1192         TALLOC_FREE(mem_ctx);
1193         return result;
1194         
1195 }
1196
1197 BOOL user_in_group(const char *username, const char *groupname)
1198 {
1199         TALLOC_CTX *mem_ctx;
1200         DOM_SID group_sid;
1201         BOOL ret;
1202
1203         mem_ctx = talloc_new(NULL);
1204         if (mem_ctx == NULL) {
1205                 DEBUG(0, ("talloc_new failed\n"));
1206                 return False;
1207         }
1208
1209         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1210                           NULL, NULL, &group_sid, NULL);
1211         TALLOC_FREE(mem_ctx);
1212
1213         if (!ret) {
1214                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1215                 return False;
1216         }
1217
1218         return user_in_group_sid(username, &group_sid);
1219 }
1220
1221
1222 /***************************************************************************
1223  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
1224  to a struct samu
1225 ***************************************************************************/
1226
1227 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1228                              char *unix_username,
1229                              struct passwd *pwd)
1230 {
1231         NTSTATUS status;
1232         struct samu *sampass = NULL;
1233         gid_t *gids;
1234         auth_serversupplied_info *result;
1235         
1236         if ( !(sampass = samu_new( NULL )) ) {
1237                 return NT_STATUS_NO_MEMORY;
1238         }
1239         
1240         status = samu_set_unix( sampass, pwd );
1241         if (!NT_STATUS_IS_OK(status)) {
1242                 return status;
1243         }
1244
1245         result = make_server_info(NULL);
1246
1247         if (!NT_STATUS_IS_OK(status)) {
1248                 TALLOC_FREE(sampass);
1249                 return status;
1250         }
1251
1252         result->sam_account = sampass;
1253         result->unix_name = talloc_strdup(result, unix_username);
1254         result->uid = pwd->pw_uid;
1255         result->gid = pwd->pw_gid;
1256
1257         status = pdb_enum_group_memberships(result, sampass,
1258                                             &result->sids, &gids,
1259                                             &result->num_sids);
1260
1261         if (!NT_STATUS_IS_OK(status)) {
1262                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1263                            nt_errstr(status)));
1264                 TALLOC_FREE(result);
1265                 return status;
1266         }
1267
1268         /* For now we throw away the gids and convert via sid_to_gid
1269          * later. This needs fixing, but I'd like to get the code straight and
1270          * simple first. */
1271         TALLOC_FREE(gids);
1272
1273         *server_info = result;
1274
1275         return NT_STATUS_OK;
1276 }
1277
1278 /***************************************************************************
1279  Make (and fill) a user_info struct for a guest login.
1280  This *must* succeed for smbd to start. If there is no mapping entry for
1281  the guest gid, then create one.
1282 ***************************************************************************/
1283
1284 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1285 {
1286         NTSTATUS status;
1287         struct samu *sampass = NULL;
1288         DOM_SID guest_sid;
1289         BOOL ret;
1290         static const char zeros[16];
1291
1292         if ( !(sampass = samu_new( NULL )) ) {
1293                 return NT_STATUS_NO_MEMORY;
1294         }
1295
1296         sid_copy(&guest_sid, get_global_sam_sid());
1297         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1298
1299         become_root();
1300         ret = pdb_getsampwsid(sampass, &guest_sid);
1301         unbecome_root();
1302
1303         if (!ret) {
1304                 TALLOC_FREE(sampass);
1305                 return NT_STATUS_NO_SUCH_USER;
1306         }
1307
1308         status = make_server_info_sam(server_info, sampass);
1309         if (!NT_STATUS_IS_OK(status)) {
1310                 TALLOC_FREE(sampass);
1311                 return status;
1312         }
1313         
1314         (*server_info)->guest = True;
1315
1316         status = create_local_token(*server_info);
1317         if (!NT_STATUS_IS_OK(status)) {
1318                 DEBUG(10, ("create_local_token failed: %s\n",
1319                            nt_errstr(status)));
1320                 return status;
1321         }
1322
1323         /* annoying, but the Guest really does have a session key, and it is
1324            all zeros! */
1325         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1326         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1327
1328         return NT_STATUS_OK;
1329 }
1330
1331 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1332 {
1333         auth_serversupplied_info *dst;
1334
1335         dst = make_server_info(NULL);
1336         if (dst == NULL) {
1337                 return NULL;
1338         }
1339
1340         dst->guest = src->guest;
1341         dst->uid = src->uid;
1342         dst->gid = src->gid;
1343         dst->n_groups = src->n_groups;
1344         if (src->n_groups != 0)
1345                 dst->groups = talloc_memdup(dst, src->groups,
1346                                             sizeof(gid_t)*dst->n_groups);
1347         else
1348                 dst->groups = NULL;
1349                 
1350         dst->ptok = dup_nt_token(dst, src->ptok);
1351         
1352         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1353                 src->user_session_key.length);
1354                 
1355         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1356                 src->lm_session_key.length);
1357                 
1358         if ( (dst->sam_account = samu_new( NULL )) != NULL )
1359                 pdb_copy_sam_account(dst->sam_account, src->sam_account);
1360         
1361         dst->pam_handle = NULL;
1362         dst->unix_name = talloc_strdup(dst, src->unix_name);
1363
1364         return dst;
1365 }
1366
1367 static auth_serversupplied_info *guest_info = NULL;
1368
1369 BOOL init_guest_info(void)
1370 {
1371         if (guest_info != NULL)
1372                 return True;
1373
1374         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1375 }
1376
1377 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1378 {
1379         *server_info = copy_serverinfo(guest_info);
1380         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1381 }
1382
1383 /***************************************************************************
1384  Purely internal function for make_server_info_info3
1385  Fill the sam account from getpwnam
1386 ***************************************************************************/
1387 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1388                                  const char *domain,
1389                                  const char *username,
1390                                  char **found_username,
1391                                  uid_t *uid, gid_t *gid,
1392                                  struct samu *account,
1393                                  BOOL *username_was_mapped)
1394 {
1395         NTSTATUS nt_status;
1396         fstring dom_user, lower_username;
1397         fstring real_username;
1398         struct passwd *passwd;
1399
1400         fstrcpy( lower_username, username );
1401         strlower_m( lower_username );
1402
1403         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1404                 lower_username);
1405
1406         /* Get the passwd struct.  Try to create the account is necessary. */
1407
1408         *username_was_mapped = map_username( dom_user );
1409
1410         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1411                 return NT_STATUS_NO_SUCH_USER;
1412
1413         *uid = passwd->pw_uid;
1414         *gid = passwd->pw_gid;
1415
1416         /* This is pointless -- there is no suport for differing 
1417            unix and windows names.  Make sure to always store the 
1418            one we actually looked up and succeeded. Have I mentioned
1419            why I hate the 'winbind use default domain' parameter?   
1420                                          --jerry              */
1421            
1422         *found_username = talloc_strdup( mem_ctx, real_username );
1423         
1424         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1425
1426         nt_status = samu_set_unix( account, passwd );
1427         
1428         TALLOC_FREE(passwd);
1429         
1430         return nt_status;
1431 }
1432
1433 /****************************************************************************
1434  Wrapper to allow the getpwnam() call to strip the domain name and 
1435  try again in case a local UNIX user is already there.  Also run through 
1436  the username if we fallback to the username only.
1437  ****************************************************************************/
1438  
1439 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1440                              fstring save_username, BOOL create )
1441 {
1442         struct passwd *pw = NULL;
1443         char *p;
1444         fstring username;
1445         
1446         /* we only save a copy of the username it has been mangled 
1447            by winbindd use default domain */
1448            
1449         save_username[0] = '\0';
1450            
1451         /* don't call map_username() here since it has to be done higher 
1452            up the stack so we don't call it mutliple times */
1453
1454         fstrcpy( username, domuser );
1455         
1456         p = strchr_m( username, *lp_winbind_separator() );
1457         
1458         /* code for a DOMAIN\user string */
1459         
1460         if ( p ) {
1461                 fstring strip_username;
1462
1463                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1464                 if ( pw ) {     
1465                         /* make sure we get the case of the username correct */
1466                         /* work around 'winbind use default domain = yes' */
1467
1468                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1469                                 char *domain;
1470                                 
1471                                 /* split the domain and username into 2 strings */
1472                                 *p = '\0';
1473                                 domain = username;
1474
1475                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1476                         }
1477                         else
1478                                 fstrcpy( save_username, pw->pw_name );
1479
1480                         /* whew -- done! */             
1481                         return pw;
1482                 }
1483
1484                 /* setup for lookup of just the username */
1485                 /* remember that p and username are overlapping memory */
1486
1487                 p++;
1488                 fstrcpy( strip_username, p );
1489                 fstrcpy( username, strip_username );
1490         }
1491         
1492         /* just lookup a plain username */
1493         
1494         pw = Get_Pwnam_alloc(mem_ctx, username);
1495                 
1496         /* Create local user if requested but only if winbindd
1497            is not running.  We need to protect against cases
1498            where winbindd is failing and then prematurely
1499            creating users in /etc/passwd */
1500         
1501         if ( !pw && create && !winbind_ping() ) {
1502                 /* Don't add a machine account. */
1503                 if (username[strlen(username)-1] == '$')
1504                         return NULL;
1505
1506                 smb_create_user(NULL, username, NULL);
1507                 pw = Get_Pwnam_alloc(mem_ctx, username);
1508         }
1509         
1510         /* one last check for a valid passwd struct */
1511         
1512         if ( pw )
1513                 fstrcpy( save_username, pw->pw_name );
1514
1515         return pw;
1516 }
1517
1518 /***************************************************************************
1519  Make a server_info struct from the info3 returned by a domain logon 
1520 ***************************************************************************/
1521
1522 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1523                                 const char *sent_nt_username,
1524                                 const char *domain,
1525                                 auth_serversupplied_info **server_info, 
1526                                 NET_USER_INFO_3 *info3) 
1527 {
1528         static const char zeros[16];
1529
1530         NTSTATUS nt_status = NT_STATUS_OK;
1531         char *found_username;
1532         const char *nt_domain;
1533         const char *nt_username;
1534         struct samu *sam_account = NULL;
1535         DOM_SID user_sid;
1536         DOM_SID group_sid;
1537         BOOL username_was_mapped;
1538
1539         uid_t uid;
1540         gid_t gid;
1541
1542         size_t i;
1543
1544         auth_serversupplied_info *result;
1545
1546         /* 
1547            Here is where we should check the list of
1548            trusted domains, and verify that the SID 
1549            matches.
1550         */
1551
1552         sid_copy(&user_sid, &info3->dom_sid.sid);
1553         if (!sid_append_rid(&user_sid, info3->user_rid)) {
1554                 return NT_STATUS_INVALID_PARAMETER;
1555         }
1556         
1557         sid_copy(&group_sid, &info3->dom_sid.sid);
1558         if (!sid_append_rid(&group_sid, info3->group_rid)) {
1559                 return NT_STATUS_INVALID_PARAMETER;
1560         }
1561
1562         if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1563                 /* If the server didn't give us one, just use the one we sent
1564                  * them */
1565                 nt_username = sent_nt_username;
1566         }
1567
1568         if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1569                 /* If the server didn't give us one, just use the one we sent
1570                  * them */
1571                 nt_domain = domain;
1572         }
1573         
1574         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1575            add user script (2.2.x behavior).
1576
1577            We use the _unmapped_ username here in an attempt to provide
1578            consistent username mapping behavior between kerberos and NTLM[SSP]
1579            authentication in domain mode security.  I.E. Username mapping
1580            should be applied to the fully qualified username
1581            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1582            called map_username() unnecessarily in make_user_info_map() but
1583            that is how the current code is designed.  Making the change here
1584            is the least disruptive place.  -- jerry */
1585            
1586         if ( !(sam_account = samu_new( NULL )) ) {
1587                 return NT_STATUS_NO_MEMORY;
1588         }
1589
1590         /* this call will try to create the user if necessary */
1591
1592         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1593                                      &found_username, &uid, &gid, sam_account,
1594                                      &username_was_mapped);
1595
1596         
1597         /* if we still don't have a valid unix account check for 
1598           'map to guest = bad uid' */
1599           
1600         if (!NT_STATUS_IS_OK(nt_status)) {
1601                 TALLOC_FREE( sam_account );
1602                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1603                         make_server_info_guest(server_info); 
1604                         return NT_STATUS_OK;
1605                 }
1606                 return nt_status;
1607         }
1608                 
1609         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1610                 TALLOC_FREE(sam_account);
1611                 return NT_STATUS_NO_MEMORY;
1612         }
1613
1614         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1615                 TALLOC_FREE(sam_account);
1616                 return NT_STATUS_NO_MEMORY;
1617         }
1618
1619         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1620                 TALLOC_FREE(sam_account);
1621                 return NT_STATUS_NO_MEMORY;
1622         }
1623
1624         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1625                 TALLOC_FREE(sam_account);
1626                 return NT_STATUS_UNSUCCESSFUL;
1627         }
1628
1629         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1630                 TALLOC_FREE(sam_account);
1631                 return NT_STATUS_UNSUCCESSFUL;
1632         }
1633                 
1634         if (!pdb_set_fullname(sam_account,
1635                               unistr2_static(&(info3->uni_full_name)), 
1636                               PDB_CHANGED)) {
1637                 TALLOC_FREE(sam_account);
1638                 return NT_STATUS_NO_MEMORY;
1639         }
1640
1641         if (!pdb_set_logon_script(sam_account,
1642                                   unistr2_static(&(info3->uni_logon_script)),
1643                                   PDB_CHANGED)) {
1644                 TALLOC_FREE(sam_account);
1645                 return NT_STATUS_NO_MEMORY;
1646         }
1647
1648         if (!pdb_set_profile_path(sam_account,
1649                                   unistr2_static(&(info3->uni_profile_path)),
1650                                   PDB_CHANGED)) {
1651                 TALLOC_FREE(sam_account);
1652                 return NT_STATUS_NO_MEMORY;
1653         }
1654
1655         if (!pdb_set_homedir(sam_account,
1656                              unistr2_static(&(info3->uni_home_dir)),
1657                              PDB_CHANGED)) {
1658                 TALLOC_FREE(sam_account);
1659                 return NT_STATUS_NO_MEMORY;
1660         }
1661
1662         if (!pdb_set_dir_drive(sam_account,
1663                                unistr2_static(&(info3->uni_dir_drive)),
1664                                PDB_CHANGED)) {
1665                 TALLOC_FREE(sam_account);
1666                 return NT_STATUS_NO_MEMORY;
1667         }
1668
1669         if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
1670                 TALLOC_FREE(sam_account);
1671                 return NT_STATUS_NO_MEMORY;
1672         }
1673
1674         result = make_server_info(NULL);
1675         if (result == NULL) {
1676                 DEBUG(4, ("make_server_info failed!\n"));
1677                 TALLOC_FREE(sam_account);
1678                 return NT_STATUS_NO_MEMORY;
1679         }
1680
1681         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1682            valid struct samu) */
1683                    
1684         result->sam_account = sam_account;
1685         result->unix_name = talloc_strdup(result, found_username);
1686
1687         /* Fill in the unix info we found on the way */
1688
1689         result->uid = uid;
1690         result->gid = gid;
1691
1692         /* Create a 'combined' list of all SIDs we might want in the SD */
1693
1694         result->num_sids = 0;
1695         result->sids = NULL;
1696
1697         /* and create (by appending rids) the 'domain' sids */
1698         
1699         for (i = 0; i < info3->num_groups2; i++) {
1700                 DOM_SID sid;
1701                 if (!sid_compose(&sid, &info3->dom_sid.sid,
1702                                  info3->gids[i].g_rid)) {
1703                         DEBUG(3,("could not append additional group rid "
1704                                  "0x%x\n", info3->gids[i].g_rid));
1705                         TALLOC_FREE(result);
1706                         return NT_STATUS_INVALID_PARAMETER;
1707                 }
1708                 add_sid_to_array(result, &sid, &result->sids,
1709                                  &result->num_sids);
1710         }
1711
1712         /* Copy 'other' sids.  We need to do sid filtering here to
1713            prevent possible elevation of privileges.  See:
1714
1715            http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1716          */
1717
1718         for (i = 0; i < info3->num_other_sids; i++) {
1719                 add_sid_to_array(result, &info3->other_sids[i].sid,
1720                                  &result->sids,
1721                                  &result->num_sids);
1722         }
1723
1724         result->login_server = unistr2_tdup(result, 
1725                                             &(info3->uni_logon_srv));
1726
1727         /* ensure we are never given NULL session keys */
1728         
1729         if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1730                 result->user_session_key = data_blob(NULL, 0);
1731         } else {
1732                 result->user_session_key = data_blob_talloc(
1733                         result, info3->user_sess_key,
1734                         sizeof(info3->user_sess_key));
1735         }
1736
1737         if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1738                 result->lm_session_key = data_blob(NULL, 0);
1739         } else {
1740                 result->lm_session_key = data_blob_talloc(
1741                         result, info3->lm_sess_key,
1742                         sizeof(info3->lm_sess_key));
1743         }
1744
1745         result->was_mapped = username_was_mapped;
1746
1747         *server_info = result;
1748
1749         return NT_STATUS_OK;
1750 }
1751
1752 /***************************************************************************
1753  Free a user_info struct
1754 ***************************************************************************/
1755
1756 void free_user_info(auth_usersupplied_info **user_info)
1757 {
1758         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1759         if (*user_info != NULL) {
1760                 if ((*user_info)->smb_name) {
1761                         DEBUG(10,("structure was created for %s\n",
1762                                   (*user_info)->smb_name));
1763                 }
1764                 SAFE_FREE((*user_info)->smb_name);
1765                 SAFE_FREE((*user_info)->internal_username);
1766                 SAFE_FREE((*user_info)->client_domain);
1767                 SAFE_FREE((*user_info)->domain);
1768                 SAFE_FREE((*user_info)->wksta_name);
1769                 data_blob_free(&(*user_info)->lm_resp);
1770                 data_blob_free(&(*user_info)->nt_resp);
1771                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1772                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1773                 data_blob_clear_free(&(*user_info)->plaintext_password);
1774                 ZERO_STRUCT(**user_info);
1775         }
1776         SAFE_FREE(*user_info);
1777 }
1778
1779 /***************************************************************************
1780  Make an auth_methods struct
1781 ***************************************************************************/
1782
1783 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1784 {
1785         if (!auth_context) {
1786                 smb_panic("no auth_context supplied to "
1787                           "make_auth_methods()!\n");
1788         }
1789
1790         if (!auth_method) {
1791                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1792                           "is NULL!\n");
1793         }
1794
1795         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1796         if (!*auth_method) {
1797                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1798                 return False;
1799         }
1800         ZERO_STRUCTP(*auth_method);
1801         
1802         return True;
1803 }
1804
1805 /****************************************************************************
1806  Duplicate a SID token.
1807 ****************************************************************************/
1808
1809 NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken)
1810 {
1811         NT_USER_TOKEN *token;
1812
1813         if (!ptoken)
1814                 return NULL;
1815
1816         token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
1817         if (token == NULL) {
1818                 DEBUG(0, ("talloc failed\n"));
1819                 return NULL;
1820         }
1821
1822         token->user_sids = talloc_memdup(token, ptoken->user_sids,
1823                                          sizeof(DOM_SID) * ptoken->num_sids );
1824
1825         if ((ptoken->user_sids != NULL) && (token->user_sids == NULL)) {
1826                 DEBUG(0, ("talloc_memdup failed\n"));
1827                 TALLOC_FREE(token);
1828                 return NULL;
1829         }
1830
1831         token->num_sids = ptoken->num_sids;
1832         
1833         /* copy the privileges; don't consider failure to be critical here */
1834         
1835         if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1836                 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!.  "
1837                          "Continuing with 0 privileges assigned.\n"));
1838         }
1839
1840         return token;
1841 }
1842
1843 /****************************************************************************
1844  Check for a SID in an NT_USER_TOKEN
1845 ****************************************************************************/
1846
1847 BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
1848 {
1849         int i;
1850         
1851         if ( !sid || !token )
1852                 return False;
1853         
1854         for ( i=0; i<token->num_sids; i++ ) {
1855                 if ( sid_equal( sid, &token->user_sids[i] ) )
1856                         return True;
1857         }
1858
1859         return False;
1860 }
1861
1862 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 
1863 {
1864         DOM_SID domain_sid;
1865
1866         /* if we are a domain member, the get the domain SID, else for 
1867            a DC or standalone server, use our own SID */
1868
1869         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1870                 if ( !secrets_fetch_domain_sid( lp_workgroup(),
1871                                                 &domain_sid ) ) {
1872                         DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
1873                                  "SID for domain [%s]\n", lp_workgroup()));
1874                         return False;
1875                 }
1876         } 
1877         else
1878                 sid_copy( &domain_sid, get_global_sam_sid() );
1879
1880         sid_append_rid( &domain_sid, rid );
1881         
1882         return nt_token_check_sid( &domain_sid, token );\
1883 }
1884
1885 /**
1886  * Verify whether or not given domain is trusted.
1887  *
1888  * @param domain_name name of the domain to be verified
1889  * @return true if domain is one of the trusted once or
1890  *         false if otherwise
1891  **/
1892
1893 BOOL is_trusted_domain(const char* dom_name)
1894 {
1895         DOM_SID trustdom_sid;
1896         BOOL ret;
1897
1898         /* no trusted domains for a standalone server */
1899
1900         if ( lp_server_role() == ROLE_STANDALONE )
1901                 return False;
1902
1903         /* if we are a DC, then check for a direct trust relationships */
1904
1905         if ( IS_DC ) {
1906                 become_root();
1907                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1908                           "[%s]\n", dom_name ));
1909                 ret = secrets_fetch_trusted_domain_password(dom_name, NULL,
1910                                                             NULL, NULL);
1911                 unbecome_root();
1912                 if (ret)
1913                         return True;
1914         }
1915         else {
1916                 NSS_STATUS result;
1917
1918                 /* If winbind is around, ask it */
1919
1920                 result = wb_is_trusted_domain(dom_name);
1921
1922                 if (result == NSS_STATUS_SUCCESS) {
1923                         return True;
1924                 }
1925
1926                 if (result == NSS_STATUS_NOTFOUND) {
1927                         /* winbind could not find the domain */
1928                         return False;
1929                 }
1930
1931                 /* The only other possible result is that winbind is not up
1932                    and running. We need to update the trustdom_cache
1933                    ourselves */
1934                 
1935                 update_trustdom_cache();
1936         }
1937
1938         /* now the trustdom cache should be available a DC could still
1939          * have a transitive trust so fall back to the cache of trusted
1940          * domains (like a domain member would use  */
1941
1942         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1943                 return True;
1944         }
1945
1946         return False;
1947 }
1948