LCOV - code coverage report
Current view: top level - source3/auth - token_util.c (source / functions) Hit Total Coverage
Test: coverage report for vadcx-master-patch-75612 fe003de8 Lines: 364 552 65.9 %
Date: 2024-02-29 22:57:05 Functions: 18 18 100.0 %

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

Generated by: LCOV version 1.14