r14403: * modifies create_local_nt_token() to create a BUILTIN\Administrators
[nivanova/samba-autobuild/.git] / source3 / auth / auth_util.c
1 /*
2    Unix SMB/CIFS implementation.
3    Authentication utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett 2001
6    Copyright (C) Jeremy Allison 2000-2001
7    Copyright (C) Rafal Szczesniak 2002
8    Copyright (C) Volker Lendecke 2006
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
29
30 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
31                                                    const DOM_SID *user_sid,
32                                                    const DOM_SID *group_sid,
33                                                    BOOL is_guest,
34                                                    int num_groupsids,
35                                                    const DOM_SID *groupsids);
36
37 /****************************************************************************
38  Create a UNIX user on demand.
39 ****************************************************************************/
40
41 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
42 {
43         pstring add_script;
44         int ret;
45
46         pstrcpy(add_script, lp_adduser_script());
47         if (! *add_script)
48                 return -1;
49         all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
50         if (domain)
51                 all_string_sub(add_script, "%D", domain, sizeof(pstring));
52         if (homedir)
53                 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
54         ret = smbrun(add_script,NULL);
55         flush_pwnam_cache();
56         DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
57         return ret;
58 }
59
60 /****************************************************************************
61  Create an auth_usersupplied_data structure
62 ****************************************************************************/
63
64 static NTSTATUS make_user_info(auth_usersupplied_info **user_info, 
65                                const char *smb_name, 
66                                const char *internal_username,
67                                const char *client_domain, 
68                                const char *domain,
69                                const char *wksta_name, 
70                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
71                                DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
72                                DATA_BLOB *plaintext, 
73                                BOOL encrypted)
74 {
75
76         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
77
78         *user_info = SMB_MALLOC_P(auth_usersupplied_info);
79         if (*user_info == NULL) {
80                 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
81                 return NT_STATUS_NO_MEMORY;
82         }
83
84         ZERO_STRUCTP(*user_info);
85
86         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
87
88         (*user_info)->smb_name = SMB_STRDUP(smb_name);
89         if ((*user_info)->smb_name == NULL) { 
90                 free_user_info(user_info);
91                 return NT_STATUS_NO_MEMORY;
92         }
93         
94         (*user_info)->internal_username = SMB_STRDUP(internal_username);
95         if ((*user_info)->internal_username == NULL) { 
96                 free_user_info(user_info);
97                 return NT_STATUS_NO_MEMORY;
98         }
99
100         (*user_info)->domain = SMB_STRDUP(domain);
101         if ((*user_info)->domain == NULL) { 
102                 free_user_info(user_info);
103                 return NT_STATUS_NO_MEMORY;
104         }
105
106         (*user_info)->client_domain = SMB_STRDUP(client_domain);
107         if ((*user_info)->client_domain == NULL) { 
108                 free_user_info(user_info);
109                 return NT_STATUS_NO_MEMORY;
110         }
111
112         (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
113         if ((*user_info)->wksta_name == NULL) { 
114                 free_user_info(user_info);
115                 return NT_STATUS_NO_MEMORY;
116         }
117
118         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
119
120         if (lm_pwd)
121                 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
122         if (nt_pwd)
123                 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
124         if (lm_interactive_pwd)
125                 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
126         if (nt_interactive_pwd)
127                 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
128
129         if (plaintext)
130                 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
131
132         (*user_info)->encrypted = encrypted;
133
134         (*user_info)->logon_parameters = 0;
135
136         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
137
138         return NT_STATUS_OK;
139 }
140
141 /****************************************************************************
142  Create an auth_usersupplied_data structure after appropriate mapping.
143 ****************************************************************************/
144
145 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, 
146                             const char *smb_name, 
147                             const char *client_domain, 
148                             const char *wksta_name, 
149                             DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
150                             DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
151                             DATA_BLOB *plaintext, 
152                             BOOL encrypted)
153 {
154         const char *domain;
155         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 *******************************************************************/
682
683 static NTSTATUS add_builtin_administrators( TALLOC_CTX *ctx, struct nt_user_token *token )
684 {
685         return NT_STATUS_OK;
686 }
687
688 /*******************************************************************
689 *******************************************************************/
690
691 static NTSTATUS create_builtin_administrators( void )
692 {
693         NTSTATUS status;
694         DOM_SID dom_admins, root_sid;
695         fstring root_name;
696         enum SID_NAME_USE type;         
697         TALLOC_CTX *ctx;
698         BOOL ret;
699
700         status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
701         if ( !NT_STATUS_IS_OK(status) ) {
702                 DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
703                 return status;
704         }
705         
706         /* add domain admins */
707         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 
708                 && secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
709         {
710                 sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
711                 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
712                 if ( !NT_STATUS_IS_OK(status) ) {
713                         DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
714                                 " Administrators\n"));
715                         return status;
716                 }
717         }
718                         
719         /* add root */
720         if ( (ctx = talloc_init(NULL)) == NULL ) {
721                 return NT_STATUS_NO_MEMORY;
722         }
723         fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
724         ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
725         TALLOC_FREE( ctx );
726
727         if ( ret ) {
728                 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
729                 if ( !NT_STATUS_IS_OK(status) ) {
730                         DEBUG(0,("create_builtin_administrators: Failed to add root"
731                                 " Administrators\n"));
732                         return status;
733                 }
734         }
735         
736         return NT_STATUS_OK;
737 }               
738
739 /*******************************************************************
740  Create a NT token for the user, expanding local aliases
741 *******************************************************************/
742
743 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
744                                                    const DOM_SID *user_sid,
745                                                    const DOM_SID *group_sid,
746                                                    BOOL is_guest,
747                                                    int num_groupsids,
748                                                    const DOM_SID *groupsids)
749 {
750         TALLOC_CTX *tmp_ctx;
751         struct nt_user_token *result = NULL;
752         int i;
753         NTSTATUS status;
754         gid_t gid;
755
756         tmp_ctx = talloc_new(mem_ctx);
757         if (tmp_ctx == NULL) {
758                 DEBUG(0, ("talloc_new failed\n"));
759                 return NULL;
760         }
761
762         result = TALLOC_ZERO_P(tmp_ctx, NT_USER_TOKEN);
763         if (result == NULL) {
764                 DEBUG(0, ("talloc failed\n"));
765                 goto done;
766         }
767
768         /* Add the user and primary group sid */
769
770         add_sid_to_array(result, user_sid,
771                          &result->user_sids, &result->num_sids);
772         add_sid_to_array(result, group_sid,
773                          &result->user_sids, &result->num_sids);
774                          
775         /* Add in BUILTIN sids */
776         
777         add_sid_to_array(result, &global_sid_World,
778                          &result->user_sids, &result->num_sids);
779         add_sid_to_array(result, &global_sid_Network,
780                          &result->user_sids, &result->num_sids);
781
782         if (is_guest) {
783                 add_sid_to_array(result, &global_sid_Builtin_Guests,
784                                  &result->user_sids, &result->num_sids);
785         } else {
786                 add_sid_to_array(result, &global_sid_Authenticated_Users,
787                                  &result->user_sids, &result->num_sids);
788         }
789         
790         /* Now the SIDs we got from authentication. These are the ones from
791          * the info3 struct or from the pdb_enum_group_memberships, depending
792          * on who authenticated the user. */
793
794         for (i=0; i<num_groupsids; i++) {
795                 add_sid_to_array_unique(result, &groupsids[i],
796                                         &result->user_sids, &result->num_sids);
797         }
798         
799         /* Deal with the BUILTIN\Administrators group.  If the SID can
800            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
801            handled it. */
802
803         if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
804                 /* We can only create a mapping if winbind is running 
805                    and the nested group functionality has been enabled */
806                    
807                 if ( lp_winbind_nested_groups() ) {
808                         become_root();
809                         status = create_builtin_administrators( );
810                         if ( !NT_STATUS_IS_OK(status) ) {
811                                 DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
812                                 /* don't fail, just log the message */
813                         }
814                         unbecome_root();
815                 }
816                 else {
817                         status = add_builtin_administrators( tmp_ctx, result ); 
818                         if ( !NT_STATUS_IS_OK(status) ) {                       
819                                 result = NULL;
820                                 goto done;
821                         }                       
822                 }               
823         }
824
825         /* Deal with local groups */
826         
827         if (lp_winbind_nested_groups()) {
828
829                 /* Now add the aliases. First the one from our local SAM */
830
831                 status = add_aliases(tmp_ctx, get_global_sam_sid(), result);
832
833                 if (!NT_STATUS_IS_OK(status)) {
834                         result = NULL;
835                         goto done;
836                 }
837
838                 /* Finally the builtin ones */
839
840                 status = add_aliases(tmp_ctx, &global_sid_Builtin, result);
841
842                 if (!NT_STATUS_IS_OK(status)) {
843                         result = NULL;
844                         goto done;
845                 }
846         } 
847
848
849         get_privileges_for_sids(&result->privileges, result->user_sids,
850                                 result->num_sids);
851
852         talloc_steal(mem_ctx, result);
853
854  done:
855         TALLOC_FREE(tmp_ctx);
856         return result;
857 }
858
859 /*
860  * Create the token to use from server_info->sam_account and
861  * server_info->sids (the info3/sam groups). Find the unix gids.
862  */
863
864 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
865 {
866         TALLOC_CTX *mem_ctx;
867         NTSTATUS status;
868         size_t i;
869         
870
871         mem_ctx = talloc_new(NULL);
872         if (mem_ctx == NULL) {
873                 DEBUG(0, ("talloc_new failed\n"));
874                 return NT_STATUS_NO_MEMORY;
875         }
876
877         server_info->ptok = create_local_nt_token(
878                 server_info,
879                 pdb_get_user_sid(server_info->sam_account),
880                 pdb_get_group_sid(server_info->sam_account),
881                 server_info->guest,
882                 server_info->num_sids, server_info->sids);
883
884         if ( !server_info->ptok ) {
885                 return NT_STATUS_NO_SUCH_USER;
886         }
887         
888         /* Convert the SIDs to gids. */
889
890         server_info->n_groups = 0;
891         server_info->groups = NULL;
892
893         /* Start at index 1, where the groups start. */
894
895         for (i=1; i<server_info->ptok->num_sids; i++) {
896                 gid_t gid;
897                 DOM_SID *sid = &server_info->ptok->user_sids[i];
898
899                 if (!sid_to_gid(sid, &gid)) {
900                         DEBUG(10, ("Could not convert SID %s to gid, "
901                                    "ignoring it\n", sid_string_static(sid)));
902                         continue;
903                 }
904                 add_gid_to_array_unique(server_info, gid, &server_info->groups,
905                                         &server_info->n_groups);
906         }
907         
908         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
909
910         status = log_nt_token(mem_ctx, server_info->ptok);
911
912         TALLOC_FREE(mem_ctx);
913         return status;
914 }
915
916 /*
917  * Create an artificial NT token given just a username. (Initially indended
918  * for force user)
919  *
920  * We go through lookup_name() to avoid problems we had with 'winbind use
921  * default domain'.
922  *
923  * We have 3 cases:
924  *
925  * unmapped unix users: Go directly to nss to find the user's group.
926  *
927  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
928  *
929  * If the user is provided by winbind, the primary gid is set to "domain
930  * users" of the user's domain. For an explanation why this is necessary, see
931  * the thread starting at
932  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
933  */
934
935 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
936                                     BOOL is_guest,
937                                     uid_t *uid, gid_t *gid,
938                                     char **found_username,
939                                     struct nt_user_token **token)
940 {
941         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
942         TALLOC_CTX *tmp_ctx;
943         DOM_SID user_sid;
944         enum SID_NAME_USE type;
945         gid_t *gids;
946         DOM_SID primary_group_sid;
947         DOM_SID *group_sids;
948         size_t num_group_sids;
949
950         tmp_ctx = talloc_new(NULL);
951         if (tmp_ctx == NULL) {
952                 DEBUG(0, ("talloc_new failed\n"));
953                 return NT_STATUS_NO_MEMORY;
954         }
955
956         if (!lookup_name(tmp_ctx, username, LOOKUP_NAME_ALL,
957                          NULL, NULL, &user_sid, &type)) {
958                 DEBUG(1, ("lookup_name for %s failed\n", username));
959                 goto done;
960         }
961
962         if (type != SID_NAME_USER) {
963                 DEBUG(1, ("%s is a %s, not a user\n", username,
964                           sid_type_lookup(type)));
965                 goto done;
966         }
967
968         if (!sid_to_uid(&user_sid, uid)) {
969                 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
970                           username, sid_string_static(&user_sid)));
971                 goto done;
972         }
973
974         if (sid_check_is_in_unix_users(&user_sid)) {
975
976                 /* This is a unix user not in passdb. We need to ask nss
977                  * directly, without consulting passdb */
978
979                 struct passwd *pass;
980                 size_t i;
981
982                 pass = getpwuid_alloc(tmp_ctx, *uid);
983                 if (pass == NULL) {
984                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
985                                   *uid, username));
986                         goto done;
987                 }
988
989                 *gid = pass->pw_gid;
990                 gid_to_sid(&primary_group_sid, pass->pw_gid);
991
992                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
993                                          &gids, &num_group_sids)) {
994                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
995                                   username));
996                         goto done;
997                 }
998
999                 group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids);
1000                 if (group_sids == NULL) {
1001                         DEBUG(1, ("talloc_array failed\n"));
1002                         result = NT_STATUS_NO_MEMORY;
1003                         goto done;
1004                 }
1005
1006                 for (i=0; i<num_group_sids; i++) {
1007                         gid_to_sid(&group_sids[i], gids[i]);
1008                 }
1009                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
1010
1011         } else if (sid_check_is_in_our_domain(&user_sid)) {
1012
1013                 /* This is a passdb user, so ask passdb */
1014
1015                 struct samu *sam_acct = NULL;
1016
1017                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
1018                         goto done;
1019                 }
1020
1021                 if (!pdb_getsampwsid(sam_acct, &user_sid)) {
1022                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
1023                                   sid_string_static(&user_sid), username));
1024                         result = NT_STATUS_NO_SUCH_USER;
1025                         goto done;
1026                 }
1027
1028                 sid_copy(&primary_group_sid, pdb_get_group_sid(sam_acct));
1029
1030                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
1031                                                     &group_sids, &gids,
1032                                                     &num_group_sids);
1033                 if (!NT_STATUS_IS_OK(result)) {
1034                         DEBUG(10, ("enum_group_memberships failed for %s\n",
1035                                    username));
1036                         goto done;
1037                 }
1038
1039                 *found_username = talloc_strdup(mem_ctx,
1040                                                 pdb_get_username(sam_acct));
1041
1042         } else {
1043
1044                 /* This user is from winbind, force the primary gid to the
1045                  * user's "domain users" group. Under certain circumstances
1046                  * (user comes from NT4), this might be a loss of
1047                  * information. But we can not rely on winbind getting the
1048                  * correct info. AD might prohibit winbind looking up that
1049                  * information. */
1050
1051                 uint32 dummy;
1052
1053                 sid_copy(&primary_group_sid, &user_sid);
1054                 sid_split_rid(&primary_group_sid, &dummy);
1055                 sid_append_rid(&primary_group_sid, DOMAIN_GROUP_RID_USERS);
1056
1057                 if (!sid_to_gid(&primary_group_sid, gid)) {
1058                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1059                                   sid_string_static(&primary_group_sid)));
1060                         goto done;
1061                 }
1062
1063                 num_group_sids = 0;
1064                 group_sids = NULL;
1065
1066                 *found_username = talloc_strdup(mem_ctx, username);
1067         }
1068
1069         *token = create_local_nt_token(mem_ctx, &user_sid, &primary_group_sid,
1070                                        is_guest, num_group_sids, group_sids);
1071
1072         if ((*token == NULL) || (*found_username == NULL)) {
1073                 result = NT_STATUS_NO_MEMORY;
1074                 goto done;
1075         }
1076
1077         result = NT_STATUS_OK;
1078  done:
1079         TALLOC_FREE(tmp_ctx);
1080         return result;
1081 }
1082
1083 /***************************************************************************
1084  Build upon create_token_from_username:
1085
1086  Expensive helper function to figure out whether a user given its name is
1087  member of a particular group.
1088 ***************************************************************************/
1089 BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
1090 {
1091         NTSTATUS status;
1092         uid_t uid;
1093         gid_t gid;
1094         char *found_username;
1095         struct nt_user_token *token;
1096         BOOL result;
1097
1098         TALLOC_CTX *mem_ctx;
1099
1100         mem_ctx = talloc_new(NULL);
1101         if (mem_ctx == NULL) {
1102                 DEBUG(0, ("talloc_new failed\n"));
1103                 return False;
1104         }
1105
1106         status = create_token_from_username(mem_ctx, username, False,
1107                                             &uid, &gid, &found_username,
1108                                             &token);
1109
1110         if (!NT_STATUS_IS_OK(status)) {
1111                 DEBUG(10, ("could not create token for %s\n", username));
1112                 return False;
1113         }
1114
1115         result = nt_token_check_sid(group_sid, token);
1116
1117         TALLOC_FREE(mem_ctx);
1118         return result;
1119         
1120 }
1121
1122 BOOL user_in_group(const char *username, const char *groupname)
1123 {
1124         TALLOC_CTX *mem_ctx;
1125         DOM_SID group_sid;
1126         NTSTATUS status;
1127         BOOL ret;
1128
1129         mem_ctx = talloc_new(NULL);
1130         if (mem_ctx == NULL) {
1131                 DEBUG(0, ("talloc_new failed\n"));
1132                 return False;
1133         }
1134
1135         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1136                           NULL, NULL, &group_sid, NULL);
1137         TALLOC_FREE(mem_ctx);
1138
1139         if (!ret) {
1140                 DEBUG(10, ("lookup_name(%s) failed: %s\n", groupname,
1141                            nt_errstr(status)));
1142                 return False;
1143         }
1144
1145         return user_in_group_sid(username, &group_sid);
1146 }
1147
1148
1149 /***************************************************************************
1150  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
1151  to a struct samu
1152 ***************************************************************************/
1153
1154 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1155                              char *unix_username,
1156                              struct passwd *pwd)
1157 {
1158         NTSTATUS status;
1159         struct samu *sampass = NULL;
1160         gid_t *gids;
1161         auth_serversupplied_info *result;
1162         
1163         if ( !(sampass = samu_new( NULL )) ) {
1164                 return NT_STATUS_NO_MEMORY;
1165         }
1166         
1167         status = samu_set_unix( sampass, pwd );
1168         if (!NT_STATUS_IS_OK(status)) {
1169                 return status;
1170         }
1171
1172         result = make_server_info(NULL);
1173
1174         if (!NT_STATUS_IS_OK(status)) {
1175                 TALLOC_FREE(sampass);
1176                 return status;
1177         }
1178
1179         result->sam_account = sampass;
1180         result->unix_name = talloc_strdup(result, unix_username);
1181         result->uid = pwd->pw_uid;
1182         result->gid = pwd->pw_gid;
1183
1184         status = pdb_enum_group_memberships(result, sampass,
1185                                             &result->sids, &gids,
1186                                             &result->num_sids);
1187
1188         if (!NT_STATUS_IS_OK(status)) {
1189                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1190                            nt_errstr(status)));
1191                 TALLOC_FREE(result);
1192                 return status;
1193         }
1194
1195         /* For now we throw away the gids and convert via sid_to_gid
1196          * later. This needs fixing, but I'd like to get the code straight and
1197          * simple first. */
1198         TALLOC_FREE(gids);
1199
1200         *server_info = result;
1201
1202         return NT_STATUS_OK;
1203 }
1204
1205 /***************************************************************************
1206  Make (and fill) a user_info struct for a guest login.
1207  This *must* succeed for smbd to start. If there is no mapping entry for
1208  the guest gid, then create one.
1209 **********************
1210 *****************************************************/
1211
1212 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1213 {
1214         NTSTATUS status;
1215         struct samu *sampass = NULL;
1216         DOM_SID guest_sid;
1217         BOOL ret;
1218         static const char zeros[16];
1219
1220         if ( !(sampass = samu_new( NULL )) ) {
1221                 return NT_STATUS_NO_MEMORY;
1222         }
1223
1224         sid_copy(&guest_sid, get_global_sam_sid());
1225         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1226
1227         become_root();
1228         ret = pdb_getsampwsid(sampass, &guest_sid);
1229         unbecome_root();
1230
1231         if (!ret) {
1232                 TALLOC_FREE(sampass);
1233                 return NT_STATUS_NO_SUCH_USER;
1234         }
1235
1236         status = make_server_info_sam(server_info, sampass);
1237         if (!NT_STATUS_IS_OK(status)) {
1238                 TALLOC_FREE(sampass);
1239                 return status;
1240         }
1241         
1242         (*server_info)->guest = True;
1243
1244         status = create_local_token(*server_info);
1245         if (!NT_STATUS_IS_OK(status)) {
1246                 DEBUG(10, ("create_local_token failed: %s\n",
1247                            nt_errstr(status)));
1248                 return status;
1249         }
1250
1251         /* annoying, but the Guest really does have a session key, and it is
1252            all zeros! */
1253         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1254         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1255
1256         return NT_STATUS_OK;
1257 }
1258
1259 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1260 {
1261         auth_serversupplied_info *dst;
1262
1263         dst = make_server_info(NULL);
1264         if (dst == NULL) {
1265                 return NULL;
1266         }
1267
1268         dst->guest = src->guest;
1269         dst->uid = src->uid;
1270         dst->gid = src->gid;
1271         dst->n_groups = src->n_groups;
1272         if (src->n_groups != 0)
1273                 dst->groups = talloc_memdup(dst, src->groups,
1274                                             sizeof(gid_t)*dst->n_groups);
1275         else
1276                 dst->groups = NULL;
1277                 
1278         dst->ptok = dup_nt_token(dst, src->ptok);
1279         
1280         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1281                 src->user_session_key.length);
1282                 
1283         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1284                 src->lm_session_key.length);
1285                 
1286         if ( (dst->sam_account = samu_new( NULL )) != NULL )
1287                 pdb_copy_sam_account(dst->sam_account, src->sam_account);
1288         
1289         dst->pam_handle = NULL;
1290         dst->unix_name = talloc_strdup(dst, src->unix_name);
1291
1292         return dst;
1293 }
1294
1295 static auth_serversupplied_info *guest_info = NULL;
1296
1297 BOOL init_guest_info(void)
1298 {
1299         if (guest_info != NULL)
1300                 return True;
1301
1302         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1303 }
1304
1305 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1306 {
1307         *server_info = copy_serverinfo(guest_info);
1308         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1309 }
1310
1311 /***************************************************************************
1312  Purely internal function for make_server_info_info3
1313  Fill the sam account from getpwnam
1314 ***************************************************************************/
1315 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1316                                  const char *domain,
1317                                  const char *username,
1318                                  char **found_username,
1319                                  uid_t *uid, gid_t *gid,
1320                                  struct samu *account)
1321 {
1322         NTSTATUS nt_status;
1323         fstring dom_user, lower_username;
1324         fstring real_username;
1325         struct passwd *passwd;
1326
1327         fstrcpy( lower_username, username );
1328         strlower_m( lower_username );
1329
1330         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1331                 lower_username);
1332
1333         /* get the passwd struct but don't create the user if he/she 
1334            does not exist.  We were explicitly called from a following
1335            a winbindd authentication request so we should assume that 
1336            nss_winbindd is working */
1337
1338         map_username( dom_user );
1339
1340         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1341                 return NT_STATUS_NO_SUCH_USER;
1342
1343         *uid = passwd->pw_uid;
1344         *gid = passwd->pw_gid;
1345
1346         /* This is pointless -- there is no suport for differing 
1347            unix and windows names.  Make sure to always store the 
1348            one we actually looked up and succeeded. Have I mentioned
1349            why I hate the 'winbind use default domain' parameter?   
1350                                          --jerry              */
1351            
1352         *found_username = talloc_strdup( mem_ctx, real_username );
1353         
1354         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1355
1356         nt_status = samu_set_unix( account, passwd );
1357         
1358         TALLOC_FREE(passwd);
1359         
1360         return nt_status;
1361 }
1362
1363 /****************************************************************************
1364  Wrapper to allow the getpwnam() call to strip the domain name and 
1365  try again in case a local UNIX user is already there.  Also run through 
1366  the username if we fallback to the username only.
1367  ****************************************************************************/
1368  
1369 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1370                              fstring save_username, BOOL create )
1371 {
1372         struct passwd *pw = NULL;
1373         char *p;
1374         fstring username;
1375         
1376         /* we only save a copy of the username it has been mangled 
1377            by winbindd use default domain */
1378            
1379         save_username[0] = '\0';
1380            
1381         /* don't call map_username() here since it has to be done higher 
1382            up the stack so we don't call it mutliple times */
1383
1384         fstrcpy( username, domuser );
1385         
1386         p = strchr_m( username, *lp_winbind_separator() );
1387         
1388         /* code for a DOMAIN\user string */
1389         
1390         if ( p ) {
1391                 fstring strip_username;
1392
1393                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1394                 if ( pw ) {     
1395                         /* make sure we get the case of the username correct */
1396                         /* work around 'winbind use default domain = yes' */
1397
1398                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1399                                 char *domain;
1400                                 
1401                                 /* split the domain and username into 2 strings */
1402                                 *p = '\0';
1403                                 domain = username;
1404
1405                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1406                         }
1407                         else
1408                                 fstrcpy( save_username, pw->pw_name );
1409
1410                         /* whew -- done! */             
1411                         return pw;
1412                 }
1413
1414                 /* setup for lookup of just the username */
1415                 /* remember that p and username are overlapping memory */
1416
1417                 p++;
1418                 fstrcpy( strip_username, p );
1419                 fstrcpy( username, strip_username );
1420         }
1421         
1422         /* just lookup a plain username */
1423         
1424         pw = Get_Pwnam_alloc(mem_ctx, username);
1425                 
1426         /* Create local user if requested. */
1427         
1428         if ( !pw && create ) {
1429                 /* Don't add a machine account. */
1430                 if (username[strlen(username)-1] == '$')
1431                         return NULL;
1432
1433                 smb_create_user(NULL, username, NULL);
1434                 pw = Get_Pwnam_alloc(mem_ctx, username);
1435         }
1436         
1437         /* one last check for a valid passwd struct */
1438         
1439         if ( pw )
1440                 fstrcpy( save_username, pw->pw_name );
1441
1442         return pw;
1443 }
1444
1445 /***************************************************************************
1446  Make a server_info struct from the info3 returned by a domain logon 
1447 ***************************************************************************/
1448
1449 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1450                                 const char *internal_username,
1451                                 const char *sent_nt_username,
1452                                 const char *domain,
1453                                 auth_serversupplied_info **server_info, 
1454                                 NET_USER_INFO_3 *info3) 
1455 {
1456         static const char zeros[16];
1457
1458         NTSTATUS nt_status = NT_STATUS_OK;
1459         char *found_username;
1460         const char *nt_domain;
1461         const char *nt_username;
1462         struct samu *sam_account = NULL;
1463         DOM_SID user_sid;
1464         DOM_SID group_sid;
1465
1466         uid_t uid;
1467         gid_t gid;
1468
1469         size_t i;
1470
1471         auth_serversupplied_info *result;
1472
1473         /* 
1474            Here is where we should check the list of
1475            trusted domains, and verify that the SID 
1476            matches.
1477         */
1478
1479         sid_copy(&user_sid, &info3->dom_sid.sid);
1480         if (!sid_append_rid(&user_sid, info3->user_rid)) {
1481                 return NT_STATUS_INVALID_PARAMETER;
1482         }
1483         
1484         sid_copy(&group_sid, &info3->dom_sid.sid);
1485         if (!sid_append_rid(&group_sid, info3->group_rid)) {
1486                 return NT_STATUS_INVALID_PARAMETER;
1487         }
1488
1489         if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1490                 /* If the server didn't give us one, just use the one we sent
1491                  * them */
1492                 nt_username = sent_nt_username;
1493         }
1494
1495         if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1496                 /* If the server didn't give us one, just use the one we sent
1497                  * them */
1498                 nt_domain = domain;
1499         }
1500         
1501         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1502            add user script (2.2.x behavior).
1503
1504            We use the _unmapped_ username here in an attempt to provide
1505            consistent username mapping behavior between kerberos and NTLM[SSP]
1506            authentication in domain mode security.  I.E. Username mapping
1507            should be applied to the fully qualified username
1508            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1509            called map_username() unnecessarily in make_user_info_map() but
1510            that is how the current code is designed.  Making the change here
1511            is the least disruptive place.  -- jerry */
1512            
1513         if ( !(sam_account = samu_new( NULL )) ) {
1514                 return NT_STATUS_NO_MEMORY;
1515         }
1516
1517         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1518                                      &found_username, &uid, &gid, sam_account);
1519
1520         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
1521                 DEBUG(3,("User %s does not exist, trying to add it\n",
1522                          internal_username));
1523                 smb_create_user( nt_domain, sent_nt_username, NULL);
1524                 nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username, 
1525                                               &found_username, &uid, &gid, sam_account );
1526         }
1527         
1528         /* if we still don't have a valid unix account check for 
1529           'map to guest = bad uid' */
1530           
1531         if (!NT_STATUS_IS_OK(nt_status)) {
1532                 TALLOC_FREE( sam_account );
1533                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1534                         make_server_info_guest(server_info); 
1535                         return NT_STATUS_OK;
1536                 }
1537                 return nt_status;
1538         }
1539                 
1540         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1541                 TALLOC_FREE(sam_account);
1542                 return NT_STATUS_NO_MEMORY;
1543         }
1544
1545         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1546                 TALLOC_FREE(sam_account);
1547                 return NT_STATUS_NO_MEMORY;
1548         }
1549
1550         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1551                 TALLOC_FREE(sam_account);
1552                 return NT_STATUS_NO_MEMORY;
1553         }
1554
1555         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1556                 TALLOC_FREE(sam_account);
1557                 return NT_STATUS_UNSUCCESSFUL;
1558         }
1559
1560         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1561                 TALLOC_FREE(sam_account);
1562                 return NT_STATUS_UNSUCCESSFUL;
1563         }
1564                 
1565         if (!pdb_set_fullname(sam_account,
1566                               unistr2_static(&(info3->uni_full_name)), 
1567                               PDB_CHANGED)) {
1568                 TALLOC_FREE(sam_account);
1569                 return NT_STATUS_NO_MEMORY;
1570         }
1571
1572         if (!pdb_set_logon_script(sam_account,
1573                                   unistr2_static(&(info3->uni_logon_script)),
1574                                   PDB_CHANGED)) {
1575                 TALLOC_FREE(sam_account);
1576                 return NT_STATUS_NO_MEMORY;
1577         }
1578
1579         if (!pdb_set_profile_path(sam_account,
1580                                   unistr2_static(&(info3->uni_profile_path)),
1581                                   PDB_CHANGED)) {
1582                 TALLOC_FREE(sam_account);
1583                 return NT_STATUS_NO_MEMORY;
1584         }
1585
1586         if (!pdb_set_homedir(sam_account,
1587                              unistr2_static(&(info3->uni_home_dir)),
1588                              PDB_CHANGED)) {
1589                 TALLOC_FREE(sam_account);
1590                 return NT_STATUS_NO_MEMORY;
1591         }
1592
1593         if (!pdb_set_dir_drive(sam_account,
1594                                unistr2_static(&(info3->uni_dir_drive)),
1595                                PDB_CHANGED)) {
1596                 TALLOC_FREE(sam_account);
1597                 return NT_STATUS_NO_MEMORY;
1598         }
1599
1600         if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
1601                 TALLOC_FREE(sam_account);
1602                 return NT_STATUS_NO_MEMORY;
1603         }
1604
1605         result = make_server_info(NULL);
1606         if (result == NULL) {
1607                 DEBUG(4, ("make_server_info failed!\n"));
1608                 TALLOC_FREE(sam_account);
1609                 return NT_STATUS_NO_MEMORY;
1610         }
1611
1612         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1613            valid struct samu) */
1614                    
1615         result->sam_account = sam_account;
1616         result->unix_name = talloc_strdup(result, found_username);
1617
1618         /* Fill in the unix info we found on the way */
1619
1620         result->uid = uid;
1621         result->gid = gid;
1622
1623         /* Create a 'combined' list of all SIDs we might want in the SD */
1624
1625         result->num_sids = 0;
1626         result->sids = NULL;
1627
1628         /* and create (by appending rids) the 'domain' sids */
1629         
1630         for (i = 0; i < info3->num_groups2; i++) {
1631                 DOM_SID sid;
1632                 if (!sid_compose(&sid, &info3->dom_sid.sid,
1633                                  info3->gids[i].g_rid)) {
1634                         DEBUG(3,("could not append additional group rid "
1635                                  "0x%x\n", info3->gids[i].g_rid));
1636                         TALLOC_FREE(result);
1637                         return NT_STATUS_INVALID_PARAMETER;
1638                 }
1639                 add_sid_to_array(result, &sid, &result->sids,
1640                                  &result->num_sids);
1641         }
1642
1643         /* Copy 'other' sids.  We need to do sid filtering here to
1644            prevent possible elevation of privileges.  See:
1645
1646            http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1647          */
1648
1649         for (i = 0; i < info3->num_other_sids; i++) {
1650                 add_sid_to_array(result, &info3->other_sids[i].sid,
1651                                  &result->sids,
1652                                  &result->num_sids);
1653         }
1654
1655         result->login_server = unistr2_tdup(result, 
1656                                             &(info3->uni_logon_srv));
1657
1658         /* ensure we are never given NULL session keys */
1659         
1660         if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1661                 result->user_session_key = data_blob(NULL, 0);
1662         } else {
1663                 result->user_session_key = data_blob_talloc(
1664                         result, info3->user_sess_key,
1665                         sizeof(info3->user_sess_key));
1666         }
1667
1668         if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1669                 result->lm_session_key = data_blob(NULL, 0);
1670         } else {
1671                 result->lm_session_key = data_blob_talloc(
1672                         result, info3->lm_sess_key,
1673                         sizeof(info3->lm_sess_key));
1674         }
1675
1676         *server_info = result;
1677
1678         return NT_STATUS_OK;
1679 }
1680
1681 /***************************************************************************
1682  Free a user_info struct
1683 ***************************************************************************/
1684
1685 void free_user_info(auth_usersupplied_info **user_info)
1686 {
1687         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1688         if (*user_info != NULL) {
1689                 if ((*user_info)->smb_name) {
1690                         DEBUG(10,("structure was created for %s\n",
1691                                   (*user_info)->smb_name));
1692                 }
1693                 SAFE_FREE((*user_info)->smb_name);
1694                 SAFE_FREE((*user_info)->internal_username);
1695                 SAFE_FREE((*user_info)->client_domain);
1696                 SAFE_FREE((*user_info)->domain);
1697                 SAFE_FREE((*user_info)->wksta_name);
1698                 data_blob_free(&(*user_info)->lm_resp);
1699                 data_blob_free(&(*user_info)->nt_resp);
1700                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1701                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1702                 data_blob_clear_free(&(*user_info)->plaintext_password);
1703                 ZERO_STRUCT(**user_info);
1704         }
1705         SAFE_FREE(*user_info);
1706 }
1707
1708 /***************************************************************************
1709  Make an auth_methods struct
1710 ***************************************************************************/
1711
1712 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1713 {
1714         if (!auth_context) {
1715                 smb_panic("no auth_context supplied to "
1716                           "make_auth_methods()!\n");
1717         }
1718
1719         if (!auth_method) {
1720                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1721                           "is NULL!\n");
1722         }
1723
1724         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1725         if (!*auth_method) {
1726                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1727                 return False;
1728         }
1729         ZERO_STRUCTP(*auth_method);
1730         
1731         return True;
1732 }
1733
1734 /****************************************************************************
1735  Duplicate a SID token.
1736 ****************************************************************************/
1737
1738 NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken)
1739 {
1740         NT_USER_TOKEN *token;
1741
1742         if (!ptoken)
1743                 return NULL;
1744
1745         token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
1746         if (token == NULL) {
1747                 DEBUG(0, ("talloc failed\n"));
1748                 return NULL;
1749         }
1750
1751         token->user_sids = talloc_memdup(token, ptoken->user_sids,
1752                                          sizeof(DOM_SID) * ptoken->num_sids );
1753
1754         if ((ptoken->user_sids != NULL) && (token->user_sids == NULL)) {
1755                 DEBUG(0, ("talloc_memdup failed\n"));
1756                 TALLOC_FREE(token);
1757                 return NULL;
1758         }
1759
1760         token->num_sids = ptoken->num_sids;
1761         
1762         /* copy the privileges; don't consider failure to be critical here */
1763         
1764         if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1765                 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!.  "
1766                          "Continuing with 0 privileges assigned.\n"));
1767         }
1768
1769         return token;
1770 }
1771
1772 /****************************************************************************
1773  Check for a SID in an NT_USER_TOKEN
1774 ****************************************************************************/
1775
1776 BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
1777 {
1778         int i;
1779         
1780         if ( !sid || !token )
1781                 return False;
1782         
1783         for ( i=0; i<token->num_sids; i++ ) {
1784                 if ( sid_equal( sid, &token->user_sids[i] ) )
1785                         return True;
1786         }
1787
1788         return False;
1789 }
1790
1791 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 
1792 {
1793         DOM_SID domain_sid;
1794
1795         /* if we are a domain member, the get the domain SID, else for 
1796            a DC or standalone server, use our own SID */
1797
1798         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1799                 if ( !secrets_fetch_domain_sid( lp_workgroup(),
1800                                                 &domain_sid ) ) {
1801                         DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
1802                                  "SID for domain [%s]\n", lp_workgroup()));
1803                         return False;
1804                 }
1805         } 
1806         else
1807                 sid_copy( &domain_sid, get_global_sam_sid() );
1808
1809         sid_append_rid( &domain_sid, rid );
1810         
1811         return nt_token_check_sid( &domain_sid, token );\
1812 }
1813
1814 /**
1815  * Verify whether or not given domain is trusted.
1816  *
1817  * @param domain_name name of the domain to be verified
1818  * @return true if domain is one of the trusted once or
1819  *         false if otherwise
1820  **/
1821
1822 BOOL is_trusted_domain(const char* dom_name)
1823 {
1824         DOM_SID trustdom_sid;
1825         BOOL ret;
1826
1827         /* no trusted domains for a standalone server */
1828
1829         if ( lp_server_role() == ROLE_STANDALONE )
1830                 return False;
1831
1832         /* if we are a DC, then check for a direct trust relationships */
1833
1834         if ( IS_DC ) {
1835                 become_root();
1836                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1837                           "[%s]\n", dom_name ));
1838                 ret = secrets_fetch_trusted_domain_password(dom_name, NULL,
1839                                                             NULL, NULL);
1840                 unbecome_root();
1841                 if (ret)
1842                         return True;
1843         }
1844         else {
1845                 NSS_STATUS result;
1846
1847                 /* If winbind is around, ask it */
1848
1849                 result = wb_is_trusted_domain(dom_name);
1850
1851                 if (result == NSS_STATUS_SUCCESS) {
1852                         return True;
1853                 }
1854
1855                 if (result == NSS_STATUS_NOTFOUND) {
1856                         /* winbind could not find the domain */
1857                         return False;
1858                 }
1859
1860                 /* The only other possible result is that winbind is not up
1861                    and running. We need to update the trustdom_cache
1862                    ourselves */
1863                 
1864                 update_trustdom_cache();
1865         }
1866
1867         /* now the trustdom cache should be available a DC could still
1868          * have a transitive trust so fall back to the cache of trusted
1869          * domains (like a domain member would use  */
1870
1871         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1872                 return True;
1873         }
1874
1875         return False;
1876 }
1877