source: trunk/samba/source/auth/auth_util.c @ 30

Last change on this file since 30 was 30, checked in by Paul Smedley, 14 years ago

Code updated to Samba 3.0.25rc2 level

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