LCOV - code coverage report
Current view: top level - source3/passdb - lookup_sid.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 496 737 67.3 %
Date: 2024-06-13 04:01:37 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          48 : static bool lookup_unix_user_name(const char *name, struct dom_sid *sid)
      35             : {
      36             :         struct passwd *pwd;
      37             :         bool ret;
      38             : 
      39          48 :         pwd = Get_Pwnam_alloc(talloc_tos(), name);
      40          48 :         if (pwd == NULL) {
      41          44 :                 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           4 :         ret = sid_compose(sid, &global_sid_Unix_Users, pwd->pw_uid);
      49           4 :         TALLOC_FREE(pwd);
      50           4 :         return ret;
      51             : }
      52             : 
      53          84 : static bool lookup_unix_group_name(const char *name, struct dom_sid *sid)
      54             : {
      55             :         struct group *grp;
      56             : 
      57          84 :         grp = getgrnam(name);
      58          84 :         if (grp == NULL) {
      59           2 :                 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          82 :         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         653 : 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             :         char *p;
      83             :         const char *tmp;
      84         653 :         const char *domain = NULL;
      85         653 :         const char *name = NULL;
      86             :         uint32_t rid;
      87             :         struct dom_sid sid;
      88             :         enum lsa_SidType type;
      89         653 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
      90             : 
      91         653 :         if (tmp_ctx == NULL) {
      92           0 :                 DEBUG(0, ("talloc_new failed\n"));
      93           0 :                 return false;
      94             :         }
      95             : 
      96         653 :         p = strchr_m(full_name, '\\');
      97             : 
      98         653 :         if (p != NULL) {
      99         879 :                 domain = talloc_strndup(tmp_ctx, full_name,
     100         602 :                                         PTR_DIFF(p, full_name));
     101         602 :                 name = talloc_strdup(tmp_ctx, p+1);
     102             :         } else {
     103          51 :                 char *q = strchr_m(full_name, '@');
     104             : 
     105             :                 /* Set the domain for UPNs */
     106          51 :                 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          51 :                         domain = talloc_strdup(tmp_ctx, "");
     113          51 :                         name = talloc_strdup(tmp_ctx, full_name);
     114             :                 }
     115             :         }
     116             : 
     117         653 :         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         653 :         DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
     124             :                 full_name, domain, name));
     125         653 :         DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
     126             : 
     127         653 :         if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) {
     128         653 :                 bool check_global_sam = false;
     129             : 
     130         653 :                 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         653 :                 if (!check_global_sam && (IS_DC)) {
     138          11 :                         struct pdb_domain_info *dom_info = NULL;
     139          11 :                         dom_info = pdb_get_domain_info(tmp_ctx);
     140             : 
     141          11 :                         if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
     142           4 :                                 check_global_sam = strequal(domain, dom_info->dns_forest);
     143             :                         }
     144             : 
     145          11 :                         TALLOC_FREE(dom_info);
     146             :                 }
     147             : 
     148         653 :                 if (check_global_sam) {
     149             :                         /* It's our own domain, lookup the name in passdb */
     150         291 :                         if (lookup_global_sam_name(name, flags, &rid, &type)) {
     151         146 :                                 sid_compose(&sid, get_global_sam_sid(), rid);
     152         146 :                                 goto ok;
     153             :                         }
     154         145 :                         TALLOC_FREE(tmp_ctx);
     155         145 :                         return false;
     156             :                 }
     157             :         }
     158             : 
     159         724 :         if ((flags & LOOKUP_NAME_BUILTIN) &&
     160         362 :             strequal(domain, builtin_domain_name()))
     161             :         {
     162           8 :                 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           8 :                 if (lookup_builtin_name(name, &rid)) {
     172           8 :                         sid_compose(&sid, &global_sid_Builtin, rid);
     173           8 :                         type = SID_NAME_ALIAS;
     174           8 :                         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         513 :         if ((domain[0] != '\0') &&
     184         606 :             (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
     185         303 :             (winbind_lookup_name(domain, name, &sid, &type))) {
     186         254 :                         goto ok;
     187             :         }
     188             : 
     189         100 :         if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
     190          58 :             && strequal(domain, unix_users_domain_name())) {
     191           6 :                 if (lookup_unix_user_name(name, &sid)) {
     192           4 :                         type = SID_NAME_USER;
     193           4 :                         goto ok;
     194             :                 }
     195           2 :                 TALLOC_FREE(tmp_ctx);
     196           2 :                 return false;
     197             :         }
     198             : 
     199          94 :         if (((flags & LOOKUP_NAME_NO_NSS) == 0)
     200          94 :             && strequal(domain, unix_groups_domain_name())) {
     201          42 :                 if (lookup_unix_group_name(name, &sid)) {
     202          42 :                         type = SID_NAME_DOM_GRP;
     203          42 :                         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          53 :         if ((domain[0] != '\0') &&
     214           2 :             (flags & LOOKUP_NAME_WKN) &&
     215           1 :             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          52 :         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          52 :         if (domain[0] != '\0') {
     234           1 :                 TALLOC_FREE(tmp_ctx);
     235           1 :                 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         102 :         if ((flags & LOOKUP_NAME_WKN) &&
     251          51 :             lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
     252             :         {
     253           0 :                 type = SID_NAME_WKN_GRP;
     254           0 :                 goto ok;
     255             :         }
     256             : 
     257             :         /* 2. Builtin domain as such */
     258             : 
     259         102 :         if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
     260          51 :             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         102 :         if ((flags & LOOKUP_NAME_DOMAIN) &&
     272          51 :             strequal(name, get_global_sam_name()))
     273             :         {
     274           2 :                 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           2 :                 tmp = name; name = domain; domain = tmp;
     281           2 :                 type = SID_NAME_DOMAIN;
     282           2 :                 goto ok;
     283             :         }
     284             : 
     285             :         /* 4. Primary domain */
     286             : 
     287          93 :         if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
     288          44 :             strequal(name, lp_workgroup()))
     289             :         {
     290           1 :                 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           1 :                 tmp = name; name = domain; domain = tmp;
     297           1 :                 type = SID_NAME_DOMAIN;
     298           1 :                 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          48 :         if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
     305           0 :             (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          96 :         if ((flags & LOOKUP_NAME_BUILTIN) &&
     316          48 :             lookup_builtin_name(name, &rid))
     317             :         {
     318           0 :                 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
     319           0 :                 sid_compose(&sid, &global_sid_Builtin, rid);
     320           0 :                 type = SID_NAME_ALIAS;
     321           0 :                 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          96 :         if ((flags & LOOKUP_NAME_DOMAIN) &&
     330          48 :             lookup_global_sam_name(name, flags, &rid, &type))
     331             :         {
     332           4 :                 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
     333           4 :                 sid_compose(&sid, get_global_sam_sid(), rid);
     334           4 :                 goto ok;
     335             :         }
     336             : 
     337             :         /* Now our local possibilities are exhausted. */
     338             : 
     339          44 :         if (!(flags & LOOKUP_NAME_REMOTE)) {
     340           2 :                 TALLOC_FREE(tmp_ctx);
     341           2 :                 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          84 :         if (!IS_DC &&
     348          42 :             (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          42 :         if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
     359             :                 struct dom_sid dom_sid;
     360             :                 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          42 :         if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
     392          42 :             && 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          42 :         if (((flags & LOOKUP_NAME_NO_NSS) == 0)
     399          42 :             && 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           2 :         TALLOC_FREE(tmp_ctx);
     410           2 :         return false;
     411             : 
     412         501 :  ok:
     413         501 :         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         552 :         if ((ret_name != NULL) &&
     424          90 :             !(*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         501 :         if (ret_domain != NULL) {
     431             :                 char *tmp_dom;
     432          97 :                 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          97 :                 if (!strupper_m(tmp_dom)) {
     438           0 :                         TALLOC_FREE(tmp_ctx);
     439           0 :                         return false;
     440             :                 }
     441          97 :                 *ret_domain = tmp_dom;
     442             :         }
     443             : 
     444         501 :         if (ret_sid != NULL) {
     445         501 :                 sid_copy(ret_sid, &sid);
     446             :         }
     447             : 
     448         501 :         if (ret_type != NULL) {
     449         461 :                 *ret_type = type;
     450             :         }
     451             : 
     452         501 :         TALLOC_FREE(tmp_ctx);
     453         501 :         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         432 : 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         432 :         char *qualified_name = NULL;
     468         432 :         const char *p = strchr_m(full_name, *lp_winbind_separator());
     469         432 :         bool is_qualified = p != NULL || strchr_m(full_name, '@') != NULL;
     470             : 
     471             :         /* For DOMAIN\user or user@REALM directly call lookup_name(). */
     472         432 :         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         274 :         if (lp_winbind_use_default_domain()) {
     494             :                 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         274 :         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
     518             :                                 get_global_sam_name(),
     519             :                                 full_name );
     520         274 :         if (!qualified_name) {
     521           0 :                 return false;
     522             :         }
     523             : 
     524         274 :         if (lookup_name(mem_ctx, qualified_name, flags,
     525             :                                 ret_domain, ret_name,
     526             :                                 ret_sid, ret_type)) {
     527         144 :                 return true;
     528             :         }
     529             : 
     530             :         /* Finally try with "Unix Users" or "Unix Group" */
     531         130 :         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
     532         130 :                                 flags & LOOKUP_NAME_GROUP ?
     533          19 :                                         unix_groups_domain_name() :
     534          40 :                                         unix_users_domain_name(),
     535             :                                 full_name );
     536         130 :         if (!qualified_name) {
     537           0 :                 return false;
     538             :         }
     539             : 
     540         130 :         return lookup_name(mem_ctx, qualified_name, flags,
     541             :                                 ret_domain, ret_name,
     542             :                                 ret_sid, ret_type);
     543             : }
     544             : 
     545          20 : 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             :         int i;
     552             :         const char **my_names;
     553             :         enum lsa_SidType *my_types;
     554             :         TALLOC_CTX *tmp_ctx;
     555             : 
     556          20 :         if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
     557           0 :                 return false;
     558             :         }
     559             : 
     560          20 :         if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
     561             :                                  domain_name, &my_names, &my_types)) {
     562          20 :                 *domain_name = "";
     563          40 :                 for (i=0; i<num_rids; i++) {
     564          20 :                         names[i] = "";
     565          20 :                         types[i] = SID_NAME_UNKNOWN;
     566             :                 }
     567          20 :                 TALLOC_FREE(tmp_ctx);
     568          20 :                 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        2770 : 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             :         int i;
     602             :         struct dom_sid_buf buf;
     603             : 
     604        2770 :         DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
     605             :                    dom_sid_str_buf(domain_sid, &buf)));
     606             : 
     607        2770 :         if (num_rids) {
     608        2770 :                 *names = talloc_zero_array(mem_ctx, const char *, num_rids);
     609        2770 :                 *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
     610             : 
     611        2770 :                 if ((*names == NULL) || (*types == NULL)) {
     612           0 :                         return false;
     613             :                 }
     614             : 
     615        5540 :                 for (i = 0; i < num_rids; i++)
     616        2770 :                         (*types)[i] = SID_NAME_UNKNOWN;
     617             :         } else {
     618           0 :                 *names = NULL;
     619           0 :                 *types = NULL;
     620             :         }
     621             : 
     622        2770 :         if (sid_check_is_our_sam(domain_sid)) {
     623             :                 NTSTATUS result;
     624             : 
     625        2295 :                 if (*domain_name == NULL) {
     626        2295 :                         *domain_name = talloc_strdup(
     627             :                                 mem_ctx, get_global_sam_name());
     628             :                 }
     629             : 
     630        2295 :                 if (*domain_name == NULL) {
     631           0 :                         return false;
     632             :                 }
     633             : 
     634        2295 :                 become_root();
     635        2295 :                 result = pdb_lookup_rids(domain_sid, num_rids, rids,
     636             :                                          *names, *types);
     637        2295 :                 unbecome_root();
     638             : 
     639        2295 :                 return (NT_STATUS_IS_OK(result) ||
     640        2295 :                         NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
     641           0 :                         NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
     642             :         }
     643             : 
     644         475 :         if (sid_check_is_builtin(domain_sid)) {
     645             : 
     646         439 :                 if (*domain_name == NULL) {
     647         439 :                         *domain_name = talloc_strdup(
     648             :                                 mem_ctx, builtin_domain_name());
     649             :                 }
     650             : 
     651         439 :                 if (*domain_name == NULL) {
     652           0 :                         return false;
     653             :                 }
     654             : 
     655         878 :                 for (i=0; i<num_rids; i++) {
     656         439 :                         if (lookup_builtin_rid(*names, rids[i],
     657         439 :                                                &(*names)[i])) {
     658         439 :                                 if ((*names)[i] == NULL) {
     659           0 :                                         return false;
     660             :                                 }
     661         439 :                                 (*types)[i] = SID_NAME_ALIAS;
     662             :                         } else {
     663           0 :                                 (*types)[i] = SID_NAME_UNKNOWN;
     664             :                         }
     665             :                 }
     666         439 :                 return true;
     667             :         }
     668             : 
     669          36 :         if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
     670           0 :                 for (i=0; i<num_rids; i++) {
     671             :                         struct dom_sid sid;
     672           0 :                         sid_compose(&sid, domain_sid, rids[i]);
     673           0 :                         if (lookup_wellknown_sid(mem_ctx, &sid,
     674           0 :                                                  domain_name, &(*names)[i])) {
     675           0 :                                 if ((*names)[i] == NULL) {
     676           0 :                                         return false;
     677             :                                 }
     678           0 :                                 (*types)[i] = SID_NAME_WKN_GRP;
     679             :                         } else {
     680           0 :                                 (*types)[i] = SID_NAME_UNKNOWN;
     681             :                         }
     682             :                 }
     683           0 :                 return true;
     684             :         }
     685             : 
     686          36 :         if (sid_check_is_unix_users(domain_sid)) {
     687          16 :                 if (*domain_name == NULL) {
     688          16 :                         *domain_name = talloc_strdup(
     689             :                                 mem_ctx, unix_users_domain_name());
     690          16 :                         if (*domain_name == NULL) {
     691           0 :                                 return false;
     692             :                         }
     693             :                 }
     694          32 :                 for (i=0; i<num_rids; i++) {
     695          16 :                         (*names)[i] = talloc_strdup(
     696          16 :                                 (*names), uidtoname(rids[i]));
     697          16 :                         if ((*names)[i] == NULL) {
     698           0 :                                 return false;
     699             :                         }
     700          16 :                         (*types)[i] = SID_NAME_USER;
     701             :                 }
     702          16 :                 return true;
     703             :         }
     704             : 
     705          20 :         if (sid_check_is_unix_groups(domain_sid)) {
     706           0 :                 if (*domain_name == NULL) {
     707           0 :                         *domain_name = talloc_strdup(
     708             :                                 mem_ctx, unix_groups_domain_name());
     709           0 :                         if (*domain_name == NULL) {
     710           0 :                                 return false;
     711             :                         }
     712             :                 }
     713           0 :                 for (i=0; i<num_rids; i++) {
     714           0 :                         (*names)[i] = talloc_strdup(
     715           0 :                                 (*names), gidtoname(rids[i]));
     716           0 :                         if ((*names)[i] == NULL) {
     717           0 :                                 return false;
     718             :                         }
     719           0 :                         (*types)[i] = SID_NAME_DOM_GRP;
     720             :                 }
     721           0 :                 return true;
     722             :         }
     723             : 
     724          20 :         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        2770 : static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
     733             :                              const char **name)
     734             : {
     735             :         const char *tmp;
     736             :         enum lsa_SidType type;
     737             : 
     738        2770 :         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        2770 :         if (sid_check_is_builtin(sid)) {
     744           0 :                 *name = talloc_strdup(mem_ctx, builtin_domain_name());
     745           0 :                 return true;
     746             :         }
     747             : 
     748        2770 :         if (sid_check_is_wellknown_domain(sid, &tmp)) {
     749           0 :                 *name = talloc_strdup(mem_ctx, tmp);
     750           0 :                 return true;
     751             :         }
     752             : 
     753        2770 :         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        2770 :         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        2770 :         if (sid->num_auths != 4) {
     764             :                 /* This can't be a domain */
     765        2770 :                 return false;
     766             :         }
     767             : 
     768           0 :         if (IS_DC) {
     769             :                 uint32_t i, num_domains;
     770             :                 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        2770 : static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
     821             : {
     822             :         struct dom_sid_buf buf;
     823        2770 :         int ret = false;
     824             : 
     825        2770 :         switch(level) {
     826        2770 :         case 1:
     827        2770 :                 ret = true;
     828        2770 :                 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        2770 :         DEBUG(10, ("%s SID %s in level %d\n",
     844             :                    ret ? "Accepting" : "Rejecting",
     845             :                    dom_sid_str_buf(sid, &buf),
     846             :                    level));
     847        2770 :         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        2770 : 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             :         TALLOC_CTX *tmp_ctx;
     866             :         NTSTATUS result;
     867             :         struct lsa_name_info *name_infos;
     868        2770 :         struct lsa_dom_info *dom_infos = NULL;
     869             : 
     870             :         int i, j;
     871             : 
     872        2770 :         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        2770 :         if (num_sids) {
     878        2770 :                 name_infos = talloc_array(mem_ctx, struct lsa_name_info, num_sids);
     879        2770 :                 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        2770 :         dom_infos = talloc_zero_array(mem_ctx, struct lsa_dom_info,
     888             :                                       LSA_REF_DOMAIN_LIST_MULTIPLIER);
     889        2770 :         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        5540 :         for (i=0; i<num_sids; i++) {
     909             :                 struct dom_sid sid;
     910        2770 :                 uint32_t rid = 0;
     911        2770 :                 const char *domain_name = NULL;
     912             : 
     913        2770 :                 sid_copy(&sid, sids[i]);
     914        2770 :                 name_infos[i].type = SID_NAME_USE_NONE;
     915             : 
     916        2770 :                 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        2770 :                         if (!sid_split_rid(&sid, &rid)) {
     946           0 :                                 result = NT_STATUS_INVALID_SID;
     947           0 :                                 goto fail;
     948             :                         }
     949             :                 }
     950             : 
     951        2770 :                 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        2770 :                 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
     959        2770 :                         if (!dom_infos[j].valid) {
     960        2770 :                                 break;
     961             :                         }
     962           0 :                         if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
     963           0 :                                 break;
     964             :                         }
     965             :                 }
     966             : 
     967        2770 :                 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        2770 :                 if (!dom_infos[j].valid) {
     974             :                         /* We found a domain not yet referenced, create a new
     975             :                          * ref. */
     976        2770 :                         dom_infos[j].valid = true;
     977        2770 :                         sid_copy(&dom_infos[j].sid, &sid);
     978             : 
     979        2770 :                         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        2770 :                                 dom_infos[j].name = NULL;
     991             :                         }
     992             :                 }
     993             : 
     994        2770 :                 name_infos[i].dom_idx = j;
     995             : 
     996        2770 :                 if (name_infos[i].type == SID_NAME_USE_NONE) {
     997        2770 :                         name_infos[i].rid = rid;
     998             : 
     999        2770 :                         ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
    1000             :                                      &dom_infos[j].num_idxs);
    1001             : 
    1002        2770 :                         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        5540 :         for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
    1012             :                 uint32_t *rids;
    1013        5540 :                 const char *domain_name = NULL;
    1014             :                 const char **names;
    1015             :                 enum lsa_SidType *types;
    1016        5540 :                 struct lsa_dom_info *dom = &dom_infos[i];
    1017             : 
    1018        5540 :                 if (!dom->valid) {
    1019             :                         /* No domains left, we're done */
    1020        2770 :                         break;
    1021             :                 }
    1022             : 
    1023        2770 :                 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        2770 :                 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        5540 :                 for (j=0; j<dom->num_idxs; j++) {
    1038        2770 :                         rids[j] = name_infos[dom->idxs[j]].rid;
    1039             :                 }
    1040             : 
    1041        2770 :                 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        2770 :                 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
    1049           0 :                         result = NT_STATUS_NO_MEMORY;
    1050           0 :                         goto fail;
    1051             :                 }
    1052             : 
    1053        5540 :                 for (j=0; j<dom->num_idxs; j++) {
    1054        2770 :                         int idx = dom->idxs[j];
    1055        2770 :                         name_infos[idx].type = types[j];
    1056        2770 :                         if (types[j] != SID_NAME_UNKNOWN) {
    1057        5500 :                                 name_infos[idx].name =
    1058        4999 :                                         talloc_strdup(name_infos, names[j]);
    1059        2750 :                                 if (name_infos[idx].name == NULL) {
    1060           0 :                                         result = NT_STATUS_NO_MEMORY;
    1061           0 :                                         goto fail;
    1062             :                                 }
    1063             :                         } else {
    1064          20 :                                 name_infos[idx].name = NULL;
    1065             :                         }
    1066             :                 }
    1067             :         }
    1068             : 
    1069        2770 :         *ret_domains = dom_infos;
    1070        2770 :         *ret_names = name_infos;
    1071        2770 :         TALLOC_FREE(tmp_ctx);
    1072        2770 :         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        2750 : 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             :         struct lsa_dom_info *domain;
    1090             :         struct lsa_name_info *name;
    1091             :         struct dom_sid_buf buf;
    1092             :         TALLOC_CTX *tmp_ctx;
    1093        2750 :         bool ret = false;
    1094             : 
    1095        2750 :         DEBUG(10, ("lookup_sid called for SID '%s'\n",
    1096             :                    dom_sid_str_buf(sid, &buf)));
    1097             : 
    1098        2750 :         if (!(tmp_ctx = talloc_new(mem_ctx))) {
    1099           0 :                 DEBUG(0, ("talloc_new failed\n"));
    1100           0 :                 return false;
    1101             :         }
    1102             : 
    1103        2750 :         if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
    1104             :                                          &domain, &name))) {
    1105           0 :                 goto done;
    1106             :         }
    1107             : 
    1108        2750 :         if (name->type == SID_NAME_UNKNOWN) {
    1109           0 :                 goto done;
    1110             :         }
    1111             : 
    1112        2750 :         if ((ret_domain != NULL) &&
    1113           0 :             !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
    1114           0 :                 goto done;
    1115             :         }
    1116             : 
    1117        2801 :         if ((ret_name != NULL) &&
    1118          58 :             !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
    1119           0 :                 goto done;
    1120             :         }
    1121             : 
    1122        2750 :         if (ret_type != NULL) {
    1123        2750 :                 *ret_type = name->type;
    1124             :         }
    1125             : 
    1126        2750 :         ret = true;
    1127             : 
    1128        2750 :  done:
    1129        2750 :         if (ret) {
    1130        2750 :                 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        2750 :         TALLOC_FREE(tmp_ctx);
    1138        2750 :         return ret;
    1139             : }
    1140             : 
    1141             : /*****************************************************************
    1142             :  *THE LEGACY* convert SID to id function.
    1143             : *****************************************************************/
    1144             : 
    1145        2910 : static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id)
    1146             : {
    1147             :         bool ret;
    1148             : 
    1149        2910 :         become_root();
    1150        2910 :         ret = pdb_sid_to_id(psid, id);
    1151        2910 :         unbecome_root();
    1152             : 
    1153        2910 :         if (!ret) {
    1154             :                 struct dom_sid_buf buf;
    1155        2434 :                 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
    1156             :                           dom_sid_str_buf(psid, &buf)));
    1157        2434 :                 return false;
    1158             :         }
    1159             : 
    1160         476 :         return true;
    1161             : }
    1162             : 
    1163        1584 : static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
    1164             : {
    1165             :         struct unixid id;
    1166        1584 :         if (!legacy_sid_to_unixid(psid, &id)) {
    1167        1209 :                 return false;
    1168             :         }
    1169         375 :         if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
    1170         313 :                 *pgid = id.id;
    1171         313 :                 return true;
    1172             :         }
    1173          62 :         return false;
    1174             : }
    1175             : 
    1176        1326 : static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
    1177             : {
    1178             :         struct unixid id;
    1179        1326 :         if (!legacy_sid_to_unixid(psid, &id)) {
    1180        1225 :                 return false;
    1181             :         }
    1182         101 :         if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) {
    1183         101 :                 *puid = id.id;
    1184         101 :                 return true;
    1185             :         }
    1186           0 :         return false;
    1187             : }
    1188             : 
    1189       39690 : void xid_to_sid(struct dom_sid *psid, const struct unixid *xid)
    1190             : {
    1191       39690 :         bool expired = true;
    1192             :         bool ret;
    1193             :         struct dom_sid_buf buf;
    1194             : 
    1195       39690 :         SMB_ASSERT(xid->type == ID_TYPE_UID || xid->type == ID_TYPE_GID);
    1196             : 
    1197       39690 :         *psid = (struct dom_sid) {0};
    1198             : 
    1199       39690 :         ret = idmap_cache_find_xid2sid(xid, psid, &expired);
    1200       39690 :         if (ret && !expired) {
    1201       34975 :                 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       34975 :                 goto done;
    1206             :         }
    1207             : 
    1208        4715 :         ret = winbind_xid_to_sid(psid, xid);
    1209        4715 :         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        3682 :                 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        3682 :                 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        1033 :                 struct unixid rw_xid = *xid;
    1229             : 
    1230        1033 :                 become_root();
    1231        1033 :                 ret = pdb_id_to_sid(&rw_xid, psid);
    1232        1033 :                 unbecome_root();
    1233             :         }
    1234             : 
    1235        1033 :         if (ret) {
    1236         119 :                 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         119 :                 goto done;
    1241             :         }
    1242             : 
    1243       31340 : done:
    1244       39690 :         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        6063 :                 if (xid->type == ID_TYPE_UID) {
    1251          12 :                         uid_to_unix_users_sid(xid->id, psid);
    1252             :                 } else {
    1253        6051 :                         gid_to_unix_groups_sid(xid->id, psid);
    1254             :                 }
    1255             : 
    1256        6063 :                 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       39690 : }
    1262             : 
    1263       16998 : void uid_to_sid(struct dom_sid *psid, uid_t uid)
    1264             : {
    1265       16998 :         struct unixid xid = { .type = ID_TYPE_UID, .id = uid};
    1266       16998 :         xid_to_sid(psid, &xid);
    1267       16998 : }
    1268             : 
    1269       22692 : void gid_to_sid(struct dom_sid *psid, gid_t gid)
    1270             : {
    1271       22692 :         struct unixid xid = { .type = ID_TYPE_GID, .id = gid};
    1272       22692 :         xid_to_sid(psid, &xid);
    1273       22692 : }
    1274             : 
    1275        6194 : bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
    1276             :                      struct unixid *ids)
    1277             : {
    1278        6194 :         struct wbcDomainSid *wbc_sids = NULL;
    1279        6194 :         struct wbcUnixId *wbc_ids = NULL;
    1280        6194 :         struct bitmap *found = NULL;
    1281             :         uint32_t i, num_not_cached;
    1282        6194 :         uint32_t wbc_ids_size = 0;
    1283             :         wbcErr err;
    1284        6194 :         bool ret = false;
    1285             : 
    1286        6194 :         wbc_sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_sids);
    1287        6194 :         if (wbc_sids == NULL) {
    1288           0 :                 return false;
    1289             :         }
    1290        6194 :         found = bitmap_talloc(wbc_sids, num_sids);
    1291        6194 :         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        6194 :         num_not_cached = 0;
    1306             : 
    1307       25410 :         for (i=0; i<num_sids; i++) {
    1308             :                 bool expired;
    1309             :                 uint32_t rid;
    1310             : 
    1311       19216 :                 if (sid_peek_check_rid(&global_sid_Unix_Users,
    1312       19216 :                                        &sids[i], &rid)) {
    1313          44 :                         ids[i].type = ID_TYPE_UID;
    1314          44 :                         ids[i].id = rid;
    1315          44 :                         bitmap_set(found, i);
    1316       17290 :                         continue;
    1317             :                 }
    1318       19172 :                 if (sid_peek_check_rid(&global_sid_Unix_Groups,
    1319       19172 :                                        &sids[i], &rid)) {
    1320        1483 :                         ids[i].type = ID_TYPE_GID;
    1321        1483 :                         ids[i].id = rid;
    1322        1483 :                         bitmap_set(found, i);
    1323        1483 :                         continue;
    1324             :                 }
    1325       17689 :                 if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
    1326       15739 :                     && !expired)
    1327             :                 {
    1328       15739 :                         bitmap_set(found, i);
    1329       15739 :                         continue;
    1330             :                 }
    1331        1950 :                 ids[i].type = ID_TYPE_NOT_SPECIFIED;
    1332        2562 :                 memcpy(&wbc_sids[num_not_cached], &sids[i],
    1333        1950 :                        ndr_size_dom_sid(&sids[i], 0));
    1334        1950 :                 num_not_cached += 1;
    1335             :         }
    1336        6194 :         if (num_not_cached == 0) {
    1337        4935 :                 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        1259 :         wbc_ids_size = num_not_cached;
    1346        1259 :         wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, wbc_ids_size);
    1347        1259 :         if (wbc_ids == NULL) {
    1348           0 :                 goto fail;
    1349             :         }
    1350        3209 :         for (i=0; i<wbc_ids_size; i++) {
    1351        1950 :                 wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
    1352        1950 :                 wbc_ids[i].id.gid = (uint32_t)-1;
    1353             :         }
    1354        1259 :         err = wbcSidsToUnixIds(wbc_sids, wbc_ids_size, wbc_ids);
    1355        1259 :         if (!WBC_ERROR_IS_OK(err)) {
    1356         905 :                 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        1259 :         num_not_cached = 0;
    1370             : 
    1371        9680 :         for (i=0; i<num_sids; i++) {
    1372        8421 :                 if (bitmap_query(found, i)) {
    1373        6471 :                         continue;
    1374             :                 }
    1375             : 
    1376        1950 :                 SMB_ASSERT(num_not_cached < wbc_ids_size);
    1377             : 
    1378        1950 :                 switch (wbc_ids[num_not_cached].type) {
    1379           1 :                 case WBC_ID_TYPE_UID:
    1380           1 :                         ids[i].type = ID_TYPE_UID;
    1381           1 :                         ids[i].id = wbc_ids[num_not_cached].id.uid;
    1382           1 :                         bitmap_set(found, i);
    1383           1 :                         break;
    1384          81 :                 case WBC_ID_TYPE_GID:
    1385          81 :                         ids[i].type = ID_TYPE_GID;
    1386          81 :                         ids[i].id = wbc_ids[num_not_cached].id.gid;
    1387          81 :                         bitmap_set(found, i);
    1388          81 :                         break;
    1389         327 :                 case WBC_ID_TYPE_BOTH:
    1390         327 :                         ids[i].type = ID_TYPE_BOTH;
    1391         327 :                         ids[i].id = wbc_ids[num_not_cached].id.uid;
    1392         327 :                         bitmap_set(found, i);
    1393         327 :                         break;
    1394        1541 :                 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        1541 :                         ids[i].type = ID_TYPE_NOT_SPECIFIED;
    1403        1541 :                         ids[i].id = (uint32_t)-1;
    1404        1541 :                         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             :                         break;
    1413             :                 }
    1414        1950 :                 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        9680 :         for (i=0; i<num_sids; i++) {
    1428        8421 :                 if (bitmap_query(found, i)) {
    1429        6880 :                         continue;
    1430             :                 }
    1431        1541 :                 if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
    1432         280 :                         ids[i].type = ID_TYPE_GID;
    1433         280 :                         bitmap_set(found, i);
    1434         280 :                         continue;
    1435             :                 }
    1436        1261 :                 if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
    1437          62 :                         ids[i].type = ID_TYPE_UID;
    1438          62 :                         bitmap_set(found, i);
    1439          62 :                         continue;
    1440             :                 }
    1441             :         }
    1442        1259 : 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       25410 :         for (i=0; i<num_sids; i++) {
    1449       19216 :                 switch(ids[i].type) {
    1450       17949 :                 case ID_TYPE_GID:
    1451             :                 case ID_TYPE_UID:
    1452             :                 case ID_TYPE_BOTH:
    1453       17949 :                         if (ids[i].id == (uint32_t)-1) {
    1454           0 :                                 ids[i].type = ID_TYPE_NOT_SPECIFIED;
    1455             :                         }
    1456       17949 :                         break;
    1457        1267 :                 case ID_TYPE_NOT_SPECIFIED:
    1458        1267 :                         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             :                         break;
    1466             :                 }
    1467             :         }
    1468             : 
    1469        6194 :         ret = true;
    1470        6194 : fail:
    1471        6194 :         TALLOC_FREE(wbc_ids);
    1472        6194 :         TALLOC_FREE(wbc_sids);
    1473        6194 :         return ret;
    1474             : }
    1475             : 
    1476             : /*****************************************************************
    1477             :  *THE CANONICAL* convert SID to uid function.
    1478             : *****************************************************************/
    1479             : 
    1480        4378 : bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
    1481             : {
    1482        4378 :         bool expired = true;
    1483             :         bool ret;
    1484             :         uint32_t rid;
    1485             :         struct dom_sid_buf buf;
    1486             : 
    1487             :         /* Optimize for the Unix Users Domain
    1488             :          * as the conversion is straightforward */
    1489        4378 :         if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
    1490         124 :                 uid_t uid = rid;
    1491         124 :                 *puid = uid;
    1492             : 
    1493             :                 /* return here, don't cache */
    1494         124 :                 DEBUG(10,("sid %s -> uid %u\n",
    1495             :                           dom_sid_str_buf(psid, &buf),
    1496             :                           (unsigned int)*puid ));
    1497         124 :                 return true;
    1498             :         }
    1499             : 
    1500        4254 :         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        4254 :         ret = idmap_cache_find_sid2uid(psid, puid, &expired);
    1508             : 
    1509        4254 :         if (ret && !expired && (*puid == (uid_t)-1)) {
    1510             :                 /*
    1511             :                  * Negative cache entry, we already asked.
    1512             :                  * do legacy.
    1513             :                  */
    1514          20 :                 return legacy_sid_to_uid(psid, puid);
    1515             :         }
    1516             : 
    1517        4234 :         if (!ret || expired) {
    1518             :                 /* Not in cache. Ask winbindd. */
    1519         948 :                 if (!winbind_sid_to_uid(puid, psid)) {
    1520          45 :                         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          45 :                         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        4189 :         DEBUG(10,("sid %s -> uid %u\n",
    1531             :                   dom_sid_str_buf(psid, &buf),
    1532             :                 (unsigned int)*puid ));
    1533             : 
    1534        4189 :         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        2427 : bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
    1543             : {
    1544        2427 :         bool expired = true;
    1545             :         bool ret;
    1546             :         uint32_t rid;
    1547             :         struct dom_sid_buf buf;
    1548             : 
    1549             :         /* Optimize for the Unix Groups Domain
    1550             :          * as the conversion is straightforward */
    1551        2427 :         if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
    1552          42 :                 gid_t gid = rid;
    1553          42 :                 *pgid = gid;
    1554             : 
    1555             :                 /* return here, don't cache */
    1556          42 :                 DEBUG(10,("sid %s -> gid %u\n",
    1557             :                           dom_sid_str_buf(psid, &buf),
    1558             :                         (unsigned int)*pgid ));
    1559          42 :                 return true;
    1560             :         }
    1561             : 
    1562        2385 :         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        2385 :         ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
    1570             : 
    1571        2385 :         if (ret && !expired && (*pgid == (gid_t)-1)) {
    1572             :                 /*
    1573             :                  * Negative cache entry, we already asked.
    1574             :                  * do legacy.
    1575             :                  */
    1576           6 :                 return legacy_sid_to_gid(psid, pgid);
    1577             :         }
    1578             : 
    1579        2379 :         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         301 :                 if ( !winbind_sid_to_gid(pgid, psid) ) {
    1585             : 
    1586          37 :                         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          37 :                         return legacy_sid_to_gid(psid, pgid);
    1590             :                 }
    1591             :         }
    1592             : 
    1593        2342 :         DEBUG(10,("sid %s -> gid %u\n",
    1594             :                   dom_sid_str_buf(psid, &buf),
    1595             :                   (unsigned int)*pgid ));
    1596             : 
    1597        2342 :         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        1733 : 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             :         TALLOC_CTX *tmp_ctx;
    1630        1733 :         bool need_lookup_sid = false;
    1631             :         struct dom_sid *group_sid;
    1632        1733 :         struct passwd *pwd = *_pwd;
    1633             : 
    1634        1733 :         tmp_ctx = talloc_new(mem_ctx);
    1635        1733 :         if (!tmp_ctx) {
    1636           0 :                 return NT_STATUS_NO_MEMORY;
    1637             :         }
    1638             : 
    1639        1733 :         if (!pwd) {
    1640        1440 :                 pwd = Get_Pwnam_alloc(mem_ctx, username);
    1641        1440 :                 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        1733 :         group_sid = talloc_zero(mem_ctx, struct dom_sid);
    1650        1733 :         if (!group_sid) {
    1651           0 :                 TALLOC_FREE(tmp_ctx);
    1652           0 :                 return NT_STATUS_NO_MEMORY;
    1653             :         }
    1654             : 
    1655        1733 :         gid_to_sid(group_sid, pwd->pw_gid);
    1656        1733 :         if (!is_null_sid(group_sid)) {
    1657             :                 struct dom_sid domain_sid;
    1658             :                 uint32_t rid;
    1659             : 
    1660             :                 /* We need a sid within our domain */
    1661        1733 :                 sid_copy(&domain_sid, group_sid);
    1662        1733 :                 sid_split_rid(&domain_sid, &rid);
    1663        1733 :                 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          14 :                         switch (rid) {
    1669          14 :                         case DOMAIN_RID_ADMINS:
    1670             :                         case DOMAIN_RID_USERS:
    1671          14 :                                 goto done;
    1672           0 :                         default:
    1673           0 :                                 need_lookup_sid = true;
    1674           0 :                                 break;
    1675             :                         }
    1676             :                 } else {
    1677             :                         /* Try group mapping */
    1678             :                         struct unixid id;
    1679             : 
    1680        1719 :                         id.id = pwd->pw_gid;
    1681        1719 :                         id.type = ID_TYPE_GID;
    1682             : 
    1683        1719 :                         ZERO_STRUCTP(group_sid);
    1684        1719 :                         if (pdb_id_to_sid(&id, group_sid)) {
    1685           0 :                                 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        1719 :         if (need_lookup_sid) {
    1693           0 :                 enum lsa_SidType type = SID_NAME_UNKNOWN;
    1694             :                 bool lookup_ret;
    1695             :                 struct dom_sid_buf buf;
    1696             : 
    1697           0 :                 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           0 :                 lookup_ret = lookup_sid(tmp_ctx, group_sid,
    1704             :                                         NULL, NULL, &type);
    1705             : 
    1706           0 :                 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
    1707           0 :                         goto done;
    1708             :                 }
    1709             : 
    1710           0 :                 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        1719 :         DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
    1721             :                   username));
    1722             : 
    1723        1719 :         sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
    1724             : 
    1725        1733 : done:
    1726        1733 :         *_pwd = talloc_move(mem_ctx, &pwd);
    1727        1733 :         *_group_sid = talloc_move(mem_ctx, &group_sid);
    1728        1733 :         TALLOC_FREE(tmp_ctx);
    1729        1733 :         return NT_STATUS_OK;
    1730             : }
    1731             : 

Generated by: LCOV version 1.13