LCOV - code coverage report
Current view: top level - source3/passdb - lookup_sid.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 554 799 69.3 %
Date: 2024-04-21 15:09:00 Functions: 20 20 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    uid/user handling
       4             :    Copyright (C) Andrew Tridgell         1992-1998
       5             :    Copyright (C) Gerald (Jerry) Carter   2003
       6             :    Copyright (C) Volker Lendecke         2005
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "passdb.h"
      24             : #include "lib/util_unixsids.h"
      25             : #include "../librpc/gen_ndr/ndr_security.h"
      26             : #include "secrets.h"
      27             : #include "../lib/util/memcache.h"
      28             : #include "idmap_cache.h"
      29             : #include "../libcli/security/security.h"
      30             : #include "lib/winbind_util.h"
      31             : #include "../librpc/gen_ndr/idmap.h"
      32             : #include "lib/util/bitmap.h"
      33             : 
      34          50 : static bool lookup_unix_user_name(const char *name, struct dom_sid *sid)
      35             : {
      36           0 :         struct passwd *pwd;
      37           0 :         bool ret;
      38             : 
      39          50 :         pwd = Get_Pwnam_alloc(talloc_tos(), name);
      40          50 :         if (pwd == NULL) {
      41          42 :                 return False;
      42             :         }
      43             : 
      44             :         /*
      45             :          * For 64-bit uid's we have enough space in the whole SID,
      46             :          * should they become necessary
      47             :          */
      48           8 :         ret = sid_compose(sid, &global_sid_Unix_Users, pwd->pw_uid);
      49           8 :         TALLOC_FREE(pwd);
      50           8 :         return ret;
      51             : }
      52             : 
      53         186 : static bool lookup_unix_group_name(const char *name, struct dom_sid *sid)
      54             : {
      55           0 :         struct group *grp;
      56             : 
      57         186 :         grp = getgrnam(name);
      58         186 :         if (grp == NULL) {
      59           0 :                 return False;
      60             :         }
      61             : 
      62             :         /*
      63             :          * For 64-bit gid's we have enough space in the whole SID,
      64             :          * should they become necessary
      65             :          */
      66         186 :         return sid_compose(sid, &global_sid_Unix_Groups, grp->gr_gid);
      67             : }
      68             : 
      69             : /*****************************************************************
      70             :  Dissect a user-provided name into domain, name, sid and type.
      71             : 
      72             :  If an explicit domain name was given in the form domain\user, it
      73             :  has to try that. If no explicit domain name was given, we have
      74             :  to do guesswork.
      75             : *****************************************************************/
      76             : 
      77        3662 : bool lookup_name(TALLOC_CTX *mem_ctx,
      78             :                  const char *full_name, int flags,
      79             :                  const char **ret_domain, const char **ret_name,
      80             :                  struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
      81             : {
      82           0 :         char *p;
      83           0 :         const char *tmp;
      84        3662 :         const char *domain = NULL;
      85        3662 :         const char *name = NULL;
      86           0 :         uint32_t rid;
      87           0 :         struct dom_sid sid;
      88           0 :         enum lsa_SidType type;
      89        3662 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
      90             : 
      91        3662 :         if (tmp_ctx == NULL) {
      92           0 :                 DEBUG(0, ("talloc_new failed\n"));
      93           0 :                 return false;
      94             :         }
      95             : 
      96        3662 :         p = strchr_m(full_name, '\\');
      97             : 
      98        3662 :         if (p != NULL) {
      99        3452 :                 domain = talloc_strndup(tmp_ctx, full_name,
     100        1726 :                                         PTR_DIFF(p, full_name));
     101        1726 :                 name = talloc_strdup(tmp_ctx, p+1);
     102             :         } else {
     103        1936 :                 char *q = strchr_m(full_name, '@');
     104             : 
     105             :                 /* Set the domain for UPNs */
     106        1936 :                 if (q != NULL) {
     107           0 :                         name = talloc_strndup(tmp_ctx,
     108             :                                               full_name,
     109           0 :                                               PTR_DIFF(q, full_name));
     110           0 :                         domain = talloc_strdup(tmp_ctx, q + 1);
     111             :                 } else {
     112        1936 :                         domain = talloc_strdup(tmp_ctx, "");
     113        1936 :                         name = talloc_strdup(tmp_ctx, full_name);
     114             :                 }
     115             :         }
     116             : 
     117        3662 :         if ((domain == NULL) || (name == NULL)) {
     118           0 :                 DEBUG(0, ("talloc failed\n"));
     119           0 :                 TALLOC_FREE(tmp_ctx);
     120           0 :                 return false;
     121             :         }
     122             : 
     123        3662 :         DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
     124             :                 full_name, domain, name));
     125        3662 :         DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
     126             : 
     127        3662 :         if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) {
     128        3662 :                 bool check_global_sam = false;
     129             : 
     130        3662 :                 check_global_sam = strequal(domain, get_global_sam_name());
     131             : 
     132             :                 /* If we are running on a DC that has PASSDB module with domain
     133             :                  * information, check if DNS forest name is matching the domain
     134             :                  * name. This is the case of IPA domain controller when
     135             :                  * trusted AD DC looks up users found in a Global Catalog of
     136             :                  * the forest root domain. */
     137        3662 :                 if (!check_global_sam && (IS_DC)) {
     138        1942 :                         struct pdb_domain_info *dom_info = NULL;
     139        1942 :                         dom_info = pdb_get_domain_info(tmp_ctx);
     140             : 
     141        1942 :                         if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
     142           4 :                                 check_global_sam = strequal(domain, dom_info->dns_forest);
     143             :                         }
     144             : 
     145        1942 :                         TALLOC_FREE(dom_info);
     146             :                 }
     147             : 
     148        3662 :                 if (check_global_sam) {
     149             :                         /* It's our own domain, lookup the name in passdb */
     150        1096 :                         if (lookup_global_sam_name(name, flags, &rid, &type)) {
     151         689 :                                 sid_compose(&sid, get_global_sam_sid(), rid);
     152         689 :                                 goto ok;
     153             :                         }
     154         407 :                         TALLOC_FREE(tmp_ctx);
     155         407 :                         return false;
     156             :                 }
     157             :         }
     158             : 
     159        5132 :         if ((flags & LOOKUP_NAME_BUILTIN) &&
     160        2566 :             strequal(domain, builtin_domain_name()))
     161             :         {
     162          12 :                 if (strlen(name) == 0) {
     163             :                         /* Swap domain and name */
     164           0 :                         tmp = name; name = domain; domain = tmp;
     165           0 :                         sid_copy(&sid, &global_sid_Builtin);
     166           0 :                         type = SID_NAME_DOMAIN;
     167           0 :                         goto ok;
     168             :                 }
     169             : 
     170             :                 /* Explicit request for a name in BUILTIN */
     171          12 :                 if (lookup_builtin_name(name, &rid)) {
     172          12 :                         sid_compose(&sid, &global_sid_Builtin, rid);
     173          12 :                         type = SID_NAME_ALIAS;
     174          12 :                         goto ok;
     175             :                 }
     176           0 :                 TALLOC_FREE(tmp_ctx);
     177           0 :                 return false;
     178             :         }
     179             : 
     180             :         /* Try the explicit winbind lookup first, don't let it guess the
     181             :          * domain yet at this point yet. This comes later. */
     182             : 
     183        2554 :         if ((domain[0] != '\0') &&
     184        1236 :             (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
     185         618 :             (winbind_lookup_name(domain, name, &sid, &type))) {
     186         462 :                         goto ok;
     187             :         }
     188             : 
     189        2092 :         if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
     190        1946 :             && strequal(domain, unix_users_domain_name())) {
     191          10 :                 if (lookup_unix_user_name(name, &sid)) {
     192           8 :                         type = SID_NAME_USER;
     193           8 :                         goto ok;
     194             :                 }
     195           2 :                 TALLOC_FREE(tmp_ctx);
     196           2 :                 return false;
     197             :         }
     198             : 
     199        2082 :         if (((flags & LOOKUP_NAME_NO_NSS) == 0)
     200        2082 :             && strequal(domain, unix_groups_domain_name())) {
     201         146 :                 if (lookup_unix_group_name(name, &sid)) {
     202         146 :                         type = SID_NAME_DOM_GRP;
     203         146 :                         goto ok;
     204             :                 }
     205           0 :                 TALLOC_FREE(tmp_ctx);
     206           0 :                 return false;
     207             :         }
     208             : 
     209             :         /*
     210             :          * Finally check for a well known domain name ("NT Authority"),
     211             :          * this is being taken care of in lookup_wellknown_name().
     212             :          */
     213        1936 :         if ((domain[0] != '\0') &&
     214           0 :             (flags & LOOKUP_NAME_WKN) &&
     215           0 :             lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
     216             :         {
     217           0 :                 type = SID_NAME_WKN_GRP;
     218           0 :                 goto ok;
     219             :         }
     220             : 
     221             :         /*
     222             :          * If we're told not to look up 'isolated' names then we're
     223             :          * done.
     224             :          */
     225        1936 :         if (!(flags & LOOKUP_NAME_ISOLATED)) {
     226           0 :                 TALLOC_FREE(tmp_ctx);
     227           0 :                 return false;
     228             :         }
     229             : 
     230             :         /*
     231             :          * No domain names beyond this point
     232             :          */
     233        1936 :         if (domain[0] != '\0') {
     234           0 :                 TALLOC_FREE(tmp_ctx);
     235           0 :                 return false;
     236             :         }
     237             : 
     238             :         /* Now the guesswork begins, we haven't been given an explicit
     239             :          * domain. Try the sequence as documented on
     240             :          * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
     241             :          * November 27, 2005 */
     242             : 
     243             :         /* 1. well-known names */
     244             : 
     245             :         /*
     246             :          * Check for well known names without a domain name.
     247             :          * e.g. \Creator Owner.
     248             :          */
     249             : 
     250        3872 :         if ((flags & LOOKUP_NAME_WKN) &&
     251        1936 :             lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
     252             :         {
     253          24 :                 type = SID_NAME_WKN_GRP;
     254          24 :                 goto ok;
     255             :         }
     256             : 
     257             :         /* 2. Builtin domain as such */
     258             : 
     259        3824 :         if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
     260        1912 :             strequal(name, builtin_domain_name()))
     261             :         {
     262             :                 /* Swap domain and name */
     263           0 :                 tmp = name; name = domain; domain = tmp;
     264           0 :                 sid_copy(&sid, &global_sid_Builtin);
     265           0 :                 type = SID_NAME_DOMAIN;
     266           0 :                 goto ok;
     267             :         }
     268             : 
     269             :         /* 3. Account domain */
     270             : 
     271        3824 :         if ((flags & LOOKUP_NAME_DOMAIN) &&
     272        1912 :             strequal(name, get_global_sam_name()))
     273             :         {
     274           0 :                 if (!secrets_fetch_domain_sid(name, &sid)) {
     275           0 :                         DEBUG(3, ("Could not fetch my SID\n"));
     276           0 :                         TALLOC_FREE(tmp_ctx);
     277           0 :                         return false;
     278             :                 }
     279             :                 /* Swap domain and name */
     280           0 :                 tmp = name; name = domain; domain = tmp;
     281           0 :                 type = SID_NAME_DOMAIN;
     282           0 :                 goto ok;
     283             :         }
     284             : 
     285             :         /* 4. Primary domain */
     286             : 
     287        2050 :         if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
     288         138 :             strequal(name, lp_workgroup()))
     289             :         {
     290           0 :                 if (!secrets_fetch_domain_sid(name, &sid)) {
     291           0 :                         DEBUG(3, ("Could not fetch the domain SID\n"));
     292           0 :                         TALLOC_FREE(tmp_ctx);
     293           0 :                         return false;
     294             :                 }
     295             :                 /* Swap domain and name */
     296           0 :                 tmp = name; name = domain; domain = tmp;
     297           0 :                 type = SID_NAME_DOMAIN;
     298           0 :                 goto ok;
     299             :         }
     300             : 
     301             :         /* 5. Trusted domains as such, to me it looks as if members don't do
     302             :               this, tested an XP workstation in a NT domain -- vl */
     303             : 
     304        2712 :         if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
     305         800 :             (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
     306             :         {
     307             :                 /* Swap domain and name */
     308           0 :                 tmp = name; name = domain; domain = tmp;
     309           0 :                 type = SID_NAME_DOMAIN;
     310           0 :                 goto ok;
     311             :         }
     312             : 
     313             :         /* 6. Builtin aliases */
     314             : 
     315        3824 :         if ((flags & LOOKUP_NAME_BUILTIN) &&
     316        1912 :             lookup_builtin_name(name, &rid))
     317             :         {
     318         800 :                 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
     319         800 :                 sid_compose(&sid, &global_sid_Builtin, rid);
     320         800 :                 type = SID_NAME_ALIAS;
     321         800 :                 goto ok;
     322             :         }
     323             : 
     324             :         /* 7. Local systems' SAM (DCs don't have a local SAM) */
     325             :         /* 8. Primary SAM (On members, this is the domain) */
     326             : 
     327             :         /* Both cases are done by looking at our passdb */
     328             : 
     329        2224 :         if ((flags & LOOKUP_NAME_DOMAIN) &&
     330        1112 :             lookup_global_sam_name(name, flags, &rid, &type))
     331             :         {
     332         116 :                 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
     333         116 :                 sid_compose(&sid, get_global_sam_sid(), rid);
     334         116 :                 goto ok;
     335             :         }
     336             : 
     337             :         /* Now our local possibilities are exhausted. */
     338             : 
     339         996 :         if (!(flags & LOOKUP_NAME_REMOTE)) {
     340         956 :                 TALLOC_FREE(tmp_ctx);
     341         956 :                 return false;
     342             :         }
     343             : 
     344             :         /* If we are not a DC, we have to ask in our primary domain. Let
     345             :          * winbind do that. */
     346             : 
     347          80 :         if (!IS_DC &&
     348          40 :             (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
     349           0 :                 domain = talloc_strdup(tmp_ctx, lp_workgroup());
     350           0 :                 goto ok;
     351             :         }
     352             : 
     353             :         /* 9. Trusted domains */
     354             : 
     355             :         /* If we're a DC we have to ask all trusted DC's. Winbind does not do
     356             :          * that (yet), but give it a chance. */
     357             : 
     358          40 :         if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
     359           0 :                 struct dom_sid dom_sid;
     360           0 :                 enum lsa_SidType domain_type;
     361             : 
     362           0 :                 if (type == SID_NAME_DOMAIN) {
     363             :                         /* Swap name and type */
     364           0 :                         tmp = name; name = domain; domain = tmp;
     365           0 :                         goto ok;
     366             :                 }
     367             : 
     368             :                 /* Here we have to cope with a little deficiency in the
     369             :                  * winbind API: We have to ask it again for the name of the
     370             :                  * domain it figured out itself. Maybe fix that later... */
     371             : 
     372           0 :                 sid_copy(&dom_sid, &sid);
     373           0 :                 sid_split_rid(&dom_sid, NULL);
     374             : 
     375           0 :                 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
     376           0 :                                         &domain_type) ||
     377           0 :                     (domain_type != SID_NAME_DOMAIN)) {
     378           0 :                         DEBUG(2, ("winbind could not find the domain's name "
     379             :                                   "it just looked up for us\n"));
     380           0 :                         TALLOC_FREE(tmp_ctx);
     381           0 :                         return false;
     382             :                 }
     383           0 :                 goto ok;
     384             :         }
     385             : 
     386             :         /* 10. Don't translate */
     387             : 
     388             :         /* 11. Ok, windows would end here. Samba has two more options:
     389             :                Unmapped users and unmapped groups */
     390             : 
     391          40 :         if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
     392          40 :             && lookup_unix_user_name(name, &sid)) {
     393           0 :                 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
     394           0 :                 type = SID_NAME_USER;
     395           0 :                 goto ok;
     396             :         }
     397             : 
     398          40 :         if (((flags & LOOKUP_NAME_NO_NSS) == 0)
     399          40 :             && lookup_unix_group_name(name, &sid)) {
     400          40 :                 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
     401          40 :                 type = SID_NAME_DOM_GRP;
     402          40 :                 goto ok;
     403             :         }
     404             : 
     405             :         /*
     406             :          * Ok, all possibilities tried. Fail.
     407             :          */
     408             : 
     409           0 :         TALLOC_FREE(tmp_ctx);
     410           0 :         return false;
     411             : 
     412        2297 :  ok:
     413        2297 :         if ((domain == NULL) || (name == NULL)) {
     414           0 :                 DEBUG(0, ("talloc failed\n"));
     415           0 :                 TALLOC_FREE(tmp_ctx);
     416           0 :                 return false;
     417             :         }
     418             : 
     419             :         /*
     420             :          * Hand over the results to the talloc context we've been given.
     421             :          */
     422             : 
     423        2297 :         if ((ret_name != NULL) &&
     424         372 :             !(*ret_name = talloc_strdup(mem_ctx, name))) {
     425           0 :                 DEBUG(0, ("talloc failed\n"));
     426           0 :                 TALLOC_FREE(tmp_ctx);
     427           0 :                 return false;
     428             :         }
     429             : 
     430        2297 :         if (ret_domain != NULL) {
     431           0 :                 char *tmp_dom;
     432        1350 :                 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
     433           0 :                         DEBUG(0, ("talloc failed\n"));
     434           0 :                         TALLOC_FREE(tmp_ctx);
     435           0 :                         return false;
     436             :                 }
     437        1350 :                 if (!strupper_m(tmp_dom)) {
     438           0 :                         TALLOC_FREE(tmp_ctx);
     439           0 :                         return false;
     440             :                 }
     441        1350 :                 *ret_domain = tmp_dom;
     442             :         }
     443             : 
     444        2297 :         if (ret_sid != NULL) {
     445        2289 :                 sid_copy(ret_sid, &sid);
     446             :         }
     447             : 
     448        2297 :         if (ret_type != NULL) {
     449        2245 :                 *ret_type = type;
     450             :         }
     451             : 
     452        2297 :         TALLOC_FREE(tmp_ctx);
     453        2297 :         return true;
     454             : }
     455             : 
     456             : /************************************************************************
     457             :  Names from smb.conf can be unqualified. eg. valid users = foo
     458             :  These names should never map to a remote name. Try global_sam_name()\foo,
     459             :  and then "Unix Users"\foo (or "Unix Groups"\foo).
     460             : ************************************************************************/
     461             : 
     462        1145 : bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
     463             :                  const char *full_name, int flags,
     464             :                  const char **ret_domain, const char **ret_name,
     465             :                  struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
     466             : {
     467        1145 :         char *qualified_name = NULL;
     468        1145 :         const char *p = strchr_m(full_name, *lp_winbind_separator());
     469        1145 :         bool is_qualified = p != NULL || strchr_m(full_name, '@') != NULL;
     470             : 
     471             :         /* For DOMAIN\user or user@REALM directly call lookup_name(). */
     472        1145 :         if (is_qualified) {
     473             : 
     474             :                 /* The name is already qualified with a domain. */
     475             : 
     476         158 :                 if (p != NULL && *lp_winbind_separator() != '\\') {
     477             :                         /* lookup_name() needs '\\' as a separator */
     478             : 
     479         158 :                         qualified_name = talloc_strdup(mem_ctx, full_name);
     480         158 :                         if (qualified_name == NULL) {
     481           0 :                                 return false;
     482             :                         }
     483         158 :                         qualified_name[p - full_name] = '\\';
     484         158 :                         full_name = qualified_name;
     485             :                 }
     486             : 
     487         158 :                 return lookup_name(mem_ctx, full_name, flags,
     488             :                                 ret_domain, ret_name,
     489             :                                 ret_sid, ret_type);
     490             :         }
     491             : 
     492             :         /* Try with winbind default domain name. */
     493         987 :         if (lp_winbind_use_default_domain()) {
     494           0 :                 bool ok;
     495             : 
     496           0 :                 qualified_name = talloc_asprintf(mem_ctx,
     497             :                                                  "%s\\%s",
     498             :                                                  lp_workgroup(),
     499             :                                                  full_name);
     500           0 :                 if (qualified_name == NULL) {
     501           0 :                         return false;
     502             :                 }
     503             : 
     504           0 :                 ok = lookup_name(mem_ctx,
     505             :                                  qualified_name,
     506             :                                  flags,
     507             :                                  ret_domain,
     508             :                                  ret_name,
     509             :                                  ret_sid,
     510             :                                  ret_type);
     511           0 :                 if (ok) {
     512           0 :                         return true;
     513             :                 }
     514             :         }
     515             : 
     516             :         /* Try with our own SAM name. */
     517         987 :         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
     518             :                                 get_global_sam_name(),
     519             :                                 full_name );
     520         987 :         if (!qualified_name) {
     521           0 :                 return false;
     522             :         }
     523             : 
     524         987 :         if (lookup_name(mem_ctx, qualified_name, flags,
     525             :                                 ret_domain, ret_name,
     526             :                                 ret_sid, ret_type)) {
     527         593 :                 return true;
     528             :         }
     529             : 
     530             :         /* Finally try with "Unix Users" or "Unix Group" */
     531         394 :         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
     532         394 :                                 flags & LOOKUP_NAME_GROUP ?
     533         146 :                                         unix_groups_domain_name() :
     534         248 :                                         unix_users_domain_name(),
     535             :                                 full_name );
     536         394 :         if (!qualified_name) {
     537           0 :                 return false;
     538             :         }
     539             : 
     540         394 :         return lookup_name(mem_ctx, qualified_name, flags,
     541             :                                 ret_domain, ret_name,
     542             :                                 ret_sid, ret_type);
     543             : }
     544             : 
     545         150 : static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
     546             :                            const struct dom_sid *domain_sid,
     547             :                            int num_rids, uint32_t *rids,
     548             :                            const char **domain_name,
     549             :                            const char **names, enum lsa_SidType *types)
     550             : {
     551           0 :         int i;
     552           0 :         const char **my_names;
     553           0 :         enum lsa_SidType *my_types;
     554           0 :         TALLOC_CTX *tmp_ctx;
     555             : 
     556         150 :         if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
     557           0 :                 return false;
     558             :         }
     559             : 
     560         150 :         if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
     561             :                                  domain_name, &my_names, &my_types)) {
     562         150 :                 *domain_name = "";
     563         300 :                 for (i=0; i<num_rids; i++) {
     564         150 :                         names[i] = "";
     565         150 :                         types[i] = SID_NAME_UNKNOWN;
     566             :                 }
     567         150 :                 TALLOC_FREE(tmp_ctx);
     568         150 :                 return true;
     569             :         }
     570             : 
     571           0 :         if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
     572           0 :                 TALLOC_FREE(tmp_ctx);
     573           0 :                 return false;
     574             :         }
     575             : 
     576             :         /*
     577             :          * winbind_lookup_rids allocates its own array. We've been given the
     578             :          * array, so copy it over
     579             :          */
     580             : 
     581           0 :         for (i=0; i<num_rids; i++) {
     582           0 :                 if (my_names[i] == NULL) {
     583           0 :                         TALLOC_FREE(tmp_ctx);
     584           0 :                         return false;
     585             :                 }
     586           0 :                 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
     587           0 :                         TALLOC_FREE(tmp_ctx);
     588           0 :                         return false;
     589             :                 }
     590           0 :                 types[i] = my_types[i];
     591             :         }
     592           0 :         TALLOC_FREE(tmp_ctx);
     593           0 :         return true;
     594             : }
     595             : 
     596        6462 : static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
     597             :                         int num_rids, uint32_t *rids,
     598             :                         const char **domain_name,
     599             :                         const char ***names, enum lsa_SidType **types)
     600             : {
     601         270 :         int i;
     602         270 :         struct dom_sid_buf buf;
     603             : 
     604        6462 :         DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
     605             :                    dom_sid_str_buf(domain_sid, &buf)));
     606             : 
     607        6462 :         if (num_rids) {
     608        6462 :                 *names = talloc_zero_array(mem_ctx, const char *, num_rids);
     609        6462 :                 *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
     610             : 
     611        6462 :                 if ((*names == NULL) || (*types == NULL)) {
     612           0 :                         return false;
     613             :                 }
     614             : 
     615       13716 :                 for (i = 0; i < num_rids; i++)
     616        7254 :                         (*types)[i] = SID_NAME_UNKNOWN;
     617             :         } else {
     618           0 :                 *names = NULL;
     619           0 :                 *types = NULL;
     620             :         }
     621             : 
     622        6462 :         if (sid_check_is_our_sam(domain_sid)) {
     623         270 :                 NTSTATUS result;
     624             : 
     625        4982 :                 if (*domain_name == NULL) {
     626        4982 :                         *domain_name = talloc_strdup(
     627             :                                 mem_ctx, get_global_sam_name());
     628             :                 }
     629             : 
     630        4982 :                 if (*domain_name == NULL) {
     631           0 :                         return false;
     632             :                 }
     633             : 
     634        4982 :                 become_root();
     635        4982 :                 result = pdb_lookup_rids(domain_sid, num_rids, rids,
     636             :                                          *names, *types);
     637        4982 :                 unbecome_root();
     638             : 
     639        4712 :                 return (NT_STATUS_IS_OK(result) ||
     640        4982 :                         NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
     641           0 :                         NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
     642             :         }
     643             : 
     644        1480 :         if (sid_check_is_builtin(domain_sid)) {
     645             : 
     646        1040 :                 if (*domain_name == NULL) {
     647        1040 :                         *domain_name = talloc_strdup(
     648             :                                 mem_ctx, builtin_domain_name());
     649             :                 }
     650             : 
     651        1040 :                 if (*domain_name == NULL) {
     652           0 :                         return false;
     653             :                 }
     654             : 
     655        2872 :                 for (i=0; i<num_rids; i++) {
     656        1832 :                         if (lookup_builtin_rid(*names, rids[i],
     657        1832 :                                                &(*names)[i])) {
     658        1832 :                                 if ((*names)[i] == NULL) {
     659           0 :                                         return false;
     660             :                                 }
     661        1832 :                                 (*types)[i] = SID_NAME_ALIAS;
     662             :                         } else {
     663           0 :                                 (*types)[i] = SID_NAME_UNKNOWN;
     664             :                         }
     665             :                 }
     666        1040 :                 return true;
     667             :         }
     668             : 
     669         440 :         if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
     670         248 :                 for (i=0; i<num_rids; i++) {
     671           0 :                         struct dom_sid sid;
     672         124 :                         sid_compose(&sid, domain_sid, rids[i]);
     673         124 :                         if (lookup_wellknown_sid(mem_ctx, &sid,
     674         124 :                                                  domain_name, &(*names)[i])) {
     675         124 :                                 if ((*names)[i] == NULL) {
     676           0 :                                         return false;
     677             :                                 }
     678         124 :                                 (*types)[i] = SID_NAME_WKN_GRP;
     679             :                         } else {
     680           0 :                                 (*types)[i] = SID_NAME_UNKNOWN;
     681             :                         }
     682             :                 }
     683         124 :                 return true;
     684             :         }
     685             : 
     686         316 :         if (sid_check_is_unix_users(domain_sid)) {
     687         158 :                 if (*domain_name == NULL) {
     688         158 :                         *domain_name = talloc_strdup(
     689             :                                 mem_ctx, unix_users_domain_name());
     690         158 :                         if (*domain_name == NULL) {
     691           0 :                                 return false;
     692             :                         }
     693             :                 }
     694         316 :                 for (i=0; i<num_rids; i++) {
     695         158 :                         (*names)[i] = talloc_strdup(
     696         158 :                                 (*names), uidtoname(rids[i]));
     697         158 :                         if ((*names)[i] == NULL) {
     698           0 :                                 return false;
     699             :                         }
     700         158 :                         (*types)[i] = SID_NAME_USER;
     701             :                 }
     702         158 :                 return true;
     703             :         }
     704             : 
     705         158 :         if (sid_check_is_unix_groups(domain_sid)) {
     706           8 :                 if (*domain_name == NULL) {
     707           8 :                         *domain_name = talloc_strdup(
     708             :                                 mem_ctx, unix_groups_domain_name());
     709           8 :                         if (*domain_name == NULL) {
     710           0 :                                 return false;
     711             :                         }
     712             :                 }
     713          16 :                 for (i=0; i<num_rids; i++) {
     714           8 :                         (*names)[i] = talloc_strdup(
     715           8 :                                 (*names), gidtoname(rids[i]));
     716           8 :                         if ((*names)[i] == NULL) {
     717           0 :                                 return false;
     718             :                         }
     719           8 :                         (*types)[i] = SID_NAME_DOM_GRP;
     720             :                 }
     721           8 :                 return true;
     722             :         }
     723             : 
     724         150 :         return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
     725             :                               domain_name, *names, *types);
     726             : }
     727             : 
     728             : /*
     729             :  * Is the SID a domain as such? If yes, lookup its name.
     730             :  */
     731             : 
     732        7254 : static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
     733             :                              const char **name)
     734             : {
     735         270 :         const char *tmp;
     736         270 :         enum lsa_SidType type;
     737             : 
     738        7254 :         if (sid_check_is_our_sam(sid)) {
     739           0 :                 *name = talloc_strdup(mem_ctx, get_global_sam_name());
     740           0 :                 return true;
     741             :         }
     742             : 
     743        7254 :         if (sid_check_is_builtin(sid)) {
     744           0 :                 *name = talloc_strdup(mem_ctx, builtin_domain_name());
     745           0 :                 return true;
     746             :         }
     747             : 
     748        7254 :         if (sid_check_is_wellknown_domain(sid, &tmp)) {
     749           0 :                 *name = talloc_strdup(mem_ctx, tmp);
     750           0 :                 return true;
     751             :         }
     752             : 
     753        7254 :         if (sid_check_is_unix_users(sid)) {
     754           0 :                 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
     755           0 :                 return true;
     756             :         }
     757             : 
     758        7254 :         if (sid_check_is_unix_groups(sid)) {
     759           0 :                 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
     760           0 :                 return true;
     761             :         }
     762             : 
     763        7254 :         if (sid->num_auths != 4) {
     764             :                 /* This can't be a domain */
     765        6984 :                 return false;
     766             :         }
     767             : 
     768           0 :         if (IS_DC) {
     769           0 :                 uint32_t i, num_domains;
     770           0 :                 struct trustdom_info **domains;
     771             : 
     772             :                 /* This is relatively expensive, but it happens only on DCs
     773             :                  * and for SIDs that have 4 sub-authorities and thus look like
     774             :                  * domains */
     775             : 
     776           0 :                 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
     777             :                                                           &num_domains,
     778             :                                                           &domains))) {
     779           0 :                         return false;
     780             :                 }
     781             : 
     782           0 :                 for (i=0; i<num_domains; i++) {
     783           0 :                         if (dom_sid_equal(sid, &domains[i]->sid)) {
     784           0 :                                 *name = talloc_strdup(mem_ctx,
     785           0 :                                                       domains[i]->name);
     786           0 :                                 return true;
     787             :                         }
     788             :                 }
     789           0 :                 return false;
     790             :         }
     791             : 
     792           0 :         if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
     793           0 :             (type == SID_NAME_DOMAIN)) {
     794           0 :                 *name = tmp;
     795           0 :                 return true;
     796             :         }
     797             : 
     798           0 :         return false;
     799             : }
     800             : 
     801             : /*
     802             :  * This tries to implement the rather weird rules for the lsa_lookup level
     803             :  * parameter.
     804             :  *
     805             :  * This is as close as we can get to what W2k3 does. With this we survive the
     806             :  * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
     807             :  * different, but I assume that's just being too liberal. For example, W2k3
     808             :  * replies to everything else but the levels 1-6 with INVALID_PARAMETER
     809             :  * whereas NT4 does the same as level 1 (I think). I did not fully test that
     810             :  * with NT4, this is what w2k3 does.
     811             :  *
     812             :  * Level 1: Ask everywhere
     813             :  * Level 2: Ask domain and trusted domains, no builtin and wkn
     814             :  * Level 3: Only ask domain
     815             :  * Level 4: W2k3ad: Only ask AD trusts
     816             :  * Level 5: Only ask transitive forest trusts
     817             :  * Level 6: Like 4
     818             :  */
     819             : 
     820        7254 : static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
     821             : {
     822         270 :         struct dom_sid_buf buf;
     823        7254 :         int ret = false;
     824             : 
     825        7254 :         switch(level) {
     826        7254 :         case 1:
     827        7254 :                 ret = true;
     828        7254 :                 break;
     829           0 :         case 2:
     830           0 :                 ret = (!sid_check_is_builtin(sid) &&
     831           0 :                        !sid_check_is_wellknown_domain(sid, NULL));
     832           0 :                 break;
     833           0 :         case 3:
     834             :         case 4:
     835             :         case 6:
     836           0 :                 ret = sid_check_is_our_sam(sid);
     837           0 :                 break;
     838           0 :         case 5:
     839           0 :                 ret = false;
     840           0 :                 break;
     841             :         }
     842             : 
     843        7254 :         DEBUG(10, ("%s SID %s in level %d\n",
     844             :                    ret ? "Accepting" : "Rejecting",
     845             :                    dom_sid_str_buf(sid, &buf),
     846             :                    level));
     847        7254 :         return ret;
     848             : }
     849             : 
     850             : /*
     851             :  * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
     852             :  * references to domains, it is explicitly made for this.
     853             :  *
     854             :  * This attempts to be as efficient as possible: It collects all SIDs
     855             :  * belonging to a domain and hands them in bulk to the appropriate lookup
     856             :  * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
     857             :  * *hugely* from this.
     858             :  */
     859             : 
     860        6462 : NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
     861             :                      const struct dom_sid **sids, int level,
     862             :                      struct lsa_dom_info **ret_domains,
     863             :                      struct lsa_name_info **ret_names)
     864             : {
     865         270 :         TALLOC_CTX *tmp_ctx;
     866         270 :         NTSTATUS result;
     867         270 :         struct lsa_name_info *name_infos;
     868        6462 :         struct lsa_dom_info *dom_infos = NULL;
     869             : 
     870         270 :         int i, j;
     871             : 
     872        6462 :         if (!(tmp_ctx = talloc_new(mem_ctx))) {
     873           0 :                 DEBUG(0, ("talloc_new failed\n"));
     874           0 :                 return NT_STATUS_NO_MEMORY;
     875             :         }
     876             : 
     877        6462 :         if (num_sids) {
     878        6462 :                 name_infos = talloc_array(mem_ctx, struct lsa_name_info, num_sids);
     879        6462 :                 if (name_infos == NULL) {
     880           0 :                         result = NT_STATUS_NO_MEMORY;
     881           0 :                         goto fail;
     882             :                 }
     883             :         } else {
     884           0 :                 name_infos = NULL;
     885             :         }
     886             : 
     887        6462 :         dom_infos = talloc_zero_array(mem_ctx, struct lsa_dom_info,
     888             :                                       LSA_REF_DOMAIN_LIST_MULTIPLIER);
     889        6462 :         if (dom_infos == NULL) {
     890           0 :                 result = NT_STATUS_NO_MEMORY;
     891           0 :                 goto fail;
     892             :         }
     893             : 
     894             :         /* First build up the data structures:
     895             :          *
     896             :          * dom_infos is a list of domains referenced in the list of
     897             :          * SIDs. Later we will walk the list of domains and look up the RIDs
     898             :          * in bulk.
     899             :          *
     900             :          * name_infos is a shadow-copy of the SIDs array to collect the real
     901             :          * data.
     902             :          *
     903             :          * dom_info->idxs is an index into the name_infos array. The
     904             :          * difficulty we have here is that we need to keep the SIDs the client
     905             :          * asked for in the same order for the reply
     906             :          */
     907             : 
     908       13716 :         for (i=0; i<num_sids; i++) {
     909         270 :                 struct dom_sid sid;
     910        7254 :                 uint32_t rid = 0;
     911        7254 :                 const char *domain_name = NULL;
     912             : 
     913        7254 :                 sid_copy(&sid, sids[i]);
     914        7254 :                 name_infos[i].type = SID_NAME_USE_NONE;
     915             : 
     916        7254 :                 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
     917             :                         /* We can't push that through the normal lookup
     918             :                          * process, as this would reference illegal
     919             :                          * domains.
     920             :                          *
     921             :                          * For example S-1-5-32 would end up referencing
     922             :                          * domain S-1-5- with RID 32 which is clearly wrong.
     923             :                          */
     924           0 :                         if (domain_name == NULL) {
     925           0 :                                 result = NT_STATUS_NO_MEMORY;
     926           0 :                                 goto fail;
     927             :                         }
     928             : 
     929           0 :                         name_infos[i].rid = 0;
     930           0 :                         name_infos[i].type = SID_NAME_DOMAIN;
     931           0 :                         name_infos[i].name = NULL;
     932             : 
     933           0 :                         if (sid_check_is_builtin(&sid)) {
     934             :                                 /* Yes, W2k3 returns "BUILTIN" both as domain
     935             :                                  * and name here */
     936           0 :                                 name_infos[i].name = talloc_strdup(
     937             :                                         name_infos, builtin_domain_name());
     938           0 :                                 if (name_infos[i].name == NULL) {
     939           0 :                                         result = NT_STATUS_NO_MEMORY;
     940           0 :                                         goto fail;
     941             :                                 }
     942             :                         }
     943             :                 } else {
     944             :                         /* This is a normal SID with rid component */
     945        7254 :                         if (!sid_split_rid(&sid, &rid)) {
     946           0 :                                 result = NT_STATUS_INVALID_SID;
     947           0 :                                 goto fail;
     948             :                         }
     949             :                 }
     950             : 
     951        7254 :                 if (!check_dom_sid_to_level(&sid, level)) {
     952           0 :                         name_infos[i].rid = 0;
     953           0 :                         name_infos[i].type = SID_NAME_UNKNOWN;
     954           0 :                         name_infos[i].name = NULL;
     955           0 :                         continue;
     956             :                 }
     957             : 
     958        7254 :                 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
     959        7254 :                         if (!dom_infos[j].valid) {
     960        6192 :                                 break;
     961             :                         }
     962         792 :                         if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
     963         792 :                                 break;
     964             :                         }
     965             :                 }
     966             : 
     967        7254 :                 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
     968             :                         /* TODO: What's the right error message here? */
     969           0 :                         result = NT_STATUS_NONE_MAPPED;
     970           0 :                         goto fail;
     971             :                 }
     972             : 
     973        7254 :                 if (!dom_infos[j].valid) {
     974             :                         /* We found a domain not yet referenced, create a new
     975             :                          * ref. */
     976        6462 :                         dom_infos[j].valid = true;
     977        6462 :                         sid_copy(&dom_infos[j].sid, &sid);
     978             : 
     979        6462 :                         if (domain_name != NULL) {
     980             :                                 /* This name was being found above in the case
     981             :                                  * when we found a domain SID */
     982           0 :                                 dom_infos[j].name =
     983           0 :                                         talloc_strdup(dom_infos, domain_name);
     984           0 :                                 if (dom_infos[j].name == NULL) {
     985           0 :                                         result = NT_STATUS_NO_MEMORY;
     986           0 :                                         goto fail;
     987             :                                 }
     988             :                         } else {
     989             :                                 /* lookup_rids will take care of this */
     990        6462 :                                 dom_infos[j].name = NULL;
     991             :                         }
     992             :                 }
     993             : 
     994        7254 :                 name_infos[i].dom_idx = j;
     995             : 
     996        7254 :                 if (name_infos[i].type == SID_NAME_USE_NONE) {
     997        7254 :                         name_infos[i].rid = rid;
     998             : 
     999        7254 :                         ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
    1000             :                                      &dom_infos[j].num_idxs);
    1001             : 
    1002        7254 :                         if (dom_infos[j].idxs == NULL) {
    1003           0 :                                 result = NT_STATUS_NO_MEMORY;
    1004           0 :                                 goto fail;
    1005             :                         }
    1006             :                 }
    1007             :         }
    1008             : 
    1009             :         /* Iterate over the domains found */
    1010             : 
    1011       12924 :         for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
    1012         540 :                 uint32_t *rids;
    1013       12924 :                 const char *domain_name = NULL;
    1014         540 :                 const char **names;
    1015         540 :                 enum lsa_SidType *types;
    1016       12924 :                 struct lsa_dom_info *dom = &dom_infos[i];
    1017             : 
    1018       12924 :                 if (!dom->valid) {
    1019             :                         /* No domains left, we're done */
    1020        6192 :                         break;
    1021             :                 }
    1022             : 
    1023        6462 :                 if (dom->num_idxs == 0) {
    1024             :                         /*
    1025             :                          * This happens only if the only sid related to
    1026             :                          * this domain is the domain sid itself, which
    1027             :                          * is mapped to SID_NAME_DOMAIN above.
    1028             :                          */
    1029           0 :                         continue;
    1030             :                 }
    1031             : 
    1032        6462 :                 if (!(rids = talloc_array(tmp_ctx, uint32_t, dom->num_idxs))) {
    1033           0 :                         result = NT_STATUS_NO_MEMORY;
    1034           0 :                         goto fail;
    1035             :                 }
    1036             : 
    1037       13716 :                 for (j=0; j<dom->num_idxs; j++) {
    1038        7254 :                         rids[j] = name_infos[dom->idxs[j]].rid;
    1039             :                 }
    1040             : 
    1041        6462 :                 if (!lookup_rids(tmp_ctx, &dom->sid,
    1042             :                                  dom->num_idxs, rids, &domain_name,
    1043             :                                  &names, &types)) {
    1044           0 :                         result = NT_STATUS_NO_MEMORY;
    1045           0 :                         goto fail;
    1046             :                 }
    1047             : 
    1048        6462 :                 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
    1049           0 :                         result = NT_STATUS_NO_MEMORY;
    1050           0 :                         goto fail;
    1051             :                 }
    1052             : 
    1053       13716 :                 for (j=0; j<dom->num_idxs; j++) {
    1054        7254 :                         int idx = dom->idxs[j];
    1055        7254 :                         name_infos[idx].type = types[j];
    1056        7254 :                         if (types[j] != SID_NAME_UNKNOWN) {
    1057       14208 :                                 name_infos[idx].name =
    1058        7104 :                                         talloc_strdup(name_infos, names[j]);
    1059        7104 :                                 if (name_infos[idx].name == NULL) {
    1060           0 :                                         result = NT_STATUS_NO_MEMORY;
    1061           0 :                                         goto fail;
    1062             :                                 }
    1063             :                         } else {
    1064         150 :                                 name_infos[idx].name = NULL;
    1065             :                         }
    1066             :                 }
    1067             :         }
    1068             : 
    1069        6462 :         *ret_domains = dom_infos;
    1070        6462 :         *ret_names = name_infos;
    1071        6462 :         TALLOC_FREE(tmp_ctx);
    1072        6462 :         return NT_STATUS_OK;
    1073             : 
    1074           0 :  fail:
    1075           0 :         TALLOC_FREE(dom_infos);
    1076           0 :         TALLOC_FREE(name_infos);
    1077           0 :         TALLOC_FREE(tmp_ctx);
    1078           0 :         return result;
    1079             : }
    1080             : 
    1081             : /*****************************************************************
    1082             :  *THE CANONICAL* convert SID to name function.
    1083             : *****************************************************************/
    1084             : 
    1085        5946 : bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
    1086             :                 const char **ret_domain, const char **ret_name,
    1087             :                 enum lsa_SidType *ret_type)
    1088             : {
    1089         270 :         struct lsa_dom_info *domain;
    1090         270 :         struct lsa_name_info *name;
    1091         270 :         struct dom_sid_buf buf;
    1092         270 :         TALLOC_CTX *tmp_ctx;
    1093        5946 :         bool ret = false;
    1094             : 
    1095        5946 :         DEBUG(10, ("lookup_sid called for SID '%s'\n",
    1096             :                    dom_sid_str_buf(sid, &buf)));
    1097             : 
    1098        5946 :         if (!(tmp_ctx = talloc_new(mem_ctx))) {
    1099           0 :                 DEBUG(0, ("talloc_new failed\n"));
    1100           0 :                 return false;
    1101             :         }
    1102             : 
    1103        5946 :         if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
    1104             :                                          &domain, &name))) {
    1105           0 :                 goto done;
    1106             :         }
    1107             : 
    1108        5946 :         if (name->type == SID_NAME_UNKNOWN) {
    1109           0 :                 goto done;
    1110             :         }
    1111             : 
    1112        5946 :         if ((ret_domain != NULL) &&
    1113          14 :             !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
    1114           0 :                 goto done;
    1115             :         }
    1116             : 
    1117        5946 :         if ((ret_name != NULL) &&
    1118         181 :             !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
    1119           0 :                 goto done;
    1120             :         }
    1121             : 
    1122        5946 :         if (ret_type != NULL) {
    1123        5932 :                 *ret_type = name->type;
    1124             :         }
    1125             : 
    1126        5946 :         ret = true;
    1127             : 
    1128        5676 :  done:
    1129        5676 :         if (ret) {
    1130        5946 :                 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
    1131             :                            dom_sid_str_buf(sid, &buf),
    1132             :                            domain->name, name->name, name->type));
    1133             :         } else {
    1134           0 :                 DEBUG(10, ("failed to lookup sid %s\n",
    1135             :                            dom_sid_str_buf(sid, &buf)));
    1136             :         }
    1137        5946 :         TALLOC_FREE(tmp_ctx);
    1138        5946 :         return ret;
    1139             : }
    1140             : 
    1141             : /*****************************************************************
    1142             :  *THE LEGACY* convert SID to id function.
    1143             : *****************************************************************/
    1144             : 
    1145       60886 : static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id)
    1146             : {
    1147          55 :         bool ret;
    1148             : 
    1149       60886 :         become_root();
    1150       60886 :         ret = pdb_sid_to_id(psid, id);
    1151       60886 :         unbecome_root();
    1152             : 
    1153       60886 :         if (!ret) {
    1154          21 :                 struct dom_sid_buf buf;
    1155       60445 :                 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
    1156             :                           dom_sid_str_buf(psid, &buf)));
    1157       60445 :                 return false;
    1158             :         }
    1159             : 
    1160         407 :         return true;
    1161             : }
    1162             : 
    1163       30262 : static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
    1164             : {
    1165          43 :         struct unixid id;
    1166       30262 :         if (!legacy_sid_to_unixid(psid, &id)) {
    1167       29920 :                 return false;
    1168             :         }
    1169         325 :         if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
    1170         273 :                 *pgid = id.id;
    1171         273 :                 return true;
    1172             :         }
    1173          52 :         return false;
    1174             : }
    1175             : 
    1176       30624 : static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
    1177             : {
    1178          12 :         struct unixid id;
    1179       30624 :         if (!legacy_sid_to_unixid(psid, &id)) {
    1180       30504 :                 return false;
    1181             :         }
    1182         116 :         if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) {
    1183         116 :                 *puid = id.id;
    1184         116 :                 return true;
    1185             :         }
    1186           0 :         return false;
    1187             : }
    1188             : 
    1189     1691113 : void xid_to_sid(struct dom_sid *psid, const struct unixid *xid)
    1190             : {
    1191     1691113 :         bool expired = true;
    1192        6452 :         bool ret;
    1193        6452 :         struct dom_sid_buf buf;
    1194             : 
    1195     1691113 :         SMB_ASSERT(xid->type == ID_TYPE_UID || xid->type == ID_TYPE_GID);
    1196             : 
    1197     1691113 :         *psid = (struct dom_sid) {0};
    1198             : 
    1199     1691113 :         ret = idmap_cache_find_xid2sid(xid, psid, &expired);
    1200     1691113 :         if (ret && !expired) {
    1201     1504915 :                 DBG_DEBUG("%cID %"PRIu32" -> %s from cache\n",
    1202             :                           xid->type == ID_TYPE_UID ? 'U' : 'G',
    1203             :                           xid->id,
    1204             :                           dom_sid_str_buf(psid, &buf));
    1205     1504915 :                 goto done;
    1206             :         }
    1207             : 
    1208      186198 :         ret = winbind_xid_to_sid(psid, xid);
    1209      186198 :         if (ret) {
    1210             :                 /*
    1211             :                  * winbind can return an explicit negative mapping
    1212             :                  * here. It's up to winbind to prime the cache either
    1213             :                  * positively or negatively, don't mess with the cache
    1214             :                  * here.
    1215             :                  */
    1216       11678 :                 DBG_DEBUG("%cID %"PRIu32" -> %s from cache\n",
    1217             :                           xid->type == ID_TYPE_UID ? 'U' : 'G',
    1218             :                           xid->id,
    1219             :                           dom_sid_str_buf(psid, &buf));
    1220       11678 :                 goto done;
    1221             :         }
    1222             : 
    1223             :         {
    1224             :                 /*
    1225             :                  * Make a copy, pdb_id_to_sid might want to turn
    1226             :                  * xid->type into ID_TYPE_BOTH, which we ignore here.
    1227             :                  */
    1228      174520 :                 struct unixid rw_xid = *xid;
    1229             : 
    1230      174520 :                 become_root();
    1231      174520 :                 ret = pdb_id_to_sid(&rw_xid, psid);
    1232      174520 :                 unbecome_root();
    1233             :         }
    1234             : 
    1235      174520 :         if (ret) {
    1236         114 :                 DBG_DEBUG("%cID %"PRIu32" -> %s from passdb\n",
    1237             :                           xid->type == ID_TYPE_UID ? 'U' : 'G',
    1238             :                           xid->id,
    1239             :                           dom_sid_str_buf(psid, &buf));
    1240         114 :                 goto done;
    1241             :         }
    1242             : 
    1243      174406 : done:
    1244     1691113 :         if (is_null_sid(psid)) {
    1245             :                 /*
    1246             :                  * Nobody found anything: Return S-1-22-xx-yy. Don't
    1247             :                  * store that in caches, this is up to the layers
    1248             :                  * beneath us.
    1249             :                  */
    1250      344320 :                 if (xid->type == ID_TYPE_UID) {
    1251         798 :                         uid_to_unix_users_sid(xid->id, psid);
    1252             :                 } else {
    1253      343522 :                         gid_to_unix_groups_sid(xid->id, psid);
    1254             :                 }
    1255             : 
    1256      344320 :                 DBG_DEBUG("%cID %"PRIu32" -> %s fallback\n",
    1257             :                           xid->type == ID_TYPE_UID ? 'U' : 'G',
    1258             :                           xid->id,
    1259             :                           dom_sid_str_buf(psid, &buf));
    1260             :         }
    1261     1691113 : }
    1262             : 
    1263      719185 : void uid_to_sid(struct dom_sid *psid, uid_t uid)
    1264             : {
    1265      719185 :         struct unixid xid = { .type = ID_TYPE_UID, .id = uid};
    1266      719185 :         xid_to_sid(psid, &xid);
    1267      719185 : }
    1268             : 
    1269      971928 : void gid_to_sid(struct dom_sid *psid, gid_t gid)
    1270             : {
    1271      971928 :         struct unixid xid = { .type = ID_TYPE_GID, .id = gid};
    1272      971928 :         xid_to_sid(psid, &xid);
    1273      971928 : }
    1274             : 
    1275      391311 : bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
    1276             :                      struct unixid *ids)
    1277             : {
    1278      391311 :         struct wbcDomainSid *wbc_sids = NULL;
    1279      391311 :         struct wbcUnixId *wbc_ids = NULL;
    1280      391311 :         struct bitmap *found = NULL;
    1281        1379 :         uint32_t i, num_not_cached;
    1282      391311 :         uint32_t wbc_ids_size = 0;
    1283        1379 :         wbcErr err;
    1284      391311 :         bool ret = false;
    1285             : 
    1286      391311 :         wbc_sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_sids);
    1287      391311 :         if (wbc_sids == NULL) {
    1288           0 :                 return false;
    1289             :         }
    1290      391311 :         found = bitmap_talloc(wbc_sids, num_sids);
    1291      391311 :         if (found == NULL) {
    1292           0 :                 goto fail;
    1293             :         }
    1294             : 
    1295             :         /*
    1296             :          * We go through the requested SID array three times.
    1297             :          * First time to look for global_sid_Unix_Users
    1298             :          * and global_sid_Unix_Groups SIDS, and to look
    1299             :          * for mappings cached in the idmap_cache.
    1300             :          *
    1301             :          * Use bitmap_set() to mark an ids[] array entry as
    1302             :          * being mapped.
    1303             :          */
    1304             : 
    1305      389932 :         num_not_cached = 0;
    1306             : 
    1307      924520 :         for (i=0; i<num_sids; i++) {
    1308        1379 :                 bool expired;
    1309        1379 :                 uint32_t rid;
    1310             : 
    1311      533209 :                 if (sid_peek_check_rid(&global_sid_Unix_Users,
    1312      533209 :                                        &sids[i], &rid)) {
    1313         124 :                         ids[i].type = ID_TYPE_UID;
    1314         124 :                         ids[i].id = rid;
    1315         124 :                         bitmap_set(found, i);
    1316      501681 :                         continue;
    1317             :                 }
    1318      533085 :                 if (sid_peek_check_rid(&global_sid_Unix_Groups,
    1319      531706 :                                        &sids[i], &rid)) {
    1320       41452 :                         ids[i].type = ID_TYPE_GID;
    1321       41452 :                         ids[i].id = rid;
    1322       41452 :                         bitmap_set(found, i);
    1323       41452 :                         continue;
    1324             :                 }
    1325      491633 :                 if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
    1326      460105 :                     && !expired)
    1327             :                 {
    1328      460105 :                         bitmap_set(found, i);
    1329      460105 :                         continue;
    1330             :                 }
    1331       31528 :                 ids[i].type = ID_TYPE_NOT_SPECIFIED;
    1332       63035 :                 memcpy(&wbc_sids[num_not_cached], &sids[i],
    1333       31507 :                        ndr_size_dom_sid(&sids[i], 0));
    1334       31528 :                 num_not_cached += 1;
    1335             :         }
    1336      391311 :         if (num_not_cached == 0) {
    1337      377186 :                 goto done;
    1338             :         }
    1339             : 
    1340             :         /*
    1341             :          * For the ones that we couldn't map in the loop above, query winbindd
    1342             :          * via wbcSidsToUnixIds().
    1343             :          */
    1344             : 
    1345       14125 :         wbc_ids_size = num_not_cached;
    1346       14125 :         wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, wbc_ids_size);
    1347       14125 :         if (wbc_ids == NULL) {
    1348           0 :                 goto fail;
    1349             :         }
    1350       45653 :         for (i=0; i<wbc_ids_size; i++) {
    1351       31528 :                 wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
    1352       31528 :                 wbc_ids[i].id.gid = (uint32_t)-1;
    1353             :         }
    1354       14125 :         err = wbcSidsToUnixIds(wbc_sids, wbc_ids_size, wbc_ids);
    1355       14125 :         if (!WBC_ERROR_IS_OK(err)) {
    1356       12839 :                 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
    1357             :                            wbcErrorString(err)));
    1358             :         }
    1359             : 
    1360             :         /*
    1361             :          * Second time through the SID array, replace
    1362             :          * the ids[] entries that wbcSidsToUnixIds() was able to
    1363             :          * map.
    1364             :          *
    1365             :          * Use bitmap_set() to mark an ids[] array entry as
    1366             :          * being mapped.
    1367             :          */
    1368             : 
    1369       14104 :         num_not_cached = 0;
    1370             : 
    1371      108221 :         for (i=0; i<num_sids; i++) {
    1372       94096 :                 if (bitmap_query(found, i)) {
    1373       62568 :                         continue;
    1374             :                 }
    1375             : 
    1376       31528 :                 SMB_ASSERT(num_not_cached < wbc_ids_size);
    1377             : 
    1378       31528 :                 switch (wbc_ids[num_not_cached].type) {
    1379           8 :                 case WBC_ID_TYPE_UID:
    1380           8 :                         ids[i].type = ID_TYPE_UID;
    1381           8 :                         ids[i].id = wbc_ids[num_not_cached].id.uid;
    1382           8 :                         bitmap_set(found, i);
    1383           8 :                         break;
    1384          97 :                 case WBC_ID_TYPE_GID:
    1385          97 :                         ids[i].type = ID_TYPE_GID;
    1386          97 :                         ids[i].id = wbc_ids[num_not_cached].id.gid;
    1387          97 :                         bitmap_set(found, i);
    1388          97 :                         break;
    1389        1244 :                 case WBC_ID_TYPE_BOTH:
    1390        1244 :                         ids[i].type = ID_TYPE_BOTH;
    1391        1244 :                         ids[i].id = wbc_ids[num_not_cached].id.uid;
    1392        1244 :                         bitmap_set(found, i);
    1393        1244 :                         break;
    1394       30179 :                 case WBC_ID_TYPE_NOT_SPECIFIED:
    1395             :                         /*
    1396             :                          * wbcSidsToUnixIds() wasn't able to map this
    1397             :                          * so we still need to check legacy_sid_to_XXX()
    1398             :                          * below. Don't mark the bitmap entry
    1399             :                          * as being found so the final loop knows
    1400             :                          * to try and map this entry.
    1401             :                          */
    1402       30179 :                         ids[i].type = ID_TYPE_NOT_SPECIFIED;
    1403       30179 :                         ids[i].id = (uint32_t)-1;
    1404       30179 :                         break;
    1405           0 :                 default:
    1406             :                         /*
    1407             :                          * A successful return from wbcSidsToUnixIds()
    1408             :                          * cannot return anything other than the values
    1409             :                          * checked for above. Ensure this is so.
    1410             :                          */
    1411           0 :                         smb_panic(__location__);
    1412          21 :                         break;
    1413             :                 }
    1414       31528 :                 num_not_cached += 1;
    1415             :         }
    1416             : 
    1417             :         /*
    1418             :          * Third and final time through the SID array,
    1419             :          * try legacy_sid_to_gid()/legacy_sid_to_uid()
    1420             :          * for entries we haven't already been able to
    1421             :          * map.
    1422             :          *
    1423             :          * Use bitmap_set() to mark an ids[] array entry as
    1424             :          * being mapped.
    1425             :          */
    1426             : 
    1427      108221 :         for (i=0; i<num_sids; i++) {
    1428       94096 :                 if (bitmap_query(found, i)) {
    1429       63917 :                         continue;
    1430             :                 }
    1431       30179 :                 if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
    1432         224 :                         ids[i].type = ID_TYPE_GID;
    1433         224 :                         bitmap_set(found, i);
    1434         224 :                         continue;
    1435             :                 }
    1436       29955 :                 if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
    1437          52 :                         ids[i].type = ID_TYPE_UID;
    1438          52 :                         bitmap_set(found, i);
    1439          52 :                         continue;
    1440             :                 }
    1441             :         }
    1442       14125 : done:
    1443             :         /*
    1444             :          * Pass through the return array for consistency.
    1445             :          * Any ids[].id mapped to (uint32_t)-1 must be returned
    1446             :          * as ID_TYPE_NOT_SPECIFIED.
    1447             :          */
    1448      924520 :         for (i=0; i<num_sids; i++) {
    1449      533209 :                 switch(ids[i].type) {
    1450      502617 :                 case ID_TYPE_GID:
    1451             :                 case ID_TYPE_UID:
    1452             :                 case ID_TYPE_BOTH:
    1453      502617 :                         if (ids[i].id == (uint32_t)-1) {
    1454           0 :                                 ids[i].type = ID_TYPE_NOT_SPECIFIED;
    1455             :                         }
    1456      501239 :                         break;
    1457       30591 :                 case ID_TYPE_NOT_SPECIFIED:
    1458       30591 :                         break;
    1459           0 :                 case ID_TYPE_WB_REQUIRE_TYPE:
    1460             :                         /*
    1461             :                          * these are internal between winbindd
    1462             :                          * parent and child.
    1463             :                          */
    1464           0 :                         smb_panic(__location__);
    1465        1379 :                         break;
    1466             :                 }
    1467             :         }
    1468             : 
    1469      389932 :         ret = true;
    1470      391311 : fail:
    1471      391311 :         TALLOC_FREE(wbc_ids);
    1472      391311 :         TALLOC_FREE(wbc_sids);
    1473      391311 :         return ret;
    1474             : }
    1475             : 
    1476             : /*****************************************************************
    1477             :  *THE CANONICAL* convert SID to uid function.
    1478             : *****************************************************************/
    1479             : 
    1480      177888 : bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
    1481             : {
    1482      177888 :         bool expired = true;
    1483         459 :         bool ret;
    1484         459 :         uint32_t rid;
    1485         459 :         struct dom_sid_buf buf;
    1486             : 
    1487             :         /* Optimize for the Unix Users Domain
    1488             :          * as the conversion is straightforward */
    1489      177888 :         if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
    1490         528 :                 uid_t uid = rid;
    1491         528 :                 *puid = uid;
    1492             : 
    1493             :                 /* return here, don't cache */
    1494         528 :                 DEBUG(10,("sid %s -> uid %u\n",
    1495             :                           dom_sid_str_buf(psid, &buf),
    1496             :                           (unsigned int)*puid ));
    1497         528 :                 return true;
    1498             :         }
    1499             : 
    1500      177360 :         if (sid_check_is_in_unix_groups(psid)) {
    1501           0 :                 DBG_DEBUG("SID %s is a group, failing\n",
    1502             :                           dom_sid_str_buf(psid, &buf));
    1503           0 :                 return false;
    1504             :         }
    1505             : 
    1506             :         /* Check the winbindd cache directly. */
    1507      177360 :         ret = idmap_cache_find_sid2uid(psid, puid, &expired);
    1508             : 
    1509      177360 :         if (ret && !expired && (*puid == (uid_t)-1)) {
    1510             :                 /*
    1511             :                  * Negative cache entry, we already asked.
    1512             :                  * do legacy.
    1513             :                  */
    1514         597 :                 return legacy_sid_to_uid(psid, puid);
    1515             :         }
    1516             : 
    1517      176763 :         if (!ret || expired) {
    1518             :                 /* Not in cache. Ask winbindd. */
    1519        2431 :                 if (!winbind_sid_to_uid(puid, psid)) {
    1520          72 :                         DEBUG(5, ("winbind failed to find a uid for sid %s\n",
    1521             :                                   dom_sid_str_buf(psid, &buf)));
    1522             :                         /* winbind failed. do legacy */
    1523          72 :                         return legacy_sid_to_uid(psid, puid);
    1524             :                 }
    1525             :         }
    1526             : 
    1527             :         /* TODO: Here would be the place to allocate both a gid and a uid for
    1528             :          * the SID in question */
    1529             : 
    1530      176691 :         DEBUG(10,("sid %s -> uid %u\n",
    1531             :                   dom_sid_str_buf(psid, &buf),
    1532             :                 (unsigned int)*puid ));
    1533             : 
    1534      176243 :         return true;
    1535             : }
    1536             : 
    1537             : /*****************************************************************
    1538             :  *THE CANONICAL* convert SID to gid function.
    1539             :  Group mapping is used for gids that maps to Wellknown SIDs
    1540             : *****************************************************************/
    1541             : 
    1542      152285 : bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
    1543             : {
    1544      152285 :         bool expired = true;
    1545         474 :         bool ret;
    1546         474 :         uint32_t rid;
    1547         474 :         struct dom_sid_buf buf;
    1548             : 
    1549             :         /* Optimize for the Unix Groups Domain
    1550             :          * as the conversion is straightforward */
    1551      152285 :         if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
    1552         328 :                 gid_t gid = rid;
    1553         328 :                 *pgid = gid;
    1554             : 
    1555             :                 /* return here, don't cache */
    1556         328 :                 DEBUG(10,("sid %s -> gid %u\n",
    1557             :                           dom_sid_str_buf(psid, &buf),
    1558             :                         (unsigned int)*pgid ));
    1559         328 :                 return true;
    1560             :         }
    1561             : 
    1562      151957 :         if (sid_check_is_in_unix_users(psid)) {
    1563           0 :                 DBG_DEBUG("SID %s is a user, failing\n",
    1564             :                           dom_sid_str_buf(psid, &buf));
    1565           0 :                 return false;
    1566             :         }
    1567             : 
    1568             :         /* Check the winbindd cache directly. */
    1569      151957 :         ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
    1570             : 
    1571      151957 :         if (ret && !expired && (*pgid == (gid_t)-1)) {
    1572             :                 /*
    1573             :                  * Negative cache entry, we already asked.
    1574             :                  * do legacy.
    1575             :                  */
    1576          16 :                 return legacy_sid_to_gid(psid, pgid);
    1577             :         }
    1578             : 
    1579      151941 :         if (!ret || expired) {
    1580             :                 /* Not in cache or negative. Ask winbindd. */
    1581             :                 /* Ask winbindd if it can map this sid to a gid.
    1582             :                  * (Idmap will check it is a valid SID and of the right type) */
    1583             : 
    1584        1319 :                 if ( !winbind_sid_to_gid(pgid, psid) ) {
    1585             : 
    1586          67 :                         DEBUG(10,("winbind failed to find a gid for sid %s\n",
    1587             :                                   dom_sid_str_buf(psid, &buf)));
    1588             :                         /* winbind failed. do legacy */
    1589          67 :                         return legacy_sid_to_gid(psid, pgid);
    1590             :                 }
    1591             :         }
    1592             : 
    1593      151874 :         DEBUG(10,("sid %s -> gid %u\n",
    1594             :                   dom_sid_str_buf(psid, &buf),
    1595             :                   (unsigned int)*pgid ));
    1596             : 
    1597      151422 :         return true;
    1598             : }
    1599             : 
    1600             : /**
    1601             :  * @brief This function gets the primary group SID mapping the primary
    1602             :  *        GID of the user as obtained by an actual getpwnam() call.
    1603             :  *        This is necessary to avoid issues with arbitrary group SIDs
    1604             :  *        stored in passdb. We try as hard as we can to get the SID
    1605             :  *        corresponding to the GID, including trying group mapping.
    1606             :  *        If nothing else works, we will force "Domain Users" as the
    1607             :  *        primary group.
    1608             :  *        This is needed because we must always be able to lookup the
    1609             :  *        primary group SID, so we cannot settle for an arbitrary SID.
    1610             :  *
    1611             :  *        This call can be expensive. Use with moderation.
    1612             :  *        If you have a "samu" struct around use pdb_get_group_sid()
    1613             :  *        instead as it does properly cache results.
    1614             :  *
    1615             :  * @param mem_ctx[in]     The memory context iused to allocate the result.
    1616             :  * @param username[in]    The user's name
    1617             :  * @param _pwd[in|out]    If available, pass in user's passwd struct.
    1618             :  *                        It will contain a tallocated passwd if NULL was
    1619             :  *                        passed in.
    1620             :  * @param _group_sid[out] The user's Primary Group SID
    1621             :  *
    1622             :  * @return NTSTATUS error code.
    1623             :  */
    1624       45998 : NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
    1625             :                                 const char *username,
    1626             :                                 struct passwd **_pwd,
    1627             :                                 struct dom_sid **_group_sid)
    1628             : {
    1629           1 :         TALLOC_CTX *tmp_ctx;
    1630       45998 :         bool need_lookup_sid = false;
    1631           1 :         struct dom_sid *group_sid;
    1632       45998 :         struct passwd *pwd = *_pwd;
    1633             : 
    1634       45998 :         tmp_ctx = talloc_new(mem_ctx);
    1635       45998 :         if (!tmp_ctx) {
    1636           0 :                 return NT_STATUS_NO_MEMORY;
    1637             :         }
    1638             : 
    1639       45998 :         if (!pwd) {
    1640       45444 :                 pwd = Get_Pwnam_alloc(mem_ctx, username);
    1641       45444 :                 if (!pwd) {
    1642           0 :                         DEBUG(0, ("Failed to find a Unix account for %s\n",
    1643             :                                   username));
    1644           0 :                         TALLOC_FREE(tmp_ctx);
    1645           0 :                         return NT_STATUS_NO_SUCH_USER;
    1646             :                 }
    1647             :         }
    1648             : 
    1649       45998 :         group_sid = talloc_zero(mem_ctx, struct dom_sid);
    1650       45998 :         if (!group_sid) {
    1651           0 :                 TALLOC_FREE(tmp_ctx);
    1652           0 :                 return NT_STATUS_NO_MEMORY;
    1653             :         }
    1654             : 
    1655       45998 :         gid_to_sid(group_sid, pwd->pw_gid);
    1656       45998 :         if (!is_null_sid(group_sid)) {
    1657           1 :                 struct dom_sid domain_sid;
    1658           1 :                 uint32_t rid;
    1659             : 
    1660             :                 /* We need a sid within our domain */
    1661       45998 :                 sid_copy(&domain_sid, group_sid);
    1662       45998 :                 sid_split_rid(&domain_sid, &rid);
    1663       45998 :                 if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
    1664             :                         /*
    1665             :                          * As shortcut for the expensive lookup_sid call
    1666             :                          * compare the domain sid part
    1667             :                          */
    1668         200 :                         switch (rid) {
    1669         200 :                         case DOMAIN_RID_ADMINS:
    1670             :                         case DOMAIN_RID_USERS:
    1671         200 :                                 goto done;
    1672           0 :                         default:
    1673           0 :                                 need_lookup_sid = true;
    1674           0 :                                 break;
    1675             :                         }
    1676             :                 } else {
    1677             :                         /* Try group mapping */
    1678           1 :                         struct unixid id;
    1679             : 
    1680       45798 :                         id.id = pwd->pw_gid;
    1681       45798 :                         id.type = ID_TYPE_GID;
    1682             : 
    1683       45798 :                         ZERO_STRUCTP(group_sid);
    1684       45798 :                         if (pdb_id_to_sid(&id, group_sid)) {
    1685           8 :                                 need_lookup_sid = true;
    1686             :                         }
    1687             :                 }
    1688             :         }
    1689             : 
    1690             :         /* We must verify that this is a valid SID that resolves to a
    1691             :          * group of the correct type */
    1692       45798 :         if (need_lookup_sid) {
    1693           8 :                 enum lsa_SidType type = SID_NAME_UNKNOWN;
    1694           0 :                 bool lookup_ret;
    1695           0 :                 struct dom_sid_buf buf;
    1696             : 
    1697           8 :                 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
    1698             :                            dom_sid_str_buf(group_sid, &buf),
    1699             :                            username));
    1700             : 
    1701             :                 /* Now check that it's actually a domain group and
    1702             :                  * not something else */
    1703           8 :                 lookup_ret = lookup_sid(tmp_ctx, group_sid,
    1704             :                                         NULL, NULL, &type);
    1705             : 
    1706           8 :                 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
    1707           0 :                         goto done;
    1708             :                 }
    1709             : 
    1710           8 :                 DEBUG(3, ("Primary group %s for user %s is"
    1711             :                           " a %s and not a domain group\n",
    1712             :                           dom_sid_str_buf(group_sid, &buf),
    1713             :                           username,
    1714             :                           sid_type_lookup(type)));
    1715             :         }
    1716             : 
    1717             :         /* Everything else, failed.
    1718             :          * Just set it to the 'Domain Users' RID of 513 which will
    1719             :            always resolve to a name */
    1720       45798 :         DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
    1721             :                   username));
    1722             : 
    1723       45798 :         sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
    1724             : 
    1725       45998 : done:
    1726       45998 :         *_pwd = talloc_move(mem_ctx, &pwd);
    1727       45998 :         *_group_sid = talloc_move(mem_ctx, &group_sid);
    1728       45998 :         TALLOC_FREE(tmp_ctx);
    1729       45998 :         return NT_STATUS_OK;
    1730             : }
    1731             : 

Generated by: LCOV version 1.14