LCOV - code coverage report
Current view: top level - source3/auth - token_util.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 318 481 66.1 %
Date: 2021-09-23 10:06:22 Functions: 16 17 94.1 %

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

Generated by: LCOV version 1.13