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