r13590: * replace all pdb_init_sam[_talloc]() calls with samu_new()
[sfrench/samba-autobuild/.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 = my_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 = sys_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                 TALLOC_FREE(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 struct samu
551 ***************************************************************************/
552
553 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, 
554                               struct samu *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                 struct samu *sam_acct = NULL;
953
954                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
955                         goto done;
956                 }
957
958                 if (!pdb_getsampwsid(sam_acct, &user_sid)) {
959                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
960                                   sid_string_static(&user_sid), username));
961                         result = NT_STATUS_NO_SUCH_USER;
962                         goto done;
963                 }
964
965                 sid_copy(&primary_group_sid, pdb_get_group_sid(sam_acct));
966
967                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
968                                                     &group_sids, &gids,
969                                                     &num_group_sids);
970                 if (!NT_STATUS_IS_OK(result)) {
971                         DEBUG(10, ("enum_group_memberships failed for %s\n",
972                                    username));
973                         goto done;
974                 }
975
976                 *found_username = talloc_strdup(mem_ctx,
977                                                 pdb_get_username(sam_acct));
978
979         } else {
980
981                 /* This user is from winbind, force the primary gid to the
982                  * user's "domain users" group. Under certain circumstances
983                  * (user comes from NT4), this might be a loss of
984                  * information. But we can not rely on winbind getting the
985                  * correct info. AD might prohibit winbind looking up that
986                  * information. */
987
988                 uint32 dummy;
989
990                 sid_copy(&primary_group_sid, &user_sid);
991                 sid_split_rid(&primary_group_sid, &dummy);
992                 sid_append_rid(&primary_group_sid, DOMAIN_GROUP_RID_USERS);
993
994                 if (!sid_to_gid(&primary_group_sid, gid)) {
995                         DEBUG(1, ("sid_to_gid(%s) failed\n",
996                                   sid_string_static(&primary_group_sid)));
997                         goto done;
998                 }
999
1000                 num_group_sids = 0;
1001                 group_sids = NULL;
1002
1003                 *found_username = talloc_strdup(mem_ctx, username);
1004         }
1005
1006         *token = create_local_nt_token(mem_ctx, &user_sid, &primary_group_sid,
1007                                        is_guest, num_group_sids, group_sids);
1008
1009         if ((*token == NULL) || (*found_username == NULL)) {
1010                 result = NT_STATUS_NO_MEMORY;
1011                 goto done;
1012         }
1013
1014         result = NT_STATUS_OK;
1015  done:
1016         TALLOC_FREE(tmp_ctx);
1017         return result;
1018 }
1019
1020 /***************************************************************************
1021  Build upon create_token_from_username:
1022
1023  Expensive helper function to figure out whether a user given its name is
1024  member of a particular group.
1025 ***************************************************************************/
1026 BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
1027 {
1028         NTSTATUS status;
1029         uid_t uid;
1030         gid_t gid;
1031         char *found_username;
1032         struct nt_user_token *token;
1033         BOOL result;
1034
1035         TALLOC_CTX *mem_ctx;
1036
1037         mem_ctx = talloc_new(NULL);
1038         if (mem_ctx == NULL) {
1039                 DEBUG(0, ("talloc_new failed\n"));
1040                 return False;
1041         }
1042
1043         status = create_token_from_username(mem_ctx, username, False,
1044                                             &uid, &gid, &found_username,
1045                                             &token);
1046
1047         if (!NT_STATUS_IS_OK(status)) {
1048                 DEBUG(10, ("could not create token for %s\n", username));
1049                 return False;
1050         }
1051
1052         result = nt_token_check_sid(group_sid, token);
1053
1054         TALLOC_FREE(mem_ctx);
1055         return result;
1056         
1057 }
1058
1059 BOOL user_in_group(const char *username, const char *groupname)
1060 {
1061         TALLOC_CTX *mem_ctx;
1062         DOM_SID group_sid;
1063         NTSTATUS status;
1064         BOOL ret;
1065
1066         mem_ctx = talloc_new(NULL);
1067         if (mem_ctx == NULL) {
1068                 DEBUG(0, ("talloc_new failed\n"));
1069                 return False;
1070         }
1071
1072         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1073                           NULL, NULL, &group_sid, NULL);
1074         TALLOC_FREE(mem_ctx);
1075
1076         if (!ret) {
1077                 DEBUG(10, ("lookup_name(%s) failed: %s\n", groupname,
1078                            nt_errstr(status)));
1079                 return False;
1080         }
1081
1082         return user_in_group_sid(username, &group_sid);
1083 }
1084
1085
1086 /***************************************************************************
1087  Make (and fill) a user_info struct from a Kerberos PAC logon_info by
1088  conversion to a struct samu
1089 ***************************************************************************/
1090
1091 NTSTATUS make_server_info_pac(auth_serversupplied_info **server_info, 
1092                               char *unix_username,
1093                               struct passwd *pwd,
1094                               PAC_LOGON_INFO *logon_info)
1095 {
1096         NTSTATUS status;
1097         struct samu *sampass = NULL;
1098         DOM_SID user_sid, group_sid;
1099         fstring dom_name;
1100         auth_serversupplied_info *result;
1101
1102         if ( !(sampass = samu_new( NULL )) ) {
1103                 return NT_STATUS_NO_MEMORY;
1104         }
1105                 
1106         status = samu_set_unix( sampass, pwd );
1107         if ( !NT_STATUS_IS_OK(status) ) {               
1108                 return status;
1109         }
1110
1111         result = make_server_info(NULL);
1112         if (result == NULL) {
1113                 TALLOC_FREE(sampass);
1114                 return NT_STATUS_NO_MEMORY;
1115         }
1116
1117         /* only copy user_sid, group_sid and domain name out of the PAC for
1118          * now, we will benefit from more later - Guenther */
1119
1120         sid_copy(&user_sid, &logon_info->info3.dom_sid.sid);
1121         sid_append_rid(&user_sid, logon_info->info3.user_rid);
1122         pdb_set_user_sid(sampass, &user_sid, PDB_SET);
1123         
1124         sid_copy(&group_sid, &logon_info->info3.dom_sid.sid);
1125         sid_append_rid(&group_sid, logon_info->info3.group_rid);
1126         pdb_set_group_sid(sampass, &group_sid, PDB_SET);
1127
1128         unistr2_to_ascii(dom_name, &logon_info->info3.uni_logon_dom, -1);
1129         pdb_set_domain(sampass, dom_name, PDB_SET);
1130
1131         pdb_set_logon_count(sampass, logon_info->info3.logon_count, PDB_SET);
1132
1133         result->sam_account = sampass;
1134         result->unix_name = talloc_strdup(result, unix_username);
1135         result->uid = pwd->pw_uid;
1136         result->gid = pwd->pw_gid;
1137
1138         /* TODO: Add groups from pac */
1139         result->sids = NULL;
1140         result->num_sids = 0;
1141
1142         *server_info = result;
1143
1144         return NT_STATUS_OK;
1145 }
1146
1147
1148 /***************************************************************************
1149  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
1150  to a struct samu
1151 ***************************************************************************/
1152
1153 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1154                              char *unix_username,
1155                              struct passwd *pwd)
1156 {
1157         NTSTATUS status;
1158         struct samu *sampass = NULL;
1159         gid_t *gids;
1160         auth_serversupplied_info *result;
1161         
1162         if ( !(sampass = samu_new( NULL )) ) {
1163                 return NT_STATUS_NO_MEMORY;
1164         }
1165         
1166         status = samu_set_unix( sampass, pwd );
1167         if (!NT_STATUS_IS_OK(status)) {
1168                 return status;
1169         }
1170
1171         result = make_server_info(NULL);
1172
1173         if (!NT_STATUS_IS_OK(status)) {
1174                 TALLOC_FREE(sampass);
1175                 return status;
1176         }
1177
1178         result->sam_account = sampass;
1179         result->unix_name = talloc_strdup(result, unix_username);
1180         result->uid = pwd->pw_uid;
1181         result->gid = pwd->pw_gid;
1182
1183         status = pdb_enum_group_memberships(result, sampass,
1184                                             &result->sids, &gids,
1185                                             &result->num_sids);
1186
1187         if (!NT_STATUS_IS_OK(status)) {
1188                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1189                            nt_errstr(status)));
1190                 TALLOC_FREE(result);
1191                 return status;
1192         }
1193
1194         /* For now we throw away the gids and convert via sid_to_gid
1195          * later. This needs fixing, but I'd like to get the code straight and
1196          * simple first. */
1197         TALLOC_FREE(gids);
1198
1199         *server_info = result;
1200
1201         return NT_STATUS_OK;
1202 }
1203
1204 /***************************************************************************
1205  Make (and fill) a user_info struct for a guest login.
1206  This *must* succeed for smbd to start. If there is no mapping entry for
1207  the guest gid, then create one.
1208 **********************
1209 *****************************************************/
1210
1211 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1212 {
1213         NTSTATUS status;
1214         struct samu *sampass = NULL;
1215         DOM_SID guest_sid;
1216         BOOL ret;
1217         static const char zeros[16];
1218
1219         if ( !(sampass = samu_new( NULL )) ) {
1220                 return NT_STATUS_NO_MEMORY;
1221         }
1222
1223         sid_copy(&guest_sid, get_global_sam_sid());
1224         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1225
1226         become_root();
1227         ret = pdb_getsampwsid(sampass, &guest_sid);
1228         unbecome_root();
1229
1230         if (!ret) {
1231                 TALLOC_FREE(sampass);
1232                 return NT_STATUS_NO_SUCH_USER;
1233         }
1234
1235         status = make_server_info_sam(server_info, sampass);
1236         if (!NT_STATUS_IS_OK(status)) {
1237                 TALLOC_FREE(sampass);
1238                 return status;
1239         }
1240         
1241         (*server_info)->guest = True;
1242
1243         status = create_local_token(*server_info);
1244         if (!NT_STATUS_IS_OK(status)) {
1245                 DEBUG(10, ("create_local_token failed: %s\n",
1246                            nt_errstr(status)));
1247                 return status;
1248         }
1249
1250         /* annoying, but the Guest really does have a session key, and it is
1251            all zeros! */
1252         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1253         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1254
1255         return NT_STATUS_OK;
1256 }
1257
1258 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1259 {
1260         auth_serversupplied_info *dst;
1261
1262         dst = make_server_info(NULL);
1263         if (dst == NULL) {
1264                 return NULL;
1265         }
1266
1267         dst->guest = src->guest;
1268         dst->uid = src->uid;
1269         dst->gid = src->gid;
1270         dst->n_groups = src->n_groups;
1271         if (src->n_groups != 0)
1272                 dst->groups = talloc_memdup(dst, src->groups,
1273                                             sizeof(gid_t)*dst->n_groups);
1274         else
1275                 dst->groups = NULL;
1276         dst->ptok = dup_nt_token(dst, src->ptok);
1277         dst->user_session_key = data_blob_talloc(
1278                 dst, src->user_session_key.data,
1279                 src->user_session_key.length);
1280         dst->lm_session_key = data_blob_talloc(
1281                 dst, src->lm_session_key.data,
1282                 src->lm_session_key.length);
1283         pdb_copy_sam_account(src->sam_account, &dst->sam_account);
1284         dst->pam_handle = NULL;
1285         dst->unix_name = talloc_strdup(dst, src->unix_name);
1286
1287         return dst;
1288 }
1289
1290 static auth_serversupplied_info *guest_info = NULL;
1291
1292 BOOL init_guest_info(void)
1293 {
1294         if (guest_info != NULL)
1295                 return True;
1296                 
1297         
1298
1299         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1300 }
1301
1302 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1303 {
1304         *server_info = copy_serverinfo(guest_info);
1305         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1306 }
1307
1308 /***************************************************************************
1309  Purely internal function for make_server_info_info3
1310  Fill the sam account from getpwnam
1311 ***************************************************************************/
1312 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1313                                  const char *domain,
1314                                  const char *username,
1315                                  char **found_username,
1316                                  uid_t *uid, gid_t *gid,
1317                                  struct samu *account)
1318 {
1319         NTSTATUS nt_status;
1320         fstring dom_user, lower_username;
1321         fstring real_username;
1322         struct passwd *passwd;
1323
1324         fstrcpy( lower_username, username );
1325         strlower_m( lower_username );
1326
1327         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1328                 lower_username);
1329
1330         /* get the passwd struct but don't create the user if he/she 
1331            does not exist.  We were explicitly called from a following
1332            a winbindd authentication request so we should assume that 
1333            nss_winbindd is working */
1334
1335         map_username( dom_user );
1336
1337         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1338                 return NT_STATUS_NO_SUCH_USER;
1339
1340         *uid = passwd->pw_uid;
1341         *gid = passwd->pw_gid;
1342
1343         /* This is pointless -- there is no suport for differing 
1344            unix and windows names.  Make sure to always store the 
1345            one we actually looked up and succeeded. Have I mentioned
1346            why I hate the 'winbind use default domain' parameter?   
1347                                          --jerry              */
1348            
1349         *found_username = talloc_strdup( mem_ctx, real_username );
1350         
1351         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1352
1353         nt_status = samu_set_unix( account, passwd );
1354         
1355         TALLOC_FREE(passwd);
1356         
1357         return nt_status;
1358 }
1359
1360 /****************************************************************************
1361  Wrapper to allow the getpwnam() call to strip the domain name and 
1362  try again in case a local UNIX user is already there.  Also run through 
1363  the username if we fallback to the username only.
1364  ****************************************************************************/
1365  
1366 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1367                              fstring save_username, BOOL create )
1368 {
1369         struct passwd *pw = NULL;
1370         char *p;
1371         fstring username;
1372         
1373         /* we only save a copy of the username it has been mangled 
1374            by winbindd use default domain */
1375            
1376         save_username[0] = '\0';
1377            
1378         /* don't call map_username() here since it has to be done higher 
1379            up the stack so we don't call it mutliple times */
1380
1381         fstrcpy( username, domuser );
1382         
1383         p = strchr_m( username, *lp_winbind_separator() );
1384         
1385         /* code for a DOMAIN\user string */
1386         
1387         if ( p ) {
1388                 fstring strip_username;
1389
1390                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1391                 if ( pw ) {     
1392                         /* make sure we get the case of the username correct */
1393                         /* work around 'winbind use default domain = yes' */
1394
1395                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1396                                 char *domain;
1397                                 
1398                                 /* split the domain and username into 2 strings */
1399                                 *p = '\0';
1400                                 domain = username;
1401
1402                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1403                         }
1404                         else
1405                                 fstrcpy( save_username, pw->pw_name );
1406
1407                         /* whew -- done! */             
1408                         return pw;
1409                 }
1410
1411                 /* setup for lookup of just the username */
1412                 /* remember that p and username are overlapping memory */
1413
1414                 p++;
1415                 fstrcpy( strip_username, p );
1416                 fstrcpy( username, strip_username );
1417         }
1418         
1419         /* just lookup a plain username */
1420         
1421         pw = Get_Pwnam_alloc(mem_ctx, username);
1422                 
1423         /* Create local user if requested. */
1424         
1425         if ( !pw && create ) {
1426                 /* Don't add a machine account. */
1427                 if (username[strlen(username)-1] == '$')
1428                         return NULL;
1429
1430                 smb_create_user(NULL, username, NULL);
1431                 pw = Get_Pwnam_alloc(mem_ctx, username);
1432         }
1433         
1434         /* one last check for a valid passwd struct */
1435         
1436         if ( pw )
1437                 fstrcpy( save_username, pw->pw_name );
1438
1439         return pw;
1440 }
1441
1442 /***************************************************************************
1443  Make a server_info struct from the info3 returned by a domain logon 
1444 ***************************************************************************/
1445
1446 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1447                                 const char *internal_username,
1448                                 const char *sent_nt_username,
1449                                 const char *domain,
1450                                 auth_serversupplied_info **server_info, 
1451                                 NET_USER_INFO_3 *info3) 
1452 {
1453         static const char zeros[16];
1454
1455         NTSTATUS nt_status = NT_STATUS_OK;
1456         char *found_username;
1457         const char *nt_domain;
1458         const char *nt_username;
1459         struct samu *sam_account = NULL;
1460         DOM_SID user_sid;
1461         DOM_SID group_sid;
1462
1463         uid_t uid;
1464         gid_t gid;
1465
1466         size_t i;
1467
1468         auth_serversupplied_info *result;
1469
1470         /* 
1471            Here is where we should check the list of
1472            trusted domains, and verify that the SID 
1473            matches.
1474         */
1475
1476         sid_copy(&user_sid, &info3->dom_sid.sid);
1477         if (!sid_append_rid(&user_sid, info3->user_rid)) {
1478                 return NT_STATUS_INVALID_PARAMETER;
1479         }
1480         
1481         sid_copy(&group_sid, &info3->dom_sid.sid);
1482         if (!sid_append_rid(&group_sid, info3->group_rid)) {
1483                 return NT_STATUS_INVALID_PARAMETER;
1484         }
1485
1486         if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1487                 /* If the server didn't give us one, just use the one we sent
1488                  * them */
1489                 nt_username = sent_nt_username;
1490         }
1491
1492         if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1493                 /* If the server didn't give us one, just use the one we sent
1494                  * them */
1495                 nt_domain = domain;
1496         }
1497         
1498         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1499            add user script (2.2.x behavior).
1500
1501            We use the _unmapped_ username here in an attempt to provide
1502            consistent username mapping behavior between kerberos and NTLM[SSP]
1503            authentication in domain mode security.  I.E. Username mapping
1504            should be applied to the fully qualified username
1505            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1506            called map_username() unnecessarily in make_user_info_map() but
1507            that is how the current code is designed.  Making the change here
1508            is the least disruptive place.  -- jerry */
1509            
1510         if ( !(sam_account = samu_new( NULL )) ) {
1511                 return NT_STATUS_NO_MEMORY;
1512         }
1513
1514         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1515                                      &found_username, &uid, &gid, sam_account);
1516
1517         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
1518                 DEBUG(3,("User %s does not exist, trying to add it\n",
1519                          internal_username));
1520                 smb_create_user( nt_domain, sent_nt_username, NULL);
1521                 nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username, 
1522                                               &found_username, &uid, &gid, sam_account );
1523         }
1524         
1525         /* if we still don't have a valid unix account check for 
1526           'map to gues = bad uid' */
1527           
1528         if (!NT_STATUS_IS_OK(nt_status)) {
1529                 TALLOC_FREE( sam_account );
1530                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1531                         make_server_info_guest(server_info); 
1532                         return NT_STATUS_OK;
1533                 }
1534                 return nt_status;
1535         }
1536                 
1537         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1538                 TALLOC_FREE(sam_account);
1539                 return NT_STATUS_NO_MEMORY;
1540         }
1541
1542         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1543                 TALLOC_FREE(sam_account);
1544                 return NT_STATUS_NO_MEMORY;
1545         }
1546
1547         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1548                 TALLOC_FREE(sam_account);
1549                 return NT_STATUS_NO_MEMORY;
1550         }
1551
1552         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1553                 TALLOC_FREE(sam_account);
1554                 return NT_STATUS_UNSUCCESSFUL;
1555         }
1556
1557         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1558                 TALLOC_FREE(sam_account);
1559                 return NT_STATUS_UNSUCCESSFUL;
1560         }
1561                 
1562         if (!pdb_set_fullname(sam_account,
1563                               unistr2_static(&(info3->uni_full_name)), 
1564                               PDB_CHANGED)) {
1565                 TALLOC_FREE(sam_account);
1566                 return NT_STATUS_NO_MEMORY;
1567         }
1568
1569         if (!pdb_set_logon_script(sam_account,
1570                                   unistr2_static(&(info3->uni_logon_script)),
1571                                   PDB_CHANGED)) {
1572                 TALLOC_FREE(sam_account);
1573                 return NT_STATUS_NO_MEMORY;
1574         }
1575
1576         if (!pdb_set_profile_path(sam_account,
1577                                   unistr2_static(&(info3->uni_profile_path)),
1578                                   PDB_CHANGED)) {
1579                 TALLOC_FREE(sam_account);
1580                 return NT_STATUS_NO_MEMORY;
1581         }
1582
1583         if (!pdb_set_homedir(sam_account,
1584                              unistr2_static(&(info3->uni_home_dir)),
1585                              PDB_CHANGED)) {
1586                 TALLOC_FREE(sam_account);
1587                 return NT_STATUS_NO_MEMORY;
1588         }
1589
1590         if (!pdb_set_dir_drive(sam_account,
1591                                unistr2_static(&(info3->uni_dir_drive)),
1592                                PDB_CHANGED)) {
1593                 TALLOC_FREE(sam_account);
1594                 return NT_STATUS_NO_MEMORY;
1595         }
1596
1597         result = make_server_info(NULL);
1598         if (result == NULL) {
1599                 DEBUG(4, ("make_server_info failed!\n"));
1600                 TALLOC_FREE(sam_account);
1601                 return NT_STATUS_NO_MEMORY;
1602         }
1603
1604         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1605            valid struct samu) */
1606                    
1607         result->sam_account = sam_account;
1608         result->unix_name = talloc_strdup(result, found_username);
1609
1610         /* Fill in the unix info we found on the way */
1611
1612         result->uid = uid;
1613         result->gid = gid;
1614
1615         /* Create a 'combined' list of all SIDs we might want in the SD */
1616
1617         result->num_sids = 0;
1618         result->sids = NULL;
1619
1620         /* and create (by appending rids) the 'domain' sids */
1621         
1622         for (i = 0; i < info3->num_groups2; i++) {
1623                 DOM_SID sid;
1624                 if (!sid_compose(&sid, &info3->dom_sid.sid,
1625                                  info3->gids[i].g_rid)) {
1626                         DEBUG(3,("could not append additional group rid "
1627                                  "0x%x\n", info3->gids[i].g_rid));
1628                         TALLOC_FREE(result);
1629                         return NT_STATUS_INVALID_PARAMETER;
1630                 }
1631                 add_sid_to_array(result, &sid, &result->sids,
1632                                  &result->num_sids);
1633         }
1634
1635         /* Copy 'other' sids.  We need to do sid filtering here to
1636            prevent possible elevation of privileges.  See:
1637
1638            http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1639          */
1640
1641         for (i = 0; i < info3->num_other_sids; i++) {
1642                 add_sid_to_array(result, &info3->other_sids[i].sid,
1643                                  &result->sids,
1644                                  &result->num_sids);
1645         }
1646
1647         result->login_server = unistr2_tdup(result, 
1648                                             &(info3->uni_logon_srv));
1649
1650         /* ensure we are never given NULL session keys */
1651         
1652         if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1653                 result->user_session_key = data_blob(NULL, 0);
1654         } else {
1655                 result->user_session_key = data_blob_talloc(
1656                         result, info3->user_sess_key,
1657                         sizeof(info3->user_sess_key));
1658         }
1659
1660         if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1661                 result->lm_session_key = data_blob(NULL, 0);
1662         } else {
1663                 result->lm_session_key = data_blob_talloc(
1664                         result, info3->lm_sess_key,
1665                         sizeof(info3->lm_sess_key));
1666         }
1667
1668         *server_info = result;
1669
1670         return NT_STATUS_OK;
1671 }
1672
1673 /***************************************************************************
1674  Free a user_info struct
1675 ***************************************************************************/
1676
1677 void free_user_info(auth_usersupplied_info **user_info)
1678 {
1679         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1680         if (*user_info != NULL) {
1681                 if ((*user_info)->smb_name) {
1682                         DEBUG(10,("structure was created for %s\n",
1683                                   (*user_info)->smb_name));
1684                 }
1685                 SAFE_FREE((*user_info)->smb_name);
1686                 SAFE_FREE((*user_info)->internal_username);
1687                 SAFE_FREE((*user_info)->client_domain);
1688                 SAFE_FREE((*user_info)->domain);
1689                 SAFE_FREE((*user_info)->wksta_name);
1690                 data_blob_free(&(*user_info)->lm_resp);
1691                 data_blob_free(&(*user_info)->nt_resp);
1692                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1693                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1694                 data_blob_clear_free(&(*user_info)->plaintext_password);
1695                 ZERO_STRUCT(**user_info);
1696         }
1697         SAFE_FREE(*user_info);
1698 }
1699
1700 /***************************************************************************
1701  Make an auth_methods struct
1702 ***************************************************************************/
1703
1704 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1705 {
1706         if (!auth_context) {
1707                 smb_panic("no auth_context supplied to "
1708                           "make_auth_methods()!\n");
1709         }
1710
1711         if (!auth_method) {
1712                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1713                           "is NULL!\n");
1714         }
1715
1716         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1717         if (!*auth_method) {
1718                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1719                 return False;
1720         }
1721         ZERO_STRUCTP(*auth_method);
1722         
1723         return True;
1724 }
1725
1726 /****************************************************************************
1727  Duplicate a SID token.
1728 ****************************************************************************/
1729
1730 NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken)
1731 {
1732         NT_USER_TOKEN *token;
1733
1734         if (!ptoken)
1735                 return NULL;
1736
1737         token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
1738         if (token == NULL) {
1739                 DEBUG(0, ("talloc failed\n"));
1740                 return NULL;
1741         }
1742
1743         token->user_sids = talloc_memdup(token, ptoken->user_sids,
1744                                          sizeof(DOM_SID) * ptoken->num_sids );
1745
1746         if ((ptoken->user_sids != NULL) && (token->user_sids == NULL)) {
1747                 DEBUG(0, ("talloc_memdup failed\n"));
1748                 TALLOC_FREE(token);
1749                 return NULL;
1750         }
1751
1752         token->num_sids = ptoken->num_sids;
1753         
1754         /* copy the privileges; don't consider failure to be critical here */
1755         
1756         if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1757                 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!.  "
1758                          "Continuing with 0 privileges assigned.\n"));
1759         }
1760
1761         return token;
1762 }
1763
1764 /****************************************************************************
1765  Check for a SID in an NT_USER_TOKEN
1766 ****************************************************************************/
1767
1768 BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
1769 {
1770         int i;
1771         
1772         if ( !sid || !token )
1773                 return False;
1774         
1775         for ( i=0; i<token->num_sids; i++ ) {
1776                 if ( sid_equal( sid, &token->user_sids[i] ) )
1777                         return True;
1778         }
1779
1780         return False;
1781 }
1782
1783 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 
1784 {
1785         DOM_SID domain_sid;
1786
1787         /* if we are a domain member, the get the domain SID, else for 
1788            a DC or standalone server, use our own SID */
1789
1790         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1791                 if ( !secrets_fetch_domain_sid( lp_workgroup(),
1792                                                 &domain_sid ) ) {
1793                         DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
1794                                  "SID for domain [%s]\n", lp_workgroup()));
1795                         return False;
1796                 }
1797         } 
1798         else
1799                 sid_copy( &domain_sid, get_global_sam_sid() );
1800
1801         sid_append_rid( &domain_sid, rid );
1802         
1803         return nt_token_check_sid( &domain_sid, token );\
1804 }
1805
1806 /**
1807  * Verify whether or not given domain is trusted.
1808  *
1809  * @param domain_name name of the domain to be verified
1810  * @return true if domain is one of the trusted once or
1811  *         false if otherwise
1812  **/
1813
1814 BOOL is_trusted_domain(const char* dom_name)
1815 {
1816         DOM_SID trustdom_sid;
1817         BOOL ret;
1818
1819         /* no trusted domains for a standalone server */
1820
1821         if ( lp_server_role() == ROLE_STANDALONE )
1822                 return False;
1823
1824         /* if we are a DC, then check for a direct trust relationships */
1825
1826         if ( IS_DC ) {
1827                 become_root();
1828                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1829                           "[%s]\n", dom_name ));
1830                 ret = secrets_fetch_trusted_domain_password(dom_name, NULL,
1831                                                             NULL, NULL);
1832                 unbecome_root();
1833                 if (ret)
1834                         return True;
1835         }
1836         else {
1837                 NSS_STATUS result;
1838
1839                 /* If winbind is around, ask it */
1840
1841                 result = wb_is_trusted_domain(dom_name);
1842
1843                 if (result == NSS_STATUS_SUCCESS) {
1844                         return True;
1845                 }
1846
1847                 if (result == NSS_STATUS_NOTFOUND) {
1848                         /* winbind could not find the domain */
1849                         return False;
1850                 }
1851
1852                 /* The only other possible result is that winbind is not up
1853                    and running. We need to update the trustdom_cache
1854                    ourselves */
1855                 
1856                 update_trustdom_cache();
1857         }
1858
1859         /* now the trustdom cache should be available a DC could still
1860          * have a transitive trust so fall back to the cache of trusted
1861          * domains (like a domain member would use  */
1862
1863         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1864                 return True;
1865         }
1866
1867         return False;
1868 }
1869