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