r20090: Fix a class of bugs found by James Peach. Ensure
[tprouty/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_administrators: 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         if (!(result = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) {
845                 DEBUG(0, ("talloc failed\n"));
846                 return NULL;
847         }
848
849         /* Add the user and primary group sid */
850
851         if (!add_sid_to_array(result, user_sid,
852                          &result->user_sids, &result->num_sids)) {
853                 return NULL;
854         }
855
856         /* For guest, num_groupsids may be zero. */
857         if (num_groupsids) {
858                 if (!add_sid_to_array(result, &groupsids[0],
859                                  &result->user_sids, &result->num_sids)) {
860                         return NULL;
861                 }
862         }
863                          
864         /* Add in BUILTIN sids */
865         
866         if (!add_sid_to_array(result, &global_sid_World,
867                          &result->user_sids, &result->num_sids)) {
868                 return NULL;
869         }
870         if (!add_sid_to_array(result, &global_sid_Network,
871                          &result->user_sids, &result->num_sids)) {
872                 return NULL;
873         }
874
875         if (is_guest) {
876                 if (!add_sid_to_array(result, &global_sid_Builtin_Guests,
877                                  &result->user_sids, &result->num_sids)) {
878                         return NULL;
879                 }
880         } else {
881                 if (!add_sid_to_array(result, &global_sid_Authenticated_Users,
882                                  &result->user_sids, &result->num_sids)) {
883                         return NULL;
884                 }
885         }
886         
887         /* Now the SIDs we got from authentication. These are the ones from
888          * the info3 struct or from the pdb_enum_group_memberships, depending
889          * on who authenticated the user.
890          * Note that we start the for loop at "1" here, we already added the
891          * first group sid as primary above. */
892
893         for (i=1; i<num_groupsids; i++) {
894                 if (!add_sid_to_array_unique(result, &groupsids[i],
895                                         &result->user_sids, &result->num_sids)) {
896                         return NULL;
897                 }
898         }
899         
900         /* Deal with the BUILTIN\Administrators group.  If the SID can
901            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
902            handled it. */
903
904         if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
905                 /* We can only create a mapping if winbind is running 
906                    and the nested group functionality has been enabled */
907                    
908                 if ( lp_winbind_nested_groups() && winbind_ping() ) {
909                         become_root();
910                         status = create_builtin_administrators( );
911                         if ( !NT_STATUS_IS_OK(status) ) {
912                                 DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
913                                 /* don't fail, just log the message */
914                         }
915                         unbecome_root();
916                 }
917                 else {
918                         status = add_builtin_administrators( result );
919                         if ( !NT_STATUS_IS_OK(status) ) {
920                                 /* just log a complaint but do not fail */
921                                 DEBUG(3,("create_local_nt_token: failed to check for local Administrators"
922                                         " membership (%s)\n", nt_errstr(status)));
923                         }                       
924                 }               
925         }
926
927         /* Deal with the BUILTIN\Users group.  If the SID can
928            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
929            handled it. */
930
931         if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
932                 /* We can only create a mapping if winbind is running 
933                    and the nested group functionality has been enabled */
934                    
935                 if ( lp_winbind_nested_groups() && winbind_ping() ) {
936                         become_root();
937                         status = create_builtin_users( );
938                         if ( !NT_STATUS_IS_OK(status) ) {
939                                 DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Users group!\n"));
940                                 /* don't fail, just log the message */
941                         }
942                         unbecome_root();
943                 }
944         }
945
946         /* Deal with local groups */
947         
948         if (lp_winbind_nested_groups()) {
949
950                 /* Now add the aliases. First the one from our local SAM */
951
952                 status = add_aliases(get_global_sam_sid(), result);
953
954                 if (!NT_STATUS_IS_OK(status)) {
955                         TALLOC_FREE(result);
956                         return NULL;
957                 }
958
959                 /* Finally the builtin ones */
960
961                 status = add_aliases(&global_sid_Builtin, result);
962
963                 if (!NT_STATUS_IS_OK(status)) {
964                         TALLOC_FREE(result);
965                         return NULL;
966                 }
967         } 
968
969
970         get_privileges_for_sids(&result->privileges, result->user_sids,
971                                 result->num_sids);
972         return result;
973 }
974
975 /*
976  * Create the token to use from server_info->sam_account and
977  * server_info->sids (the info3/sam groups). Find the unix gids.
978  */
979
980 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
981 {
982         TALLOC_CTX *mem_ctx;
983         NTSTATUS status;
984         size_t i;
985         
986
987         mem_ctx = talloc_new(NULL);
988         if (mem_ctx == NULL) {
989                 DEBUG(0, ("talloc_new failed\n"));
990                 return NT_STATUS_NO_MEMORY;
991         }
992
993         /*
994          * If winbind is not around, we can not make much use of the SIDs the
995          * domain controller provided us with. Likewise if the user name was
996          * mapped to some local unix user.
997          */
998
999         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
1000             (server_info->was_mapped)) {
1001                 status = create_token_from_username(server_info,
1002                                                     server_info->unix_name,
1003                                                     server_info->guest,
1004                                                     &server_info->uid,
1005                                                     &server_info->gid,
1006                                                     &server_info->unix_name,
1007                                                     &server_info->ptok);
1008                 
1009         } else {
1010                 server_info->ptok = create_local_nt_token(
1011                         server_info,
1012                         pdb_get_user_sid(server_info->sam_account),
1013                         server_info->guest,
1014                         server_info->num_sids, server_info->sids);
1015                 status = server_info->ptok ?
1016                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
1017         }
1018
1019         if (!NT_STATUS_IS_OK(status)) {
1020                 TALLOC_FREE(mem_ctx);
1021                 return status;
1022         }
1023         
1024         /* Convert the SIDs to gids. */
1025
1026         server_info->n_groups = 0;
1027         server_info->groups = NULL;
1028
1029         /* Start at index 1, where the groups start. */
1030
1031         for (i=1; i<server_info->ptok->num_sids; i++) {
1032                 gid_t gid;
1033                 DOM_SID *sid = &server_info->ptok->user_sids[i];
1034
1035                 if (!sid_to_gid(sid, &gid)) {
1036                         DEBUG(10, ("Could not convert SID %s to gid, "
1037                                    "ignoring it\n", sid_string_static(sid)));
1038                         continue;
1039                 }
1040                 if (!add_gid_to_array_unique(server_info, gid, &server_info->groups,
1041                                         &server_info->n_groups)) {
1042                         TALLOC_FREE(mem_ctx);
1043                         return NT_STATUS_NO_MEMORY;
1044                 }
1045         }
1046         
1047         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
1048
1049         status = log_nt_token(mem_ctx, server_info->ptok);
1050
1051         TALLOC_FREE(mem_ctx);
1052         return status;
1053 }
1054
1055 /*
1056  * Create an artificial NT token given just a username. (Initially indended
1057  * for force user)
1058  *
1059  * We go through lookup_name() to avoid problems we had with 'winbind use
1060  * default domain'.
1061  *
1062  * We have 3 cases:
1063  *
1064  * unmapped unix users: Go directly to nss to find the user's group.
1065  *
1066  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
1067  *
1068  * If the user is provided by winbind, the primary gid is set to "domain
1069  * users" of the user's domain. For an explanation why this is necessary, see
1070  * the thread starting at
1071  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
1072  */
1073
1074 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
1075                                     BOOL is_guest,
1076                                     uid_t *uid, gid_t *gid,
1077                                     char **found_username,
1078                                     struct nt_user_token **token)
1079 {
1080         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
1081         TALLOC_CTX *tmp_ctx;
1082         DOM_SID user_sid;
1083         enum lsa_SidType type;
1084         gid_t *gids;
1085         DOM_SID *group_sids;
1086         DOM_SID unix_group_sid;
1087         size_t num_group_sids;
1088         size_t num_gids;
1089         size_t i;
1090
1091         tmp_ctx = talloc_new(NULL);
1092         if (tmp_ctx == NULL) {
1093                 DEBUG(0, ("talloc_new failed\n"));
1094                 return NT_STATUS_NO_MEMORY;
1095         }
1096
1097         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
1098                          NULL, NULL, &user_sid, &type)) {
1099                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
1100                 goto done;
1101         }
1102
1103         if (type != SID_NAME_USER) {
1104                 DEBUG(1, ("%s is a %s, not a user\n", username,
1105                           sid_type_lookup(type)));
1106                 goto done;
1107         }
1108
1109         if (!sid_to_uid(&user_sid, uid)) {
1110                 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
1111                           username, sid_string_static(&user_sid)));
1112                 goto done;
1113         }
1114
1115         if (sid_check_is_in_our_domain(&user_sid)) {
1116
1117                 /* This is a passdb user, so ask passdb */
1118
1119                 struct samu *sam_acct = NULL;
1120
1121                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
1122                         result = NT_STATUS_NO_MEMORY;
1123                         goto done;
1124                 }
1125
1126                 if (!pdb_getsampwsid(sam_acct, &user_sid)) {
1127                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
1128                                   sid_string_static(&user_sid), username));
1129                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
1130                         goto unix_user;
1131                 }
1132
1133                 result = pdb_enum_group_memberships(mem_ctx, sam_acct,
1134                                                     &group_sids, &gids,
1135                                                     &num_group_sids);
1136                 if (!NT_STATUS_IS_OK(result)) {
1137                         DEBUG(10, ("enum_group_memberships failed for %s\n",
1138                                    username));
1139                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
1140                         goto unix_user;
1141                 }
1142
1143                 /* see the smb_panic() in pdb_default_enum_group_memberships */
1144                 SMB_ASSERT(num_group_sids > 0); 
1145
1146                 *gid = gids[0];
1147                 *found_username = talloc_strdup(mem_ctx,
1148                                                 pdb_get_username(sam_acct));
1149
1150         } else  if (sid_check_is_in_unix_users(&user_sid)) {
1151
1152                 /* This is a unix user not in passdb. We need to ask nss
1153                  * directly, without consulting passdb */
1154
1155                 struct passwd *pass;
1156
1157                 /*
1158                  * This goto target is used as a fallback for the passdb
1159                  * case. The concrete bug report is when passdb gave us an
1160                  * unmapped gid.
1161                  */
1162
1163         unix_user:
1164
1165                 uid_to_unix_users_sid(*uid, &user_sid);
1166
1167                 pass = getpwuid_alloc(tmp_ctx, *uid);
1168                 if (pass == NULL) {
1169                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
1170                                   *uid, username));
1171                         goto done;
1172                 }
1173
1174                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
1175                                          &gids, &num_group_sids)) {
1176                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
1177                                   username));
1178                         goto done;
1179                 }
1180
1181                 /* group_sids can be realloced - must be done on mem_ctx not tmp_ctx. */
1182                 group_sids = talloc_array(mem_ctx, DOM_SID, num_group_sids);
1183                 if (group_sids == NULL) {
1184                         DEBUG(1, ("talloc_array failed\n"));
1185                         result = NT_STATUS_NO_MEMORY;
1186                         goto done;
1187                 }
1188
1189                 for (i=0; i<num_group_sids; i++) {
1190                         gid_to_sid(&group_sids[i], gids[i]);
1191                 }
1192
1193                 /* In getgroups_unix_user we always set the primary gid */
1194                 SMB_ASSERT(num_group_sids > 0); 
1195
1196                 *gid = gids[0];
1197                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
1198
1199         } else {
1200
1201                 /* This user is from winbind, force the primary gid to the
1202                  * user's "domain users" group. Under certain circumstances
1203                  * (user comes from NT4), this might be a loss of
1204                  * information. But we can not rely on winbind getting the
1205                  * correct info. AD might prohibit winbind looking up that
1206                  * information. */
1207
1208                 uint32 dummy;
1209
1210                 num_group_sids = 1;
1211                 group_sids = talloc_array(mem_ctx, DOM_SID, num_group_sids);
1212                 if (group_sids == NULL) {
1213                         DEBUG(1, ("talloc_array failed\n"));
1214                         result = NT_STATUS_NO_MEMORY;
1215                         goto done;
1216                 }
1217
1218                 sid_copy(&group_sids[0], &user_sid);
1219                 sid_split_rid(&group_sids[0], &dummy);
1220                 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
1221
1222                 if (!sid_to_gid(&group_sids[0], gid)) {
1223                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1224                                   sid_string_static(&group_sids[0])));
1225                         goto done;
1226                 }
1227
1228                 gids = gid;
1229
1230                 *found_username = talloc_strdup(mem_ctx, username);
1231         }
1232
1233         /* Add the "Unix Group" SID for each gid to catch mapped groups
1234            and their Unix equivalent.  This is to solve the backwards
1235            compatibility problem of 'valid users = +ntadmin' where
1236            ntadmin has been paired with "Domain Admins" in the group
1237            mapping table.  Otherwise smb.conf would need to be changed
1238            to 'valid user = "Domain Admins"'.  --jerry */
1239
1240         num_gids = num_group_sids;
1241         for ( i=0; i<num_gids; i++ ) {
1242                 gid_t high, low;
1243
1244                 /* don't pickup anything managed by Winbind */
1245
1246                 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
1247                         continue;
1248
1249                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
1250                         DEBUG(1,("create_token_from_username: Failed to create SID "
1251                                 "for gid %d!\n", gids[i]));
1252                         continue;
1253                 }
1254                 if (!add_sid_to_array_unique( mem_ctx, &unix_group_sid,
1255                                 &group_sids, &num_group_sids )) {
1256                         result = NT_STATUS_NO_MEMORY;
1257                         goto done;
1258                 }
1259         }
1260
1261         *token = create_local_nt_token(mem_ctx, &user_sid,
1262                                        is_guest, num_group_sids, group_sids);
1263
1264         if ((*token == NULL) || (*found_username == NULL)) {
1265                 result = NT_STATUS_NO_MEMORY;
1266                 goto done;
1267         }
1268
1269         result = NT_STATUS_OK;
1270  done:
1271         TALLOC_FREE(tmp_ctx);
1272         return result;
1273 }
1274
1275 /***************************************************************************
1276  Build upon create_token_from_username:
1277
1278  Expensive helper function to figure out whether a user given its name is
1279  member of a particular group.
1280 ***************************************************************************/
1281 BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
1282 {
1283         NTSTATUS status;
1284         uid_t uid;
1285         gid_t gid;
1286         char *found_username;
1287         struct nt_user_token *token;
1288         BOOL result;
1289
1290         TALLOC_CTX *mem_ctx;
1291
1292         mem_ctx = talloc_new(NULL);
1293         if (mem_ctx == NULL) {
1294                 DEBUG(0, ("talloc_new failed\n"));
1295                 return False;
1296         }
1297
1298         status = create_token_from_username(mem_ctx, username, False,
1299                                             &uid, &gid, &found_username,
1300                                             &token);
1301
1302         if (!NT_STATUS_IS_OK(status)) {
1303                 DEBUG(10, ("could not create token for %s\n", username));
1304                 return False;
1305         }
1306
1307         result = nt_token_check_sid(group_sid, token);
1308
1309         TALLOC_FREE(mem_ctx);
1310         return result;
1311         
1312 }
1313
1314 BOOL user_in_group(const char *username, const char *groupname)
1315 {
1316         TALLOC_CTX *mem_ctx;
1317         DOM_SID group_sid;
1318         BOOL ret;
1319
1320         mem_ctx = talloc_new(NULL);
1321         if (mem_ctx == NULL) {
1322                 DEBUG(0, ("talloc_new failed\n"));
1323                 return False;
1324         }
1325
1326         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1327                           NULL, NULL, &group_sid, NULL);
1328         TALLOC_FREE(mem_ctx);
1329
1330         if (!ret) {
1331                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1332                 return False;
1333         }
1334
1335         return user_in_group_sid(username, &group_sid);
1336 }
1337
1338
1339 /***************************************************************************
1340  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
1341  to a struct samu
1342 ***************************************************************************/
1343
1344 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1345                              char *unix_username,
1346                              struct passwd *pwd)
1347 {
1348         NTSTATUS status;
1349         struct samu *sampass = NULL;
1350         gid_t *gids;
1351         auth_serversupplied_info *result;
1352         
1353         if ( !(sampass = samu_new( NULL )) ) {
1354                 return NT_STATUS_NO_MEMORY;
1355         }
1356         
1357         status = samu_set_unix( sampass, pwd );
1358         if (!NT_STATUS_IS_OK(status)) {
1359                 return status;
1360         }
1361
1362         result = make_server_info(NULL);
1363         if (result == NULL) {
1364                 TALLOC_FREE(sampass);
1365                 return NT_STATUS_NO_MEMORY;
1366         }
1367
1368         result->sam_account = sampass;
1369         result->unix_name = talloc_strdup(result, unix_username);
1370         result->uid = pwd->pw_uid;
1371         result->gid = pwd->pw_gid;
1372
1373         status = pdb_enum_group_memberships(result, sampass,
1374                                             &result->sids, &gids,
1375                                             &result->num_sids);
1376
1377         if (!NT_STATUS_IS_OK(status)) {
1378                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1379                            nt_errstr(status)));
1380                 TALLOC_FREE(result);
1381                 return status;
1382         }
1383
1384         /* For now we throw away the gids and convert via sid_to_gid
1385          * later. This needs fixing, but I'd like to get the code straight and
1386          * simple first. */
1387         TALLOC_FREE(gids);
1388
1389         *server_info = result;
1390
1391         return NT_STATUS_OK;
1392 }
1393
1394 /***************************************************************************
1395  Make (and fill) a user_info struct for a guest login.
1396  This *must* succeed for smbd to start. If there is no mapping entry for
1397  the guest gid, then create one.
1398 ***************************************************************************/
1399
1400 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1401 {
1402         NTSTATUS status;
1403         struct samu *sampass = NULL;
1404         DOM_SID guest_sid;
1405         BOOL ret;
1406         static const char zeros[16] = { 0, };
1407
1408         if ( !(sampass = samu_new( NULL )) ) {
1409                 return NT_STATUS_NO_MEMORY;
1410         }
1411
1412         sid_copy(&guest_sid, get_global_sam_sid());
1413         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1414
1415         become_root();
1416         ret = pdb_getsampwsid(sampass, &guest_sid);
1417         unbecome_root();
1418
1419         if (!ret) {
1420                 TALLOC_FREE(sampass);
1421                 return NT_STATUS_NO_SUCH_USER;
1422         }
1423
1424         status = make_server_info_sam(server_info, sampass);
1425         if (!NT_STATUS_IS_OK(status)) {
1426                 TALLOC_FREE(sampass);
1427                 return status;
1428         }
1429         
1430         (*server_info)->guest = True;
1431
1432         status = create_local_token(*server_info);
1433         if (!NT_STATUS_IS_OK(status)) {
1434                 DEBUG(10, ("create_local_token failed: %s\n",
1435                            nt_errstr(status)));
1436                 return status;
1437         }
1438
1439         /* annoying, but the Guest really does have a session key, and it is
1440            all zeros! */
1441         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1442         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1443
1444         return NT_STATUS_OK;
1445 }
1446
1447 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1448 {
1449         auth_serversupplied_info *dst;
1450
1451         dst = make_server_info(NULL);
1452         if (dst == NULL) {
1453                 return NULL;
1454         }
1455
1456         dst->guest = src->guest;
1457         dst->uid = src->uid;
1458         dst->gid = src->gid;
1459         dst->n_groups = src->n_groups;
1460         if (src->n_groups != 0) {
1461                 dst->groups = (gid_t *)talloc_memdup(
1462                         dst, src->groups, sizeof(gid_t)*dst->n_groups);
1463         } else {
1464                 dst->groups = NULL;
1465         }
1466
1467         if (src->ptok) {
1468                 dst->ptok = dup_nt_token(dst, src->ptok);
1469                 if (!dst->ptok) {
1470                         TALLOC_FREE(dst);
1471                         return NULL;
1472                 }
1473         }
1474         
1475         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1476                                                 src->user_session_key.length);
1477
1478         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1479                                                 src->lm_session_key.length);
1480
1481         dst->sam_account = samu_new(NULL);
1482         if (!dst->sam_account) {
1483                 TALLOC_FREE(dst);
1484                 return NULL;
1485         }
1486
1487         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1488                 TALLOC_FREE(dst);
1489                 return NULL;
1490         }
1491         
1492         dst->pam_handle = NULL;
1493         dst->unix_name = talloc_strdup(dst, src->unix_name);
1494         if (!dst->unix_name) {
1495                 TALLOC_FREE(dst);
1496                 return NULL;
1497         }
1498
1499         return dst;
1500 }
1501
1502 static auth_serversupplied_info *guest_info = NULL;
1503
1504 BOOL init_guest_info(void)
1505 {
1506         if (guest_info != NULL)
1507                 return True;
1508
1509         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1510 }
1511
1512 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1513 {
1514         *server_info = copy_serverinfo(guest_info);
1515         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1516 }
1517
1518 BOOL copy_current_user(struct current_user *dst, struct current_user *src)
1519 {
1520         gid_t *groups;
1521         NT_USER_TOKEN *nt_token;
1522
1523         groups = (gid_t *)memdup(src->ut.groups,
1524                                  sizeof(gid_t) * src->ut.ngroups);
1525         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1526                 return False;
1527         }
1528
1529         nt_token = dup_nt_token(NULL, src->nt_user_token);
1530         if (nt_token == NULL) {
1531                 SAFE_FREE(groups);
1532                 return False;
1533         }
1534
1535         dst->conn = src->conn;
1536         dst->vuid = src->vuid;
1537         dst->ut.uid = src->ut.uid;
1538         dst->ut.gid = src->ut.gid;
1539         dst->ut.ngroups = src->ut.ngroups;
1540         dst->ut.groups = groups;
1541         dst->nt_user_token = nt_token;
1542         return True;
1543 }
1544
1545 BOOL set_current_user_guest(struct current_user *dst)
1546 {
1547         gid_t *groups;
1548         NT_USER_TOKEN *nt_token;
1549
1550         groups = (gid_t *)memdup(guest_info->groups,
1551                                  sizeof(gid_t) * guest_info->n_groups);
1552         if (groups == NULL) {
1553                 return False;
1554         }
1555
1556         nt_token = dup_nt_token(NULL, guest_info->ptok);
1557         if (nt_token == NULL) {
1558                 SAFE_FREE(groups);
1559                 return False;
1560         }
1561
1562         TALLOC_FREE(dst->nt_user_token);
1563         SAFE_FREE(dst->ut.groups);
1564
1565         /* dst->conn is never really dereferenced, it's only tested for
1566          * equality in uid.c */
1567         dst->conn = NULL;
1568
1569         dst->vuid = UID_FIELD_INVALID;
1570         dst->ut.uid = guest_info->uid;
1571         dst->ut.gid = guest_info->gid;
1572         dst->ut.ngroups = guest_info->n_groups;
1573         dst->ut.groups = groups;
1574         dst->nt_user_token = nt_token;
1575         return True;
1576 }
1577
1578 /***************************************************************************
1579  Purely internal function for make_server_info_info3
1580  Fill the sam account from getpwnam
1581 ***************************************************************************/
1582 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1583                                  const char *domain,
1584                                  const char *username,
1585                                  char **found_username,
1586                                  uid_t *uid, gid_t *gid,
1587                                  struct samu *account,
1588                                  BOOL *username_was_mapped)
1589 {
1590         NTSTATUS nt_status;
1591         fstring dom_user, lower_username;
1592         fstring real_username;
1593         struct passwd *passwd;
1594
1595         fstrcpy( lower_username, username );
1596         strlower_m( lower_username );
1597
1598         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1599                 lower_username);
1600
1601         /* Get the passwd struct.  Try to create the account is necessary. */
1602
1603         *username_was_mapped = map_username( dom_user );
1604
1605         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1606                 return NT_STATUS_NO_SUCH_USER;
1607
1608         *uid = passwd->pw_uid;
1609         *gid = passwd->pw_gid;
1610
1611         /* This is pointless -- there is no suport for differing 
1612            unix and windows names.  Make sure to always store the 
1613            one we actually looked up and succeeded. Have I mentioned
1614            why I hate the 'winbind use default domain' parameter?   
1615                                          --jerry              */
1616            
1617         *found_username = talloc_strdup( mem_ctx, real_username );
1618         
1619         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1620
1621         nt_status = samu_set_unix( account, passwd );
1622         
1623         TALLOC_FREE(passwd);
1624         
1625         return nt_status;
1626 }
1627
1628 /****************************************************************************
1629  Wrapper to allow the getpwnam() call to strip the domain name and 
1630  try again in case a local UNIX user is already there.  Also run through 
1631  the username if we fallback to the username only.
1632  ****************************************************************************/
1633  
1634 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1635                              fstring save_username, BOOL create )
1636 {
1637         struct passwd *pw = NULL;
1638         char *p;
1639         fstring username;
1640         
1641         /* we only save a copy of the username it has been mangled 
1642            by winbindd use default domain */
1643            
1644         save_username[0] = '\0';
1645            
1646         /* don't call map_username() here since it has to be done higher 
1647            up the stack so we don't call it mutliple times */
1648
1649         fstrcpy( username, domuser );
1650         
1651         p = strchr_m( username, *lp_winbind_separator() );
1652         
1653         /* code for a DOMAIN\user string */
1654         
1655         if ( p ) {
1656                 fstring strip_username;
1657
1658                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1659                 if ( pw ) {     
1660                         /* make sure we get the case of the username correct */
1661                         /* work around 'winbind use default domain = yes' */
1662
1663                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1664                                 char *domain;
1665                                 
1666                                 /* split the domain and username into 2 strings */
1667                                 *p = '\0';
1668                                 domain = username;
1669
1670                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1671                         }
1672                         else
1673                                 fstrcpy( save_username, pw->pw_name );
1674
1675                         /* whew -- done! */             
1676                         return pw;
1677                 }
1678
1679                 /* setup for lookup of just the username */
1680                 /* remember that p and username are overlapping memory */
1681
1682                 p++;
1683                 fstrcpy( strip_username, p );
1684                 fstrcpy( username, strip_username );
1685         }
1686         
1687         /* just lookup a plain username */
1688         
1689         pw = Get_Pwnam_alloc(mem_ctx, username);
1690                 
1691         /* Create local user if requested but only if winbindd
1692            is not running.  We need to protect against cases
1693            where winbindd is failing and then prematurely
1694            creating users in /etc/passwd */
1695         
1696         if ( !pw && create && !winbind_ping() ) {
1697                 /* Don't add a machine account. */
1698                 if (username[strlen(username)-1] == '$')
1699                         return NULL;
1700
1701                 smb_create_user(NULL, username, NULL);
1702                 pw = Get_Pwnam_alloc(mem_ctx, username);
1703         }
1704         
1705         /* one last check for a valid passwd struct */
1706         
1707         if ( pw )
1708                 fstrcpy( save_username, pw->pw_name );
1709
1710         return pw;
1711 }
1712
1713 /***************************************************************************
1714  Make a server_info struct from the info3 returned by a domain logon 
1715 ***************************************************************************/
1716
1717 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1718                                 const char *sent_nt_username,
1719                                 const char *domain,
1720                                 auth_serversupplied_info **server_info, 
1721                                 NET_USER_INFO_3 *info3) 
1722 {
1723         static const char zeros[16] = { 0, };
1724
1725         NTSTATUS nt_status = NT_STATUS_OK;
1726         char *found_username;
1727         const char *nt_domain;
1728         const char *nt_username;
1729         struct samu *sam_account = NULL;
1730         DOM_SID user_sid;
1731         DOM_SID group_sid;
1732         BOOL username_was_mapped;
1733
1734         uid_t uid;
1735         gid_t gid;
1736
1737         size_t i;
1738
1739         auth_serversupplied_info *result;
1740
1741         /* 
1742            Here is where we should check the list of
1743            trusted domains, and verify that the SID 
1744            matches.
1745         */
1746
1747         sid_copy(&user_sid, &info3->dom_sid.sid);
1748         if (!sid_append_rid(&user_sid, info3->user_rid)) {
1749                 return NT_STATUS_INVALID_PARAMETER;
1750         }
1751         
1752         sid_copy(&group_sid, &info3->dom_sid.sid);
1753         if (!sid_append_rid(&group_sid, info3->group_rid)) {
1754                 return NT_STATUS_INVALID_PARAMETER;
1755         }
1756
1757         if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1758                 /* If the server didn't give us one, just use the one we sent
1759                  * them */
1760                 nt_username = sent_nt_username;
1761         }
1762
1763         if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1764                 /* If the server didn't give us one, just use the one we sent
1765                  * them */
1766                 nt_domain = domain;
1767         }
1768         
1769         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1770            add user script (2.2.x behavior).
1771
1772            We use the _unmapped_ username here in an attempt to provide
1773            consistent username mapping behavior between kerberos and NTLM[SSP]
1774            authentication in domain mode security.  I.E. Username mapping
1775            should be applied to the fully qualified username
1776            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1777            called map_username() unnecessarily in make_user_info_map() but
1778            that is how the current code is designed.  Making the change here
1779            is the least disruptive place.  -- jerry */
1780            
1781         if ( !(sam_account = samu_new( NULL )) ) {
1782                 return NT_STATUS_NO_MEMORY;
1783         }
1784
1785         /* this call will try to create the user if necessary */
1786
1787         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1788                                      &found_username, &uid, &gid, sam_account,
1789                                      &username_was_mapped);
1790
1791         
1792         /* if we still don't have a valid unix account check for 
1793           'map to guest = bad uid' */
1794           
1795         if (!NT_STATUS_IS_OK(nt_status)) {
1796                 TALLOC_FREE( sam_account );
1797                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1798                         make_server_info_guest(server_info); 
1799                         return NT_STATUS_OK;
1800                 }
1801                 return nt_status;
1802         }
1803                 
1804         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1805                 TALLOC_FREE(sam_account);
1806                 return NT_STATUS_NO_MEMORY;
1807         }
1808
1809         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1810                 TALLOC_FREE(sam_account);
1811                 return NT_STATUS_NO_MEMORY;
1812         }
1813
1814         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1815                 TALLOC_FREE(sam_account);
1816                 return NT_STATUS_NO_MEMORY;
1817         }
1818
1819         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1820                 TALLOC_FREE(sam_account);
1821                 return NT_STATUS_UNSUCCESSFUL;
1822         }
1823
1824         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1825                 TALLOC_FREE(sam_account);
1826                 return NT_STATUS_UNSUCCESSFUL;
1827         }
1828                 
1829         if (!pdb_set_fullname(sam_account,
1830                               unistr2_static(&(info3->uni_full_name)), 
1831                               PDB_CHANGED)) {
1832                 TALLOC_FREE(sam_account);
1833                 return NT_STATUS_NO_MEMORY;
1834         }
1835
1836         if (!pdb_set_logon_script(sam_account,
1837                                   unistr2_static(&(info3->uni_logon_script)),
1838                                   PDB_CHANGED)) {
1839                 TALLOC_FREE(sam_account);
1840                 return NT_STATUS_NO_MEMORY;
1841         }
1842
1843         if (!pdb_set_profile_path(sam_account,
1844                                   unistr2_static(&(info3->uni_profile_path)),
1845                                   PDB_CHANGED)) {
1846                 TALLOC_FREE(sam_account);
1847                 return NT_STATUS_NO_MEMORY;
1848         }
1849
1850         if (!pdb_set_homedir(sam_account,
1851                              unistr2_static(&(info3->uni_home_dir)),
1852                              PDB_CHANGED)) {
1853                 TALLOC_FREE(sam_account);
1854                 return NT_STATUS_NO_MEMORY;
1855         }
1856
1857         if (!pdb_set_dir_drive(sam_account,
1858                                unistr2_static(&(info3->uni_dir_drive)),
1859                                PDB_CHANGED)) {
1860                 TALLOC_FREE(sam_account);
1861                 return NT_STATUS_NO_MEMORY;
1862         }
1863
1864         if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
1865                 TALLOC_FREE(sam_account);
1866                 return NT_STATUS_NO_MEMORY;
1867         }
1868
1869         result = make_server_info(NULL);
1870         if (result == NULL) {
1871                 DEBUG(4, ("make_server_info failed!\n"));
1872                 TALLOC_FREE(sam_account);
1873                 return NT_STATUS_NO_MEMORY;
1874         }
1875
1876         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1877            valid struct samu) */
1878                    
1879         result->sam_account = sam_account;
1880         result->unix_name = talloc_strdup(result, found_username);
1881
1882         /* Fill in the unix info we found on the way */
1883
1884         result->uid = uid;
1885         result->gid = gid;
1886
1887         /* Create a 'combined' list of all SIDs we might want in the SD */
1888
1889         result->num_sids = 0;
1890         result->sids = NULL;
1891
1892         /* and create (by appending rids) the 'domain' sids */
1893         
1894         for (i = 0; i < info3->num_groups2; i++) {
1895                 DOM_SID sid;
1896                 if (!sid_compose(&sid, &info3->dom_sid.sid,
1897                                  info3->gids[i].g_rid)) {
1898                         DEBUG(3,("could not append additional group rid "
1899                                  "0x%x\n", info3->gids[i].g_rid));
1900                         TALLOC_FREE(result);
1901                         return NT_STATUS_INVALID_PARAMETER;
1902                 }
1903                 if (!add_sid_to_array(result, &sid, &result->sids,
1904                                  &result->num_sids)) {
1905                         TALLOC_FREE(result);
1906                         return NT_STATUS_NO_MEMORY;
1907                 }
1908         }
1909
1910         /* Copy 'other' sids.  We need to do sid filtering here to
1911            prevent possible elevation of privileges.  See:
1912
1913            http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1914          */
1915
1916         for (i = 0; i < info3->num_other_sids; i++) {
1917                 if (!add_sid_to_array(result, &info3->other_sids[i].sid,
1918                                          &result->sids,
1919                                          &result->num_sids)) {
1920                         TALLOC_FREE(result);
1921                         return NT_STATUS_NO_MEMORY;
1922                 }
1923         }
1924
1925         result->login_server = unistr2_tdup(result, 
1926                                             &(info3->uni_logon_srv));
1927
1928         /* ensure we are never given NULL session keys */
1929         
1930         if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1931                 result->user_session_key = data_blob(NULL, 0);
1932         } else {
1933                 result->user_session_key = data_blob_talloc(
1934                         result, info3->user_sess_key,
1935                         sizeof(info3->user_sess_key));
1936         }
1937
1938         if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1939                 result->lm_session_key = data_blob(NULL, 0);
1940         } else {
1941                 result->lm_session_key = data_blob_talloc(
1942                         result, info3->lm_sess_key,
1943                         sizeof(info3->lm_sess_key));
1944         }
1945
1946         result->was_mapped = username_was_mapped;
1947
1948         *server_info = result;
1949
1950         return NT_STATUS_OK;
1951 }
1952
1953 /***************************************************************************
1954  Free a user_info struct
1955 ***************************************************************************/
1956
1957 void free_user_info(auth_usersupplied_info **user_info)
1958 {
1959         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1960         if (*user_info != NULL) {
1961                 if ((*user_info)->smb_name) {
1962                         DEBUG(10,("structure was created for %s\n",
1963                                   (*user_info)->smb_name));
1964                 }
1965                 SAFE_FREE((*user_info)->smb_name);
1966                 SAFE_FREE((*user_info)->internal_username);
1967                 SAFE_FREE((*user_info)->client_domain);
1968                 SAFE_FREE((*user_info)->domain);
1969                 SAFE_FREE((*user_info)->wksta_name);
1970                 data_blob_free(&(*user_info)->lm_resp);
1971                 data_blob_free(&(*user_info)->nt_resp);
1972                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1973                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1974                 data_blob_clear_free(&(*user_info)->plaintext_password);
1975                 ZERO_STRUCT(**user_info);
1976         }
1977         SAFE_FREE(*user_info);
1978 }
1979
1980 /***************************************************************************
1981  Make an auth_methods struct
1982 ***************************************************************************/
1983
1984 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1985 {
1986         if (!auth_context) {
1987                 smb_panic("no auth_context supplied to "
1988                           "make_auth_methods()!\n");
1989         }
1990
1991         if (!auth_method) {
1992                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1993                           "is NULL!\n");
1994         }
1995
1996         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1997         if (!*auth_method) {
1998                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1999                 return False;
2000         }
2001         ZERO_STRUCTP(*auth_method);
2002         
2003         return True;
2004 }
2005
2006 /****************************************************************************
2007  Duplicate a SID token.
2008 ****************************************************************************/
2009
2010 NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken)
2011 {
2012         NT_USER_TOKEN *token;
2013
2014         if (!ptoken)
2015                 return NULL;
2016
2017         token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
2018         if (token == NULL) {
2019                 DEBUG(0, ("talloc failed\n"));
2020                 return NULL;
2021         }
2022
2023         ZERO_STRUCTP(token);
2024
2025         if (ptoken->user_sids && ptoken->num_sids) {
2026                 token->user_sids = (DOM_SID *)talloc_memdup(
2027                         token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
2028
2029                 if (token->user_sids == NULL) {
2030                         DEBUG(0, ("talloc_memdup failed\n"));
2031                         TALLOC_FREE(token);
2032                         return NULL;
2033                 }
2034                 token->num_sids = ptoken->num_sids;
2035         }
2036         
2037         /* copy the privileges; don't consider failure to be critical here */
2038         
2039         if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
2040                 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!.  "
2041                          "Continuing with 0 privileges assigned.\n"));
2042         }
2043
2044         return token;
2045 }
2046
2047 /****************************************************************************
2048  Check for a SID in an NT_USER_TOKEN
2049 ****************************************************************************/
2050
2051 BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
2052 {
2053         int i;
2054         
2055         if ( !sid || !token )
2056                 return False;
2057         
2058         for ( i=0; i<token->num_sids; i++ ) {
2059                 if ( sid_equal( sid, &token->user_sids[i] ) )
2060                         return True;
2061         }
2062
2063         return False;
2064 }
2065
2066 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 
2067 {
2068         DOM_SID domain_sid;
2069
2070         /* if we are a domain member, the get the domain SID, else for 
2071            a DC or standalone server, use our own SID */
2072
2073         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
2074                 if ( !secrets_fetch_domain_sid( lp_workgroup(),
2075                                                 &domain_sid ) ) {
2076                         DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
2077                                  "SID for domain [%s]\n", lp_workgroup()));
2078                         return False;
2079                 }
2080         } 
2081         else
2082                 sid_copy( &domain_sid, get_global_sam_sid() );
2083
2084         sid_append_rid( &domain_sid, rid );
2085         
2086         return nt_token_check_sid( &domain_sid, token );\
2087 }
2088
2089 /**
2090  * Verify whether or not given domain is trusted.
2091  *
2092  * @param domain_name name of the domain to be verified
2093  * @return true if domain is one of the trusted once or
2094  *         false if otherwise
2095  **/
2096
2097 BOOL is_trusted_domain(const char* dom_name)
2098 {
2099         DOM_SID trustdom_sid;
2100         BOOL ret;
2101
2102         /* no trusted domains for a standalone server */
2103
2104         if ( lp_server_role() == ROLE_STANDALONE )
2105                 return False;
2106
2107         /* if we are a DC, then check for a direct trust relationships */
2108
2109         if ( IS_DC ) {
2110                 become_root();
2111                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2112                           "[%s]\n", dom_name ));
2113                 ret = secrets_fetch_trusted_domain_password(dom_name, NULL,
2114                                                             NULL, NULL);
2115                 unbecome_root();
2116                 if (ret)
2117                         return True;
2118         }
2119         else {
2120                 NSS_STATUS result;
2121
2122                 /* If winbind is around, ask it */
2123
2124                 result = wb_is_trusted_domain(dom_name);
2125
2126                 if (result == NSS_STATUS_SUCCESS) {
2127                         return True;
2128                 }
2129
2130                 if (result == NSS_STATUS_NOTFOUND) {
2131                         /* winbind could not find the domain */
2132                         return False;
2133                 }
2134
2135                 /* The only other possible result is that winbind is not up
2136                    and running. We need to update the trustdom_cache
2137                    ourselves */
2138                 
2139                 update_trustdom_cache();
2140         }
2141
2142         /* now the trustdom cache should be available a DC could still
2143          * have a transitive trust so fall back to the cache of trusted
2144          * domains (like a domain member would use  */
2145
2146         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2147                 return True;
2148         }
2149
2150         return False;
2151 }
2152