lib: Add support to parse MS Catalog files
[samba.git] / source3 / auth / token_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  *  Copyright (C) Michael Adam 2007
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 3 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
23  */
24
25 /* functions moved from auth/auth_util.c to minimize linker deps */
26
27 #include "includes.h"
28 #include "lib/util_unixsids.h"
29 #include "system/passwd.h"
30 #include "auth.h"
31 #include "secrets.h"
32 #include "../lib/util/memcache.h"
33 #include "../librpc/gen_ndr/netlogon.h"
34 #include "../libcli/security/security.h"
35 #include "../lib/util/util_pw.h"
36 #include "passdb.h"
37 #include "lib/privileges.h"
38
39 /****************************************************************************
40  Check for a SID in an struct security_token
41 ****************************************************************************/
42
43 bool nt_token_check_sid ( const struct dom_sid *sid, const struct security_token *token )
44 {
45         if ( !sid || !token )
46                 return False;
47
48         return security_token_has_sid(token, sid);
49 }
50
51 bool nt_token_check_domain_rid( struct security_token *token, uint32_t rid )
52 {
53         struct dom_sid domain_sid;
54
55         /* if we are a domain member, the get the domain SID, else for
56            a DC or standalone server, use our own SID */
57
58         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
59                 if ( !secrets_fetch_domain_sid( lp_workgroup(),
60                                                 &domain_sid ) ) {
61                         DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
62                                  "SID for domain [%s]\n", lp_workgroup()));
63                         return False;
64                 }
65         }
66         else
67                 sid_copy( &domain_sid, get_global_sam_sid() );
68
69         sid_append_rid( &domain_sid, rid );
70
71         return nt_token_check_sid( &domain_sid, token );\
72 }
73
74 /******************************************************************************
75  Create a token for the root user to be used internally by smbd.
76  This is similar to running under the context of the LOCAL_SYSTEM account
77  in Windows.  This is a read-only token.  Do not modify it or free() it.
78  Create a copy if you need to change it.
79 ******************************************************************************/
80
81 struct security_token *get_root_nt_token( void )
82 {
83         struct security_token *token, *for_cache;
84         struct dom_sid u_sid, g_sid;
85         struct passwd *pw;
86         void *cache_data;
87
88         cache_data = memcache_lookup_talloc(
89                 NULL, SINGLETON_CACHE_TALLOC,
90                 data_blob_string_const_null("root_nt_token"));
91
92         if (cache_data != NULL) {
93                 return talloc_get_type_abort(
94                         cache_data, struct security_token);
95         }
96
97         if ( !(pw = getpwuid(0)) ) {
98                 if ( !(pw = getpwnam("root")) ) {
99                         DEBUG(0,("get_root_nt_token: both getpwuid(0) "
100                                 "and getpwnam(\"root\") failed!\n"));
101                         return NULL;
102                 }
103         }
104
105         /* get the user and primary group SIDs; although the
106            BUILTIN\Administrators SId is really the one that matters here */
107
108         uid_to_sid(&u_sid, pw->pw_uid);
109         gid_to_sid(&g_sid, pw->pw_gid);
110
111         token = create_local_nt_token(talloc_tos(), &u_sid, False,
112                                       1, &global_sid_Builtin_Administrators);
113
114         security_token_set_privilege(token, SEC_PRIV_DISK_OPERATOR);
115
116         for_cache = token;
117
118         memcache_add_talloc(
119                 NULL, SINGLETON_CACHE_TALLOC,
120                 data_blob_string_const_null("root_nt_token"), &for_cache);
121
122         return token;
123 }
124
125
126 /*
127  * Add alias SIDs from memberships within the partially created token SID list
128  */
129
130 NTSTATUS add_aliases(const struct dom_sid *domain_sid,
131                      struct security_token *token)
132 {
133         uint32_t *aliases;
134         size_t i, num_aliases;
135         NTSTATUS status;
136         TALLOC_CTX *tmp_ctx;
137
138         if (!(tmp_ctx = talloc_init("add_aliases"))) {
139                 return NT_STATUS_NO_MEMORY;
140         }
141
142         aliases = NULL;
143         num_aliases = 0;
144
145         status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
146                                             token->sids,
147                                             token->num_sids,
148                                             &aliases, &num_aliases);
149
150         if (!NT_STATUS_IS_OK(status)) {
151                 DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
152                            nt_errstr(status)));
153                 goto done;
154         }
155
156         for (i=0; i<num_aliases; i++) {
157                 struct dom_sid alias_sid;
158                 sid_compose(&alias_sid, domain_sid, aliases[i]);
159                 status = add_sid_to_array_unique(token, &alias_sid,
160                                                  &token->sids,
161                                                  &token->num_sids);
162                 if (!NT_STATUS_IS_OK(status)) {
163                         DEBUG(0, ("add_sid_to_array failed\n"));
164                         goto done;
165                 }
166         }
167
168 done:
169         TALLOC_FREE(tmp_ctx);
170         return NT_STATUS_OK;
171 }
172
173 /*******************************************************************
174 *******************************************************************/
175
176 static NTSTATUS add_builtin_administrators(struct security_token *token,
177                                            const struct dom_sid *dom_sid)
178 {
179         struct dom_sid domadm;
180         NTSTATUS status;
181
182         /* nothing to do if we aren't in a domain */
183
184         if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
185                 return NT_STATUS_OK;
186         }
187
188         /* Find the Domain Admins SID */
189
190         if ( IS_DC ) {
191                 sid_copy( &domadm, get_global_sam_sid() );
192         } else {
193                 if (dom_sid == NULL) {
194                         return NT_STATUS_INVALID_PARAMETER_MIX;
195                 }
196                 sid_copy(&domadm, dom_sid);
197         }
198         sid_append_rid( &domadm, DOMAIN_RID_ADMINS );
199
200         /* Add Administrators if the user beloongs to Domain Admins */
201
202         if ( nt_token_check_sid( &domadm, token ) ) {
203                 status = add_sid_to_array(token,
204                                           &global_sid_Builtin_Administrators,
205                                           &token->sids, &token->num_sids);
206         if (!NT_STATUS_IS_OK(status)) {
207                         return status;
208                 }
209         }
210
211         return NT_STATUS_OK;
212 }
213
214 static NTSTATUS add_builtin_guests(struct security_token *token,
215                                    const struct dom_sid *dom_sid)
216 {
217         struct dom_sid tmp_sid;
218         NTSTATUS status;
219
220         /*
221          * First check the local GUEST account.
222          */
223         sid_copy(&tmp_sid, get_global_sam_sid());
224         sid_append_rid(&tmp_sid, DOMAIN_RID_GUEST);
225
226         if (nt_token_check_sid(&tmp_sid, token)) {
227                 status = add_sid_to_array_unique(token,
228                                         &global_sid_Builtin_Guests,
229                                         &token->sids, &token->num_sids);
230                 if (!NT_STATUS_IS_OK(status)) {
231                         return status;
232                 }
233
234                 return NT_STATUS_OK;
235         }
236
237         /*
238          * First check the local GUESTS group.
239          */
240         sid_copy(&tmp_sid, get_global_sam_sid());
241         sid_append_rid(&tmp_sid, DOMAIN_RID_GUESTS);
242
243         if (nt_token_check_sid(&tmp_sid, token)) {
244                 status = add_sid_to_array_unique(token,
245                                         &global_sid_Builtin_Guests,
246                                         &token->sids, &token->num_sids);
247                 if (!NT_STATUS_IS_OK(status)) {
248                         return status;
249                 }
250
251                 return NT_STATUS_OK;
252         }
253
254         if (lp_server_role() != ROLE_DOMAIN_MEMBER) {
255                 return NT_STATUS_OK;
256         }
257
258         if (dom_sid == NULL) {
259                 return NT_STATUS_INVALID_PARAMETER_MIX;
260         }
261
262         /*
263          * First check the domain GUESTS group.
264          */
265         sid_copy(&tmp_sid, dom_sid);
266         sid_append_rid(&tmp_sid, DOMAIN_RID_GUESTS);
267
268         if (nt_token_check_sid(&tmp_sid, token)) {
269                 status = add_sid_to_array_unique(token,
270                                         &global_sid_Builtin_Guests,
271                                         &token->sids, &token->num_sids);
272                 if (!NT_STATUS_IS_OK(status)) {
273                         return status;
274                 }
275
276                 return NT_STATUS_OK;
277         }
278
279         return NT_STATUS_OK;
280 }
281
282 static NTSTATUS add_local_groups(struct security_token *result,
283                                  bool is_guest);
284
285 NTSTATUS get_user_sid_info3_and_extra(const struct netr_SamInfo3 *info3,
286                                       const struct extra_auth_info *extra,
287                                       struct dom_sid *sid)
288 {
289         /* USER SID */
290         if (info3->base.rid == (uint32_t)(-1)) {
291                 /* this is a signal the user was fake and generated,
292                  * the actual SID we want to use is stored in the extra
293                  * sids */
294                 if (is_null_sid(&extra->user_sid)) {
295                         /* we couldn't find the user sid, bail out */
296                         DEBUG(3, ("Invalid user SID\n"));
297                         return NT_STATUS_UNSUCCESSFUL;
298                 }
299                 sid_copy(sid, &extra->user_sid);
300         } else {
301                 sid_copy(sid, info3->base.domain_sid);
302                 sid_append_rid(sid, info3->base.rid);
303         }
304         return NT_STATUS_OK;
305 }
306
307 NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx,
308                                           bool is_guest,
309                                           const struct netr_SamInfo3 *info3,
310                                           const struct extra_auth_info *extra,
311                                           struct security_token **ntok)
312 {
313         struct security_token *usrtok = NULL;
314         uint32_t session_info_flags = 0;
315         NTSTATUS status;
316         int i;
317
318         DEBUG(10, ("Create local NT token for %s\n",
319                    info3->base.account_name.string));
320
321         usrtok = talloc_zero(mem_ctx, struct security_token);
322         if (!usrtok) {
323                 DEBUG(0, ("talloc failed\n"));
324                 return NT_STATUS_NO_MEMORY;
325         }
326
327         /* Add the user and primary group sid FIRST */
328         /* check if the user rid is the special "Domain Guests" rid.
329          * If so pick the first sid for the extra sids instead as it
330          * is a local fake account */
331         usrtok->sids = talloc_array(usrtok, struct dom_sid, 2);
332         if (!usrtok->sids) {
333                 TALLOC_FREE(usrtok);
334                 return NT_STATUS_NO_MEMORY;
335         }
336         usrtok->num_sids = 2;
337
338         status = get_user_sid_info3_and_extra(info3, extra, &usrtok->sids[0]);
339         if (!NT_STATUS_IS_OK(status)) {
340                 TALLOC_FREE(usrtok);
341                 return status;
342         }
343
344         /* GROUP SID */
345         if (info3->base.primary_gid == (uint32_t)(-1)) {
346                 /* this is a signal the user was fake and generated,
347                  * the actual SID we want to use is stored in the extra
348                  * sids */
349                 if (is_null_sid(&extra->pgid_sid)) {
350                         /* we couldn't find the user sid, bail out */
351                         DEBUG(3, ("Invalid group SID\n"));
352                         TALLOC_FREE(usrtok);
353                         return NT_STATUS_UNSUCCESSFUL;
354                 }
355                 sid_copy(&usrtok->sids[1], &extra->pgid_sid);
356         } else {
357                 sid_copy(&usrtok->sids[1], info3->base.domain_sid);
358                 sid_append_rid(&usrtok->sids[1],
359                                 info3->base.primary_gid);
360         }
361
362         /* Now the SIDs we got from authentication. These are the ones from
363          * the info3 struct or from the pdb_enum_group_memberships, depending
364          * on who authenticated the user.
365          * Note that we start the for loop at "1" here, we already added the
366          * first group sid as primary above. */
367
368         for (i = 0; i < info3->base.groups.count; i++) {
369                 struct dom_sid tmp_sid;
370
371                 sid_copy(&tmp_sid, info3->base.domain_sid);
372                 sid_append_rid(&tmp_sid, info3->base.groups.rids[i].rid);
373
374                 status = add_sid_to_array_unique(usrtok, &tmp_sid,
375                                                  &usrtok->sids,
376                                                  &usrtok->num_sids);
377                 if (!NT_STATUS_IS_OK(status)) {
378                         DEBUG(3, ("Failed to add SID to nt token\n"));
379                         TALLOC_FREE(usrtok);
380                         return status;
381                 }
382         }
383
384         /* now also add extra sids if they are not the special user/group
385          * sids */
386         for (i = 0; i < info3->sidcount; i++) {
387                 status = add_sid_to_array_unique(usrtok,
388                                                  info3->sids[i].sid,
389                                                  &usrtok->sids,
390                                                  &usrtok->num_sids);
391                 if (!NT_STATUS_IS_OK(status)) {
392                         DEBUG(3, ("Failed to add SID to nt token\n"));
393                         TALLOC_FREE(usrtok);
394                         return status;
395                 }
396         }
397
398         status = add_local_groups(usrtok, is_guest);
399         if (!NT_STATUS_IS_OK(status)) {
400                 DEBUG(3, ("Failed to add local groups\n"));
401                 TALLOC_FREE(usrtok);
402                 return status;
403         }
404
405         session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
406         if (!is_guest) {
407                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
408         }
409
410         status = finalize_local_nt_token(usrtok, session_info_flags);
411         if (!NT_STATUS_IS_OK(status)) {
412                 DEBUG(3, ("Failed to finalize nt token\n"));
413                 TALLOC_FREE(usrtok);
414                 return status;
415         }
416
417         *ntok = usrtok;
418         return NT_STATUS_OK;
419 }
420
421 /*******************************************************************
422  Create a NT token for the user, expanding local aliases
423 *******************************************************************/
424
425 struct security_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
426                                             const struct dom_sid *user_sid,
427                                             bool is_guest,
428                                             int num_groupsids,
429                                             const struct dom_sid *groupsids)
430 {
431         struct security_token *result = NULL;
432         int i;
433         NTSTATUS status;
434         uint32_t session_info_flags = 0;
435
436         DEBUG(10, ("Create local NT token for %s\n",
437                    sid_string_dbg(user_sid)));
438
439         if (!(result = talloc_zero(mem_ctx, struct security_token))) {
440                 DEBUG(0, ("talloc failed\n"));
441                 return NULL;
442         }
443
444         /* Add the user and primary group sid */
445
446         status = add_sid_to_array(result, user_sid,
447                                   &result->sids, &result->num_sids);
448         if (!NT_STATUS_IS_OK(status)) {
449                 TALLOC_FREE(result);
450                 return NULL;
451         }
452
453         /* For guest, num_groupsids may be zero. */
454         if (num_groupsids) {
455                 status = add_sid_to_array(result, &groupsids[0],
456                                           &result->sids,
457                                           &result->num_sids);
458                 if (!NT_STATUS_IS_OK(status)) {
459                         TALLOC_FREE(result);
460                         return NULL;
461                 }
462         }
463
464         /* Now the SIDs we got from authentication. These are the ones from
465          * the info3 struct or from the pdb_enum_group_memberships, depending
466          * on who authenticated the user.
467          * Note that we start the for loop at "1" here, we already added the
468          * first group sid as primary above. */
469
470         for (i=1; i<num_groupsids; i++) {
471                 status = add_sid_to_array_unique(result, &groupsids[i],
472                                                  &result->sids,
473                                                  &result->num_sids);
474                 if (!NT_STATUS_IS_OK(status)) {
475                         TALLOC_FREE(result);
476                         return NULL;
477                 }
478         }
479
480         status = add_local_groups(result, is_guest);
481         if (!NT_STATUS_IS_OK(status)) {
482                 TALLOC_FREE(result);
483                 return NULL;
484         }
485
486         session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
487         if (!is_guest) {
488                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
489         }
490
491         status = finalize_local_nt_token(result, session_info_flags);
492         if (!NT_STATUS_IS_OK(status)) {
493                 TALLOC_FREE(result);
494                 return NULL;
495         }
496
497         if (is_guest) {
498                 /*
499                  * It's ugly, but for now it's
500                  * needed to add Builtin_Guests
501                  * here, the "local" token only
502                  * consist of S-1-22-* SIDs
503                  * and finalize_local_nt_token()
504                  * doesn't have the chance to
505                  * to detect it need to
506                  * add Builtin_Guests via
507                  * add_builtin_guests().
508                  */
509                 status = add_sid_to_array_unique(result,
510                                                  &global_sid_Builtin_Guests,
511                                                  &result->sids,
512                                                  &result->num_sids);
513                 if (!NT_STATUS_IS_OK(status)) {
514                         DEBUG(3, ("Failed to add SID to nt token\n"));
515                         TALLOC_FREE(result);
516                         return NULL;
517                 }
518         }
519
520         return result;
521 }
522
523 /***************************************************
524  Merge in any groups from /etc/group.
525 ***************************************************/
526
527 static NTSTATUS add_local_groups(struct security_token *result,
528                                  bool is_guest)
529 {
530         gid_t *gids = NULL;
531         uint32_t getgroups_num_group_sids = 0;
532         struct passwd *pass = NULL;
533         TALLOC_CTX *tmp_ctx = talloc_stackframe();
534         int i;
535
536         if (is_guest) {
537                 /*
538                  * Guest is a special case. It's always
539                  * a user that can be looked up, but
540                  * result->sids[0] is set to DOMAIN\Guest.
541                  * Lookup by account name instead.
542                  */
543                 pass = Get_Pwnam_alloc(tmp_ctx, lp_guest_account());
544         } else {
545                 uid_t uid;
546
547                 /* For non-guest result->sids[0] is always the user sid. */
548                 if (!sid_to_uid(&result->sids[0], &uid)) {
549                         /*
550                          * Non-mappable SID like SYSTEM.
551                          * Can't be in any /etc/group groups.
552                          */
553                         TALLOC_FREE(tmp_ctx);
554                         return NT_STATUS_OK;
555                 }
556
557                 pass = getpwuid_alloc(tmp_ctx, uid);
558                 if (pass == NULL) {
559                         DEBUG(1, ("SID %s -> getpwuid(%u) failed\n",
560                                 sid_string_dbg(&result->sids[0]),
561                                 (unsigned int)uid));
562                 }
563         }
564
565         if (!pass) {
566                 TALLOC_FREE(tmp_ctx);
567                 return NT_STATUS_UNSUCCESSFUL;
568         }
569
570         /*
571          * Now we must get any groups this user has been
572          * added to in /etc/group and merge them in.
573          * This has to be done in every code path
574          * that creates an NT token, as remote users
575          * may have been added to the local /etc/group
576          * database. Tokens created merely from the
577          * info3 structs (via the DC or via the krb5 PAC)
578          * won't have these local groups. Note the
579          * groups added here will only be UNIX groups
580          * (S-1-22-2-XXXX groups) as getgroups_unix_user()
581          * turns off winbindd before calling getgroups().
582          *
583          * NB. This is duplicating work already
584          * done in the 'unix_user:' case of
585          * create_token_from_sid() but won't
586          * do anything other than be inefficient
587          * in that case.
588          */
589
590         if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
591                         &gids, &getgroups_num_group_sids)) {
592                 DEBUG(1, ("getgroups_unix_user for user %s failed\n",
593                         pass->pw_name));
594                 TALLOC_FREE(tmp_ctx);
595                 return NT_STATUS_UNSUCCESSFUL;
596         }
597
598         for (i=0; i<getgroups_num_group_sids; i++) {
599                 NTSTATUS status;
600                 struct dom_sid grp_sid;
601                 gid_to_sid(&grp_sid, gids[i]);
602
603                 status = add_sid_to_array_unique(result,
604                                          &grp_sid,
605                                          &result->sids,
606                                          &result->num_sids);
607                 if (!NT_STATUS_IS_OK(status)) {
608                         DEBUG(3, ("Failed to add UNIX SID to nt token\n"));
609                         TALLOC_FREE(tmp_ctx);
610                         return status;
611                 }
612         }
613         TALLOC_FREE(tmp_ctx);
614         return NT_STATUS_OK;
615 }
616
617 NTSTATUS finalize_local_nt_token(struct security_token *result,
618                                  uint32_t session_info_flags)
619 {
620         struct dom_sid _dom_sid = { 0, };
621         struct dom_sid *domain_sid = NULL;
622         NTSTATUS status;
623         struct acct_info *info;
624         bool ok;
625
626         result->privilege_mask = 0;
627         result->rights_mask = 0;
628
629         if (result->num_sids == 0) {
630                 return NT_STATUS_INVALID_TOKEN;
631         }
632
633         if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) {
634                 status = add_sid_to_array(result, &global_sid_World,
635                                           &result->sids, &result->num_sids);
636                 if (!NT_STATUS_IS_OK(status)) {
637                         return status;
638                 }
639                 status = add_sid_to_array(result, &global_sid_Network,
640                                           &result->sids, &result->num_sids);
641                 if (!NT_STATUS_IS_OK(status)) {
642                         return status;
643                 }
644         }
645
646         /*
647          * Don't expand nested groups of system, anonymous etc
648          *
649          * Note that they still get SID_WORLD and SID_NETWORK
650          * for now in order let existing tests pass.
651          *
652          * But SYSTEM doesn't get AUTHENTICATED_USERS
653          * and ANONYMOUS doesn't get BUILTIN GUESTS anymore.
654          */
655         if (security_token_is_anonymous(result)) {
656                 return NT_STATUS_OK;
657         }
658         if (security_token_is_system(result)) {
659                 result->privilege_mask = ~0;
660                 return NT_STATUS_OK;
661         }
662
663         if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) {
664                 status = add_sid_to_array(result,
665                                           &global_sid_Authenticated_Users,
666                                           &result->sids,
667                                           &result->num_sids);
668                 if (!NT_STATUS_IS_OK(status)) {
669                         return status;
670                 }
671         }
672
673         /* Add in BUILTIN sids */
674
675         become_root();
676         ok = secrets_fetch_domain_sid(lp_workgroup(), &_dom_sid);
677         if (ok) {
678                 domain_sid = &_dom_sid;
679         } else {
680                 DEBUG(3, ("Failed to fetch domain sid for %s\n",
681                           lp_workgroup()));
682         }
683         unbecome_root();
684
685         info = talloc_zero(talloc_tos(), struct acct_info);
686         if (info == NULL) {
687                 DEBUG(0, ("talloc failed!\n"));
688                 return NT_STATUS_NO_MEMORY;
689         }
690
691         /* Deal with the BUILTIN\Administrators group.  If the SID can
692            be resolved then assume that the add_aliasmem( S-1-5-32 )
693            handled it. */
694
695         status = pdb_get_aliasinfo(&global_sid_Builtin_Administrators, info);
696         if (!NT_STATUS_IS_OK(status)) {
697
698                 become_root();
699                 status = create_builtin_administrators(domain_sid);
700                 unbecome_root();
701
702                 if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE)) {
703                         /* Add BUILTIN\Administrators directly to token. */
704                         status = add_builtin_administrators(result, domain_sid);
705                         if ( !NT_STATUS_IS_OK(status) ) {
706                                 DEBUG(3, ("Failed to check for local "
707                                           "Administrators membership (%s)\n",
708                                           nt_errstr(status)));
709                         }
710                 } else if (!NT_STATUS_IS_OK(status)) {
711                         DEBUG(2, ("WARNING: Failed to create "
712                                   "BUILTIN\\Administrators group!  Can "
713                                   "Winbind allocate gids?\n"));
714                 }
715         }
716
717         /* Deal with the BUILTIN\Users group.  If the SID can
718            be resolved then assume that the add_aliasmem( S-1-5-32 )
719            handled it. */
720
721         status = pdb_get_aliasinfo(&global_sid_Builtin_Users, info);
722         if (!NT_STATUS_IS_OK(status)) {
723
724                 become_root();
725                 status = create_builtin_users(domain_sid);
726                 unbecome_root();
727
728                 if (!NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE) &&
729                     !NT_STATUS_IS_OK(status))
730                 {
731                         DEBUG(2, ("WARNING: Failed to create BUILTIN\\Users group! "
732                                   "Can Winbind allocate gids?\n"));
733                 }
734         }
735
736         /*
737          * Deal with the BUILTIN\Guests group.  If the SID can
738          * be resolved then assume that the add_aliasmem( S-1-5-32 )
739          * handled it.
740          */
741         status = pdb_get_aliasinfo(&global_sid_Builtin_Guests, info);
742         if (!NT_STATUS_IS_OK(status)) {
743
744                 become_root();
745                 status = create_builtin_guests(domain_sid);
746                 unbecome_root();
747
748                 if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE)) {
749                         /*
750                          * Add BUILTIN\Guests directly to token.
751                          * But only if the token already indicates
752                          * real guest access by:
753                          * - local GUEST account
754                          * - local GUESTS group
755                          * - domain GUESTS group
756                          *
757                          * Even if a user was authenticated, it
758                          * can be member of a guest related group.
759                          */
760                         status = add_builtin_guests(result, domain_sid);
761                         if (!NT_STATUS_IS_OK(status)) {
762                                 DEBUG(3, ("Failed to check for local "
763                                           "Guests membership (%s)\n",
764                                           nt_errstr(status)));
765                                 /*
766                                  * This is a hard error.
767                                  */
768                                 return status;
769                         }
770                 } else if (!NT_STATUS_IS_OK(status)) {
771                         DEBUG(2, ("Failed to create "
772                                   "BUILTIN\\Guests group %s!  Can "
773                                   "Winbind allocate gids?\n",
774                                   nt_errstr(status)));
775                         /*
776                          * This is a hard error.
777                          */
778                         return status;
779                 }
780         }
781
782         TALLOC_FREE(info);
783
784         /* Deal with local groups */
785
786         if (lp_winbind_nested_groups()) {
787
788                 become_root();
789
790                 /* Now add the aliases. First the one from our local SAM */
791
792                 status = add_aliases(get_global_sam_sid(), result);
793
794                 if (!NT_STATUS_IS_OK(status)) {
795                         unbecome_root();
796                         return status;
797                 }
798
799                 /* Finally the builtin ones */
800
801                 status = add_aliases(&global_sid_Builtin, result);
802
803                 if (!NT_STATUS_IS_OK(status)) {
804                         unbecome_root();
805                         return status;
806                 }
807
808                 unbecome_root();
809         }
810
811         if (session_info_flags & AUTH_SESSION_INFO_NTLM) {
812                 struct dom_sid tmp_sid = { 0, };
813
814                 ok = dom_sid_parse(SID_NT_NTLM_AUTHENTICATION, &tmp_sid);
815                 if (!ok) {
816                         return NT_STATUS_NO_MEMORY;
817                 }
818
819                 status = add_sid_to_array(result,
820                                           &tmp_sid,
821                                           &result->sids,
822                                           &result->num_sids);
823                 if (!NT_STATUS_IS_OK(status)) {
824                         return status;
825                 }
826         }
827
828         if (session_info_flags & AUTH_SESSION_INFO_SIMPLE_PRIVILEGES) {
829                 if (security_token_has_builtin_administrators(result)) {
830                         result->privilege_mask = ~0;
831                 }
832         } else {
833                 /* Add privileges based on current user sids */
834                 get_privileges_for_sids(&result->privilege_mask, result->sids,
835                                         result->num_sids);
836         }
837
838         return NT_STATUS_OK;
839 }
840
841 /****************************************************************************
842  prints a UNIX 'token' to debug output.
843 ****************************************************************************/
844
845 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
846                            int n_groups, gid_t *groups)
847 {
848         int     i;
849         DEBUGC(dbg_class, dbg_lev,
850                ("UNIX token of user %ld\n", (long int)uid));
851
852         DEBUGADDC(dbg_class, dbg_lev,
853                   ("Primary group is %ld and contains %i supplementary "
854                    "groups\n", (long int)gid, n_groups));
855         for (i = 0; i < n_groups; i++)
856                 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
857                         (long int)groups[i]));
858 }
859
860 /*
861  * Create an artificial NT token given just a domain SID.
862  *
863  * We have 3 cases:
864  *
865  * unmapped unix users: Go directly to nss to find the user's group.
866  *
867  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
868  *
869  * If the user is provided by winbind, the primary gid is set to "domain
870  * users" of the user's domain. For an explanation why this is necessary, see
871  * the thread starting at
872  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
873  */
874
875 static NTSTATUS create_token_from_sid(TALLOC_CTX *mem_ctx,
876                                       const struct dom_sid *user_sid,
877                                       bool is_guest,
878                                       uid_t *uid, gid_t *gid,
879                                       char **found_username,
880                                       struct security_token **token)
881 {
882         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
883         TALLOC_CTX *tmp_ctx = talloc_stackframe();
884         gid_t *gids;
885         struct dom_sid *group_sids;
886         struct dom_sid tmp_sid;
887         uint32_t num_group_sids;
888         uint32_t num_gids;
889         uint32_t i;
890         uint32_t high, low;
891         bool range_ok;
892
893         if (sid_check_is_in_our_sam(user_sid)) {
894                 bool ret;
895                 uint32_t pdb_num_group_sids;
896                 /* This is a passdb user, so ask passdb */
897
898                 struct samu *sam_acct = NULL;
899
900                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
901                         result = NT_STATUS_NO_MEMORY;
902                         goto done;
903                 }
904
905                 become_root();
906                 ret = pdb_getsampwsid(sam_acct, user_sid);
907                 unbecome_root();
908
909                 if (!ret) {
910                         DEBUG(1, ("pdb_getsampwsid(%s) failed\n",
911                                   sid_string_dbg(user_sid)));
912                         DEBUGADD(1, ("Fall back to unix user\n"));
913                         goto unix_user;
914                 }
915
916                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
917                                                     &group_sids, &gids,
918                                                     &pdb_num_group_sids);
919                 if (!NT_STATUS_IS_OK(result)) {
920                         DEBUG(1, ("enum_group_memberships failed for %s: "
921                                   "%s\n", sid_string_dbg(user_sid),
922                                   nt_errstr(result)));
923                         DEBUGADD(1, ("Fall back to unix uid lookup\n"));
924                         goto unix_user;
925                 }
926                 num_group_sids = pdb_num_group_sids;
927
928                 /* see the smb_panic() in pdb_default_enum_group_memberships */
929                 SMB_ASSERT(num_group_sids > 0);
930
931                 /* Ensure we're returning the found_username on the right context. */
932                 *found_username = talloc_strdup(mem_ctx,
933                                                 pdb_get_username(sam_acct));
934
935                 if (*found_username == NULL) {
936                         result = NT_STATUS_NO_MEMORY;
937                         goto done;
938                 }
939
940                 /*
941                  * If the SID from lookup_name() was the guest sid, passdb knows
942                  * about the mapping of guest sid to lp_guest_account()
943                  * username and will return the unix_pw info for a guest
944                  * user. Use it if it's there, else lookup the *uid details
945                  * using Get_Pwnam_alloc(). See bug #6291 for details. JRA.
946                  */
947
948                 /* We must always assign the *uid. */
949                 if (sam_acct->unix_pw == NULL) {
950                         struct passwd *pwd = Get_Pwnam_alloc(sam_acct, *found_username );
951                         if (!pwd) {
952                                 DEBUG(10, ("Get_Pwnam_alloc failed for %s\n",
953                                         *found_username));
954                                 result = NT_STATUS_NO_SUCH_USER;
955                                 goto done;
956                         }
957                         result = samu_set_unix(sam_acct, pwd );
958                         if (!NT_STATUS_IS_OK(result)) {
959                                 DEBUG(10, ("samu_set_unix failed for %s\n",
960                                         *found_username));
961                                 result = NT_STATUS_NO_SUCH_USER;
962                                 goto done;
963                         }
964                 }
965                 *uid = sam_acct->unix_pw->pw_uid;
966
967         } else  if (sid_check_is_in_unix_users(user_sid)) {
968                 uint32_t getgroups_num_group_sids;
969                 /* This is a unix user not in passdb. We need to ask nss
970                  * directly, without consulting passdb */
971
972                 struct passwd *pass;
973
974                 /*
975                  * This goto target is used as a fallback for the passdb
976                  * case. The concrete bug report is when passdb gave us an
977                  * unmapped gid.
978                  */
979
980         unix_user:
981
982                 if (!sid_to_uid(user_sid, uid)) {
983                         DEBUG(1, ("unix_user case, sid_to_uid for %s failed\n",
984                                   sid_string_dbg(user_sid)));
985                         result = NT_STATUS_NO_SUCH_USER;
986                         goto done;
987                 }
988
989                 uid_to_unix_users_sid(*uid, &tmp_sid);
990                 user_sid = &tmp_sid;
991
992                 pass = getpwuid_alloc(tmp_ctx, *uid);
993                 if (pass == NULL) {
994                         DEBUG(1, ("getpwuid(%u) failed\n",
995                                   (unsigned int)*uid));
996                         goto done;
997                 }
998
999                 if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
1000                                          &gids, &getgroups_num_group_sids)) {
1001                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
1002                                   pass->pw_name));
1003                         goto done;
1004                 }
1005                 num_group_sids = getgroups_num_group_sids;
1006
1007                 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_group_sids);
1008                 if (group_sids == NULL) {
1009                         DEBUG(1, ("talloc_array failed\n"));
1010                         result = NT_STATUS_NO_MEMORY;
1011                         goto done;
1012                 }
1013
1014                 for (i=0; i<num_group_sids; i++) {
1015                         gid_to_sid(&group_sids[i], gids[i]);
1016                 }
1017
1018                 /* In getgroups_unix_user we always set the primary gid */
1019                 SMB_ASSERT(num_group_sids > 0);
1020
1021                 /* Ensure we're returning the found_username on the right context. */
1022                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
1023                 if (*found_username == NULL) {
1024                         result = NT_STATUS_NO_MEMORY;
1025                         goto done;
1026                 }
1027         } else {
1028
1029                 /* This user is from winbind, force the primary gid to the
1030                  * user's "domain users" group. Under certain circumstances
1031                  * (user comes from NT4), this might be a loss of
1032                  * information. But we can not rely on winbind getting the
1033                  * correct info. AD might prohibit winbind looking up that
1034                  * information. */
1035
1036                 /* We must always assign the *uid. */
1037                 if (!sid_to_uid(user_sid, uid)) {
1038                         DEBUG(1, ("winbindd case, sid_to_uid for %s failed\n",
1039                                   sid_string_dbg(user_sid)));
1040                         result = NT_STATUS_NO_SUCH_USER;
1041                         goto done;
1042                 }
1043
1044                 num_group_sids = 1;
1045                 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_group_sids);
1046                 if (group_sids == NULL) {
1047                         DEBUG(1, ("talloc_array failed\n"));
1048                         result = NT_STATUS_NO_MEMORY;
1049                         goto done;
1050                 }
1051
1052                 gids = talloc_array(tmp_ctx, gid_t, num_group_sids);
1053                 if (gids == NULL) {
1054                         result = NT_STATUS_NO_MEMORY;
1055                         goto done;
1056                 }
1057
1058                 sid_copy(&group_sids[0], user_sid);
1059                 sid_split_rid(&group_sids[0], NULL);
1060                 sid_append_rid(&group_sids[0], DOMAIN_RID_USERS);
1061
1062                 if (!sid_to_gid(&group_sids[0], &gids[0])) {
1063                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1064                                   sid_string_dbg(&group_sids[0])));
1065                         goto done;
1066                 }
1067
1068                 *found_username = NULL;
1069         }
1070
1071         *gid = gids[0];
1072
1073         /* Add the "Unix Group" SID for each gid to catch mapped groups
1074            and their Unix equivalent.  This is to solve the backwards
1075            compatibility problem of 'valid users = +ntadmin' where
1076            ntadmin has been paired with "Domain Admins" in the group
1077            mapping table.  Otherwise smb.conf would need to be changed
1078            to 'valid user = "Domain Admins"'.  --jerry */
1079
1080         num_gids = num_group_sids;
1081         range_ok = lp_idmap_default_range(&low, &high);
1082         for ( i=0; i<num_gids; i++ ) {
1083                 struct dom_sid unix_group_sid;
1084
1085                 /* don't pickup anything managed by Winbind */
1086                 if (range_ok && (gids[i] >= low) && (gids[i] <= high)) {
1087                         continue;
1088                 }
1089
1090                 gid_to_unix_groups_sid(gids[i], &unix_group_sid);
1091
1092                 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1093                                                  &group_sids, &num_group_sids);
1094                 if (!NT_STATUS_IS_OK(result)) {
1095                         goto done;
1096                 }
1097         }
1098
1099         /* Ensure we're creating the nt_token on the right context. */
1100         *token = create_local_nt_token(mem_ctx, user_sid,
1101                                        is_guest, num_group_sids, group_sids);
1102
1103         if (*token == NULL) {
1104                 result = NT_STATUS_NO_MEMORY;
1105                 goto done;
1106         }
1107
1108         result = NT_STATUS_OK;
1109  done:
1110         TALLOC_FREE(tmp_ctx);
1111         return result;
1112 }
1113
1114 /*
1115  * Create an artificial NT token given just a username. (Initially intended
1116  * for force user)
1117  *
1118  * We go through lookup_name() to avoid problems we had with 'winbind use
1119  * default domain'.
1120  *
1121  * We have 3 cases:
1122  *
1123  * unmapped unix users: Go directly to nss to find the user's group.
1124  *
1125  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
1126  *
1127  * If the user is provided by winbind, the primary gid is set to "domain
1128  * users" of the user's domain. For an explanation why this is necessary, see
1129  * the thread starting at
1130  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
1131  */
1132
1133 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
1134                                     bool is_guest,
1135                                     uid_t *uid, gid_t *gid,
1136                                     char **found_username,
1137                                     struct security_token **token)
1138 {
1139         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
1140         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1141         struct dom_sid user_sid;
1142         enum lsa_SidType type;
1143
1144         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
1145                          NULL, NULL, &user_sid, &type)) {
1146                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
1147                 goto done;
1148         }
1149
1150         if (type != SID_NAME_USER) {
1151                 DEBUG(1, ("%s is a %s, not a user\n", username,
1152                           sid_type_lookup(type)));
1153                 goto done;
1154         }
1155
1156         result = create_token_from_sid(mem_ctx, &user_sid, is_guest, uid, gid, found_username, token);
1157
1158         if (!NT_STATUS_IS_OK(result)) {
1159                 goto done;
1160         }
1161
1162         /*
1163          * If result == NT_STATUS_OK then
1164          * we know we have a valid token. Ensure
1165          * we also have a valid username to match.
1166          */
1167
1168         if (*found_username == NULL) {
1169                 *found_username = talloc_strdup(mem_ctx, username);
1170                 if (*found_username == NULL) {
1171                         result = NT_STATUS_NO_MEMORY;
1172                 }
1173         }
1174
1175 done:
1176         TALLOC_FREE(tmp_ctx);
1177         return result;
1178 }
1179
1180 /***************************************************************************
1181  Build upon create_token_from_sid:
1182
1183  Expensive helper function to figure out whether a user given its sid is
1184  member of a particular group.
1185 ***************************************************************************/
1186
1187 bool user_sid_in_group_sid(const struct dom_sid *sid, const struct dom_sid *group_sid)
1188 {
1189         NTSTATUS status;
1190         uid_t uid;
1191         gid_t gid;
1192         char *found_username;
1193         struct security_token *token;
1194         bool result = false;
1195         enum lsa_SidType type;
1196         TALLOC_CTX *mem_ctx = talloc_stackframe();
1197
1198         if (!lookup_sid(mem_ctx, sid,
1199                          NULL, NULL, &type)) {
1200                 DEBUG(1, ("lookup_sid for %s failed\n", dom_sid_string(mem_ctx, sid)));
1201                 goto done;
1202         }
1203
1204         if (type != SID_NAME_USER) {
1205                 DEBUG(5, ("%s is a %s, not a user\n", dom_sid_string(mem_ctx, sid),
1206                           sid_type_lookup(type)));
1207                 goto done;
1208         }
1209
1210         status = create_token_from_sid(mem_ctx, sid, False,
1211                                        &uid, &gid, &found_username,
1212                                        &token);
1213
1214         if (!NT_STATUS_IS_OK(status)) {
1215                 DEBUG(10, ("could not create token for %s\n", dom_sid_string(mem_ctx, sid)));
1216                 goto done;
1217         }
1218
1219         result = security_token_has_sid(token, group_sid);
1220
1221 done:
1222         TALLOC_FREE(mem_ctx);
1223         return result;
1224 }
1225
1226 /***************************************************************************
1227  Build upon create_token_from_username:
1228
1229  Expensive helper function to figure out whether a user given its name is
1230  member of a particular group.
1231 ***************************************************************************/
1232
1233 bool user_in_group_sid(const char *username, const struct dom_sid *group_sid)
1234 {
1235         NTSTATUS status;
1236         uid_t uid;
1237         gid_t gid;
1238         char *found_username;
1239         struct security_token *token;
1240         bool result;
1241         TALLOC_CTX *mem_ctx = talloc_stackframe();
1242
1243         status = create_token_from_username(mem_ctx, username, False,
1244                                             &uid, &gid, &found_username,
1245                                             &token);
1246
1247         if (!NT_STATUS_IS_OK(status)) {
1248                 DEBUG(10, ("could not create token for %s\n", username));
1249                 TALLOC_FREE(mem_ctx);
1250                 return False;
1251         }
1252
1253         result = security_token_has_sid(token, group_sid);
1254
1255         TALLOC_FREE(mem_ctx);
1256         return result;
1257 }
1258
1259 bool user_in_group(const char *username, const char *groupname)
1260 {
1261         TALLOC_CTX *mem_ctx = talloc_stackframe();
1262         struct dom_sid group_sid;
1263         bool ret;
1264
1265         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1266                           NULL, NULL, &group_sid, NULL);
1267         TALLOC_FREE(mem_ctx);
1268
1269         if (!ret) {
1270                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1271                 return False;
1272         }
1273
1274         return user_in_group_sid(username, &group_sid);
1275 }
1276
1277 /* END */