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