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