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