LCOV - code coverage report
Current view: top level - libcli/security - util_sid.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 196 250 78.4 %
Date: 2024-02-28 12:06:22 Functions: 21 21 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             :    Copyright (C) Andrew Tridgell                1992-1998
       5             :    Copyright (C) Luke Kenneth Caseson Leighton  1998-1999
       6             :    Copyright (C) Jeremy Allison                 1999
       7             :    Copyright (C) Stefan (metze) Metzmacher      2002
       8             :    Copyright (C) Simo Sorce                     2002
       9             :    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
      10             :    Copyright (C) Andrew Bartlett                2010
      11             : 
      12             :    This program is free software; you can redistribute it and/or modify
      13             :    it under the terms of the GNU General Public License as published by
      14             :    the Free Software Foundation; either version 3 of the License, or
      15             :    (at your option) any later version.
      16             : 
      17             :    This program is distributed in the hope that it will be useful,
      18             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             :    GNU General Public License for more details.
      21             : 
      22             :    You should have received a copy of the GNU General Public License
      23             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24             : */
      25             : 
      26             : #include "replace.h"
      27             : #include "lib/util/samba_util.h"
      28             : #include "../librpc/gen_ndr/ndr_security.h"
      29             : #include "../librpc/gen_ndr/netlogon.h"
      30             : #include "../libcli/security/security.h"
      31             : #include "auth/auth.h"
      32             : 
      33             : 
      34             : #undef strcasecmp
      35             : #undef strncasecmp
      36             : 
      37             : /*
      38             :  * Some useful sids, more well known sids can be found at
      39             :  * http://support.microsoft.com/kb/243330/EN-US/
      40             :  */
      41             : 
      42             : 
      43             : /* S-1-1 */
      44             : const struct dom_sid global_sid_World_Domain =               /* Everyone domain */
      45             : { 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      46             : /* S-1-1-0 */
      47             : const struct dom_sid global_sid_World =                      /* Everyone */
      48             : { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      49             : /* S-1-2 */
      50             : const struct dom_sid global_sid_Local_Authority =            /* Local Authority */
      51             : { 1, 0, {0,0,0,0,0,2}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      52             : /* S-1-3 */
      53             : const struct dom_sid global_sid_Creator_Owner_Domain =       /* Creator Owner domain */
      54             : { 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      55             : /* S-1-5 */
      56             : const struct dom_sid global_sid_NT_Authority =                  /* NT Authority */
      57             : { 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      58             : /* S-1-5-18 */
      59             : const struct dom_sid global_sid_System =                        /* System */
      60             : { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      61             : /* S-1-0-0 */
      62             : const struct dom_sid global_sid_NULL =                          /* NULL sid */
      63             : { 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      64             : /* S-1-5-10 */
      65             : const struct dom_sid global_sid_Self =                          /* SELF */
      66             : { 1, 1, {0,0,0,0,0,5}, {10,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      67             : /* S-1-5-11 */
      68             : const struct dom_sid global_sid_Authenticated_Users =   /* All authenticated rids */
      69             : { 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      70             : #if 0
      71             : /* for documentation S-1-5-12 */
      72             : const struct dom_sid global_sid_Restricted =                    /* Restricted Code */
      73             : { 1, 1, {0,0,0,0,0,5}, {12,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      74             : #endif
      75             : 
      76             : /* S-1-18 */
      77             : const struct dom_sid global_sid_Asserted_Identity =       /* Asserted Identity */
      78             : { 1, 0, {0,0,0,0,0,18}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      79             : /* S-1-18-1 */
      80             : const struct dom_sid global_sid_Asserted_Identity_Authentication_Authority =    /* Asserted Identity Authentication Authority */
      81             : { 1, 1, {0,0,0,0,0,18}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      82             : /* S-1-18-2 */
      83             : const struct dom_sid global_sid_Asserted_Identity_Service =     /* Asserted Identity Service */
      84             : { 1, 1, {0,0,0,0,0,18}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      85             : 
      86             : /* S-1-18-3 */
      87             : const struct dom_sid global_sid_Fresh_Public_Key_Identity =     /* Fresh Public Key Identity */
      88             : { 1, 1, {0,0,0,0,0,18}, {3,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      89             : 
      90             : /* S-1-5-2 */
      91             : const struct dom_sid global_sid_Network =                       /* Network rids */
      92             : { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      93             : 
      94             : /* S-1-3 */
      95             : const struct dom_sid global_sid_Creator_Owner =         /* Creator Owner */
      96             : { 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      97             : /* S-1-3-1 */
      98             : const struct dom_sid global_sid_Creator_Group =         /* Creator Group */
      99             : { 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     100             : /* S-1-3-4 */
     101             : const struct dom_sid global_sid_Owner_Rights =          /* Owner Rights */
     102             : { 1, 1, {0,0,0,0,0,3}, {4,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     103             : /* S-1-5-7 */
     104             : const struct dom_sid global_sid_Anonymous =                     /* Anonymous login */
     105             : { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     106             : /* S-1-5-9 */
     107             : const struct dom_sid global_sid_Enterprise_DCs =                /* Enterprise DCs */
     108             : { 1, 1, {0,0,0,0,0,5}, {9,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     109             : /* S-1-5-21-0-0-0-496 */
     110             : const struct dom_sid global_sid_Compounded_Authentication =     /* Compounded Authentication */
     111             : {1, 5, {0,0,0,0,0,5}, {21,0,0,0,496,0,0,0,0,0,0,0,0,0,0}};
     112             : /* S-1-5-21-0-0-0-497 */
     113             : const struct dom_sid global_sid_Claims_Valid =          /* Claims Valid */
     114             : {1, 5, {0,0,0,0,0,5}, {21,0,0,0,497,0,0,0,0,0,0,0,0,0,0}};
     115             : /* S-1-5-32 */
     116             : const struct dom_sid global_sid_Builtin =                       /* Local well-known domain */
     117             : { 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     118             : /* S-1-5-32-544 */
     119             : const struct dom_sid global_sid_Builtin_Administrators =        /* Builtin administrators */
     120             : { 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     121             : /* S-1-5-32-545 */
     122             : const struct dom_sid global_sid_Builtin_Users =         /* Builtin users */
     123             : { 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     124             : /* S-1-5-32-546 */
     125             : const struct dom_sid global_sid_Builtin_Guests =                /* Builtin guest users */
     126             : { 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     127             : /* S-1-5-32-547 */
     128             : const struct dom_sid global_sid_Builtin_Power_Users =   /* Builtin power users */
     129             : { 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     130             : /* S-1-5-32-548 */
     131             : const struct dom_sid global_sid_Builtin_Account_Operators =     /* Builtin account operators */
     132             : { 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     133             : /* S-1-5-32-549 */
     134             : const struct dom_sid global_sid_Builtin_Server_Operators =      /* Builtin server operators */
     135             : { 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     136             : /* S-1-5-32-550 */
     137             : const struct dom_sid global_sid_Builtin_Print_Operators =       /* Builtin print operators */
     138             : { 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     139             : /* S-1-5-32-551 */
     140             : const struct dom_sid global_sid_Builtin_Backup_Operators =      /* Builtin backup operators */
     141             : { 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     142             : /* S-1-5-32-552 */
     143             : const struct dom_sid global_sid_Builtin_Replicator =            /* Builtin replicator */
     144             : { 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     145             : /* S-1-5-32-554 */
     146             : const struct dom_sid global_sid_Builtin_PreWin2kAccess =        /* Builtin pre win2k access */
     147             : { 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     148             : 
     149             : /* S-1-22-1 */
     150             : const struct dom_sid global_sid_Unix_Users =                    /* Unmapped Unix users */
     151             : { 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     152             : /* S-1-22-2 */
     153             : const struct dom_sid global_sid_Unix_Groups =                   /* Unmapped Unix groups */
     154             : { 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     155             : 
     156             : /*
     157             :  * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
     158             :  */
     159             : /* S-1-5-88 */
     160             : const struct dom_sid global_sid_Unix_NFS =             /* MS NFS and Apple style */
     161             : { 1, 1, {0,0,0,0,0,5}, {88,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     162             : /* S-1-5-88-1 */
     163             : const struct dom_sid global_sid_Unix_NFS_Users =                /* Unix uid, MS NFS and Apple style */
     164             : { 1, 2, {0,0,0,0,0,5}, {88,1,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     165             : /* S-1-5-88-2 */
     166             : const struct dom_sid global_sid_Unix_NFS_Groups =               /* Unix gid, MS NFS and Apple style */
     167             : { 1, 2, {0,0,0,0,0,5}, {88,2,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     168             : /* S-1-5-88-3 */
     169             : const struct dom_sid global_sid_Unix_NFS_Mode =                 /* Unix mode */
     170             : { 1, 2, {0,0,0,0,0,5}, {88,3,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     171             : /* Unused, left here for documentary purposes */
     172             : #if 0
     173             : const struct dom_sid global_sid_Unix_NFS_Other =                /* Unix other, MS NFS and Apple style */
     174             : { 1, 2, {0,0,0,0,0,5}, {88,4,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     175             : #endif
     176             : 
     177             : /* Information passing via security token */
     178             : const struct dom_sid global_sid_Samba_SMB3 =
     179             : {1, 1, {0,0,0,0,0,22}, {1397571891, }};
     180             : 
     181             : const struct dom_sid global_sid_Samba_NPA_Flags = {1,
     182             :                                                    1,
     183             :                                                    {0, 0, 0, 0, 0, 22},
     184             :                                                    {
     185             :                                                            2041152804,
     186             :                                                    }};
     187             : 
     188             : /* Unused, left here for documentary purposes */
     189             : #if 0
     190             : #define SECURITY_NULL_SID_AUTHORITY    0
     191             : #define SECURITY_WORLD_SID_AUTHORITY   1
     192             : #define SECURITY_LOCAL_SID_AUTHORITY   2
     193             : #define SECURITY_CREATOR_SID_AUTHORITY 3
     194             : #define SECURITY_NT_AUTHORITY          5
     195             : #endif
     196             : 
     197             : static struct dom_sid system_sid_array[1] =
     198             : { { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
     199             : static const struct security_token system_token = {
     200             :         .num_sids       = ARRAY_SIZE(system_sid_array),
     201             :         .sids           = system_sid_array,
     202             :         .privilege_mask = SE_ALL_PRIVS
     203             : };
     204             : 
     205             : /****************************************************************************
     206             :  Lookup string names for SID types.
     207             : ****************************************************************************/
     208             : 
     209          86 : const char *sid_type_lookup(uint32_t sid_type)
     210             : {
     211          86 :         switch (sid_type) {
     212           0 :         case SID_NAME_USE_NONE:
     213           0 :                 return "None";
     214           0 :                 break;
     215          44 :         case SID_NAME_USER:
     216          44 :                 return "User";
     217           0 :                 break;
     218           0 :         case SID_NAME_DOM_GRP:
     219           0 :                 return "Domain Group";
     220           0 :                 break;
     221          38 :         case SID_NAME_DOMAIN:
     222          38 :                 return "Domain";
     223           0 :                 break;
     224           0 :         case SID_NAME_ALIAS:
     225           0 :                 return "Local Group";
     226           0 :                 break;
     227           4 :         case SID_NAME_WKN_GRP:
     228           4 :                 return "Well-known Group";
     229           0 :                 break;
     230           0 :         case SID_NAME_DELETED:
     231           0 :                 return "Deleted Account";
     232           0 :                 break;
     233           0 :         case SID_NAME_INVALID:
     234           0 :                 return "Invalid Account";
     235           0 :                 break;
     236           0 :         case SID_NAME_UNKNOWN:
     237           0 :                 return "UNKNOWN";
     238           0 :                 break;
     239           0 :         case SID_NAME_COMPUTER:
     240           0 :                 return "Computer";
     241           0 :                 break;
     242           0 :         case SID_NAME_LABEL:
     243           0 :                 return "Mandatory Label";
     244           0 :                 break;
     245             :         }
     246             : 
     247             :         /* Default return */
     248           0 :         return "SID *TYPE* is INVALID";
     249             : }
     250             : 
     251             : /**************************************************************************
     252             :  Create the SYSTEM token.
     253             : ***************************************************************************/
     254             : 
     255          14 : const struct security_token *get_system_token(void)
     256             : {
     257          14 :         return &system_token;
     258             : }
     259             : 
     260     1066523 : bool sid_compose(struct dom_sid *dst, const struct dom_sid *domain_sid, uint32_t rid)
     261             : {
     262     1066523 :         sid_copy(dst, domain_sid);
     263     1066523 :         return sid_append_rid(dst, rid);
     264             : }
     265             : 
     266             : /*****************************************************************
     267             :  Removes the last rid from the end of a sid
     268             : *****************************************************************/
     269             : 
     270     1554432 : bool sid_split_rid(struct dom_sid *sid, uint32_t *rid)
     271             : {
     272     1554432 :         if (sid->num_auths > 0) {
     273     1554422 :                 sid->num_auths--;
     274     1554422 :                 if (rid != NULL) {
     275      421841 :                         *rid = sid->sub_auths[sid->num_auths];
     276             :                 }
     277     1554422 :                 return true;
     278             :         }
     279          10 :         return false;
     280             : }
     281             : 
     282             : /*****************************************************************
     283             :  Return the last rid from the end of a sid
     284             : *****************************************************************/
     285             : 
     286      372588 : bool sid_peek_rid(const struct dom_sid *sid, uint32_t *rid)
     287             : {
     288      372588 :         if (!sid || !rid)
     289           0 :                 return false;
     290             : 
     291      372588 :         if (sid->num_auths > 0) {
     292      372588 :                 *rid = sid->sub_auths[sid->num_auths - 1];
     293      372588 :                 return true;
     294             :         }
     295           0 :         return false;
     296             : }
     297             : 
     298             : /*****************************************************************
     299             :  Return the last rid from the end of a sid
     300             :  and check the sid against the exp_dom_sid
     301             : *****************************************************************/
     302             : 
     303     1911171 : bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, const struct dom_sid *sid, uint32_t *rid)
     304             : {
     305     1911171 :         if (!exp_dom_sid || !sid || !rid)
     306           0 :                 return false;
     307             : 
     308     1911171 :         if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
     309     1221082 :                 return false;
     310             :         }
     311             : 
     312      688452 :         if (dom_sid_compare_domain(exp_dom_sid, sid)!=0){
     313      450455 :                 *rid=(-1);
     314      450455 :                 return false;
     315             :         }
     316             : 
     317      237997 :         return sid_peek_rid(sid, rid);
     318             : }
     319             : 
     320             : /*****************************************************************
     321             :  Copies a sid
     322             : *****************************************************************/
     323             : 
     324    19303980 : void sid_copy(struct dom_sid *dst, const struct dom_sid *src)
     325             : {
     326     1006346 :         int i;
     327             : 
     328    19303980 :         *dst = (struct dom_sid) {
     329    19303980 :                 .sid_rev_num = src->sid_rev_num,
     330    19303980 :                 .num_auths = src->num_auths,
     331             :         };
     332             : 
     333    19303980 :         memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
     334             : 
     335    95149604 :         for (i = 0; i < src->num_auths; i++)
     336    75845624 :                 dst->sub_auths[i] = src->sub_auths[i];
     337    19303980 : }
     338             : 
     339             : /*****************************************************************
     340             :  Parse a on-the-wire SID to a struct dom_sid.
     341             : *****************************************************************/
     342             : 
     343     5304231 : ssize_t sid_parse(const uint8_t *inbuf, size_t len, struct dom_sid *sid)
     344             : {
     345     5304231 :         DATA_BLOB in = data_blob_const(inbuf, len);
     346       72323 :         enum ndr_err_code ndr_err;
     347             : 
     348     5304231 :         ndr_err = ndr_pull_struct_blob_all(
     349             :                 &in, NULL, sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
     350     5304231 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     351           0 :                 return -1;
     352             :         }
     353     5304229 :         return ndr_size_dom_sid(sid, 0);
     354             : }
     355             : 
     356             : /********************************************************************
     357             :  Add SID to an array of SIDs
     358             : ********************************************************************/
     359             : 
     360      382207 : NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
     361             :                           struct dom_sid **sids, uint32_t *num)
     362             : {
     363         742 :         struct dom_sid *tmp;
     364             : 
     365      382207 :         if ((*num) == UINT32_MAX) {
     366           0 :                 return NT_STATUS_INTEGER_OVERFLOW;
     367             :         }
     368             : 
     369      382207 :         tmp = talloc_realloc(mem_ctx, *sids, struct dom_sid, (*num)+1);
     370      382207 :         if (tmp == NULL) {
     371           0 :                 *num = 0;
     372           0 :                 return NT_STATUS_NO_MEMORY;
     373             :         }
     374      382207 :         *sids = tmp;
     375             : 
     376      382207 :         sid_copy(&((*sids)[*num]), sid);
     377      382207 :         *num += 1;
     378             : 
     379      382207 :         return NT_STATUS_OK;
     380             : }
     381             : 
     382             : 
     383             : /********************************************************************
     384             :  Add SID to an array of SIDs ensuring that it is not already there
     385             : ********************************************************************/
     386             : 
     387      424275 : NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
     388             :                                  struct dom_sid **sids, uint32_t *num_sids)
     389             : {
     390         620 :         bool contains;
     391             : 
     392      424275 :         contains = sids_contains_sid(*sids, *num_sids, sid);
     393      424275 :         if (contains) {
     394      134687 :                 return NT_STATUS_OK;
     395             :         }
     396             : 
     397      289588 :         return add_sid_to_array(mem_ctx, sid, sids, num_sids);
     398             : }
     399             : 
     400             : /**
     401             :  * Appends a SID and attribute to an array of auth_SidAttr.
     402             :  *
     403             :  * @param [in] mem_ctx  Talloc memory context on which to allocate the array.
     404             :  * @param [in] sid      The SID to append.
     405             :  * @param [in] attrs    SE_GROUP_* flags to go with the SID.
     406             :  * @param [inout] sids  A pointer to the auth_SidAttr array.
     407             :  * @param [inout] num   A pointer to the size of the auth_SidArray array.
     408             :  * @returns NT_STATUS_OK on success.
     409             :  */
     410       65385 : NTSTATUS add_sid_to_array_attrs(TALLOC_CTX *mem_ctx,
     411             :                                 const struct dom_sid *sid, uint32_t attrs,
     412             :                                 struct auth_SidAttr **sids, uint32_t *num)
     413             : {
     414       65385 :         struct auth_SidAttr *tmp = NULL;
     415             : 
     416       65385 :         if ((*num) == UINT32_MAX) {
     417           0 :                 return NT_STATUS_INTEGER_OVERFLOW;
     418             :         }
     419             : 
     420       65385 :         tmp = talloc_realloc(mem_ctx, *sids, struct auth_SidAttr, (*num)+1);
     421       65385 :         if (tmp == NULL) {
     422           0 :                 *num = 0;
     423           0 :                 return NT_STATUS_NO_MEMORY;
     424             :         }
     425       65385 :         *sids = tmp;
     426             : 
     427       65385 :         sid_copy(&((*sids)[*num].sid), sid);
     428       65385 :         (*sids)[*num].attrs = attrs;
     429       65385 :         *num += 1;
     430             : 
     431       65385 :         return NT_STATUS_OK;
     432             : }
     433             : 
     434             : 
     435             : /**
     436             :  * Appends a SID and attribute to an array of auth_SidAttr,
     437             :  * ensuring that it is not already there.
     438             :  *
     439             :  * @param [in] mem_ctx  Talloc memory context on which to allocate the array.
     440             :  * @param [in] sid      The SID to append.
     441             :  * @param [in] attrs    SE_GROUP_* flags to go with the SID.
     442             :  * @param [inout] sids  A pointer to the auth_SidAttr array.
     443             :  * @param [inout] num_sids      A pointer to the size of the auth_SidArray array.
     444             :  * @returns NT_STATUS_OK on success.
     445             :  */
     446       65385 : NTSTATUS add_sid_to_array_attrs_unique(TALLOC_CTX *mem_ctx,
     447             :                                        const struct dom_sid *sid, uint32_t attrs,
     448             :                                        struct auth_SidAttr **sids, uint32_t *num_sids)
     449             : {
     450        2340 :         bool contains;
     451             : 
     452       65385 :         contains = sids_contains_sid_attrs(*sids, *num_sids, sid, attrs);
     453       65385 :         if (contains) {
     454           0 :                 return NT_STATUS_OK;
     455             :         }
     456             : 
     457       65385 :         return add_sid_to_array_attrs(mem_ctx, sid, attrs, sids, num_sids);
     458             : }
     459             : 
     460             : /********************************************************************
     461             :  Remove SID from an array
     462             : ********************************************************************/
     463             : 
     464       44323 : void del_sid_from_array(const struct dom_sid *sid, struct dom_sid **sids,
     465             :                         uint32_t *num)
     466             : {
     467       44323 :         struct dom_sid *sid_list = *sids;
     468           0 :         uint32_t i;
     469             : 
     470      224216 :         for ( i=0; i<*num; i++ ) {
     471             : 
     472             :                 /* if we find the SID, then decrement the count
     473             :                    and break out of the loop */
     474             : 
     475      224216 :                 if (dom_sid_equal(sid, &sid_list[i])) {
     476       44323 :                         *num -= 1;
     477       44323 :                         break;
     478             :                 }
     479             :         }
     480             : 
     481             :         /* This loop will copy the remainder of the array
     482             :            if i < num of sids in the array */
     483             : 
     484       44323 :         for ( ; i<*num; i++ ) {
     485           0 :                 sid_copy( &sid_list[i], &sid_list[i+1] );
     486             :         }
     487       44323 : }
     488             : 
     489           1 : bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
     490             :                              uint32_t rid, uint32_t **pp_rids, size_t *p_num)
     491             : {
     492           0 :         size_t i;
     493             : 
     494           1 :         for (i=0; i<*p_num; i++) {
     495           0 :                 if ((*pp_rids)[i] == rid)
     496           0 :                         return true;
     497             :         }
     498             : 
     499           1 :         *pp_rids = talloc_realloc(mem_ctx, *pp_rids, uint32_t, *p_num+1);
     500             : 
     501           1 :         if (*pp_rids == NULL) {
     502           0 :                 *p_num = 0;
     503           0 :                 return false;
     504             :         }
     505             : 
     506           1 :         (*pp_rids)[*p_num] = rid;
     507           1 :         *p_num += 1;
     508           1 :         return true;
     509             : }
     510             : 
     511     1920226 : bool is_null_sid(const struct dom_sid *sid)
     512             : {
     513        6562 :         static const struct dom_sid null_sid = {0};
     514     1920226 :         return dom_sid_equal(sid, &null_sid);
     515             : }
     516             : 
     517             : /**
     518             :  * Return true if an array of SIDs contains a certain SID.
     519             :  *
     520             :  * @param [in] sids     The SID array.
     521             :  * @param [in] num_sids The size of the SID array.
     522             :  * @param [in] sid      The SID in question.
     523             :  * @returns true if the array contains the SID.
     524             :  */
     525      424275 : bool sids_contains_sid(const struct dom_sid *sids,
     526             :                        const uint32_t num_sids,
     527             :                        const struct dom_sid *sid)
     528             : {
     529         620 :         uint32_t i;
     530             : 
     531     2784969 :         for (i = 0; i < num_sids; i++) {
     532     2495381 :                 if (dom_sid_equal(&sids[i], sid)) {
     533      134687 :                         return true;
     534             :                 }
     535             :         }
     536      288968 :         return false;
     537             : }
     538             : 
     539             : /**
     540             :  * Return true if an array of auth_SidAttr contains a certain SID.
     541             :  *
     542             :  * @param [in] sids     The auth_SidAttr array.
     543             :  * @param [in] num_sids The size of the auth_SidArray array.
     544             :  * @param [in] sid      The SID in question.
     545             :  * @returns true if the array contains the SID.
     546             :  */
     547         169 : bool sid_attrs_contains_sid(const struct auth_SidAttr *sids,
     548             :                             const uint32_t num_sids,
     549             :                             const struct dom_sid *sid)
     550             : {
     551           0 :         uint32_t i;
     552             : 
     553         751 :         for (i = 0; i < num_sids; i++) {
     554         722 :                 if (dom_sid_equal(&sids[i].sid, sid)) {
     555         140 :                         return true;
     556             :                 }
     557             :         }
     558          29 :         return false;
     559             : }
     560             : 
     561             : /**
     562             :  * Return true if an array of auth_SidAttr contains a certain SID with certain
     563             :  * attributes.
     564             :  *
     565             :  * @param [in] sids     The auth_SidAttr array.
     566             :  * @param [in] num_sids The size of the auth_SidArray array.
     567             :  * @param [in] sid      The SID in question.
     568             :  * @param [in] attrs    The attributes of the SID.
     569             :  * @returns true if the array contains the SID.
     570             :  */
     571     1102787 : bool sids_contains_sid_attrs(const struct auth_SidAttr *sids,
     572             :                              const uint32_t num_sids,
     573             :                              const struct dom_sid *sid,
     574             :                              uint32_t attrs)
     575             : {
     576       46233 :         uint32_t i;
     577             : 
     578     9075538 :         for (i = 0; i < num_sids; i++) {
     579     8537615 :                 if (attrs != sids[i].attrs) {
     580     5378692 :                         continue;
     581             :                 }
     582     3158923 :                 if (!dom_sid_equal(&sids[i].sid, sid)) {
     583     2594059 :                         continue;
     584             :                 }
     585             : 
     586      542413 :                 return true;
     587             :         }
     588      514141 :         return false;
     589             : }
     590             : 
     591             : /*
     592             :  * See [MS-LSAT] 3.1.1.1.1 Predefined Translation Database and Corresponding View
     593             :  */
     594             : struct predefined_name_mapping {
     595             :         const char *name;
     596             :         enum lsa_SidType type;
     597             :         struct dom_sid sid;
     598             : };
     599             : 
     600             : struct predefined_domain_mapping {
     601             :         const char *domain;
     602             :         struct dom_sid sid;
     603             :         size_t num_names;
     604             :         const struct predefined_name_mapping *names;
     605             : };
     606             : 
     607             : /* S-1-${AUTHORITY} */
     608             : #define _SID0(authority) \
     609             :         { 1, 0, {0,0,0,0,0,authority}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
     610             : /* S-1-${AUTHORITY}-${SUB1} */
     611             : #define _SID1(authority,sub1) \
     612             :         { 1, 1, {0,0,0,0,0,authority}, {sub1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
     613             : /* S-1-${AUTHORITY}-${SUB1}-${SUB2} */
     614             : #define _SID2(authority,sub1,sub2) \
     615             :         { 1, 2, {0,0,0,0,0,authority}, {sub1,sub2,0,0,0,0,0,0,0,0,0,0,0,0,0}}
     616             : 
     617             : /*
     618             :  * S-1-0
     619             :  */
     620             : static const struct predefined_name_mapping predefined_names_S_1_0[] = {
     621             :         {
     622             :                 .name = "NULL SID",
     623             :                 .type = SID_NAME_WKN_GRP,
     624             :                 .sid = _SID1(0, 0), /* S-1-0-0 */
     625             :         },
     626             : };
     627             : 
     628             : /*
     629             :  * S-1-1
     630             :  */
     631             : static const struct predefined_name_mapping predefined_names_S_1_1[] = {
     632             :         {
     633             :                 .name = "Everyone",
     634             :                 .type = SID_NAME_WKN_GRP,
     635             :                 .sid = _SID1(1, 0), /* S-1-1-0 */
     636             :         },
     637             : };
     638             : 
     639             : /*
     640             :  * S-1-2
     641             :  */
     642             : static const struct predefined_name_mapping predefined_names_S_1_2[] = {
     643             :         {
     644             :                 .name = "LOCAL",
     645             :                 .type = SID_NAME_WKN_GRP,
     646             :                 .sid = _SID1(2, 0), /* S-1-2-0 */
     647             :         },
     648             : };
     649             : 
     650             : /*
     651             :  * S-1-3
     652             :  */
     653             : static const struct predefined_name_mapping predefined_names_S_1_3[] = {
     654             :         {
     655             :                 .name = "CREATOR OWNER",
     656             :                 .type = SID_NAME_WKN_GRP,
     657             :                 .sid = _SID1(3, 0), /* S-1-3-0 */
     658             :         },
     659             :         {
     660             :                 .name = "CREATOR GROUP",
     661             :                 .type = SID_NAME_WKN_GRP,
     662             :                 .sid = _SID1(3, 1), /* S-1-3-1 */
     663             :         },
     664             :         {
     665             :                 .name = "CREATOR OWNER SERVER",
     666             :                 .type = SID_NAME_WKN_GRP,
     667             :                 .sid = _SID1(3, 0), /* S-1-3-2 */
     668             :         },
     669             :         {
     670             :                 .name = "CREATOR GROUP SERVER",
     671             :                 .type = SID_NAME_WKN_GRP,
     672             :                 .sid = _SID1(3, 1), /* S-1-3-3 */
     673             :         },
     674             :         {
     675             :                 .name = "OWNER RIGHTS",
     676             :                 .type = SID_NAME_WKN_GRP,
     677             :                 .sid = _SID1(3, 4), /* S-1-3-4 */
     678             :         },
     679             : };
     680             : 
     681             : /*
     682             :  * S-1-5 only 'NT Pseudo Domain'
     683             :  */
     684             : static const struct predefined_name_mapping predefined_names_S_1_5p[] = {
     685             :         {
     686             :                 .name = "NT Pseudo Domain",
     687             :                 .type = SID_NAME_DOMAIN,
     688             :                 .sid = _SID0(5), /* S-1-5 */
     689             :         },
     690             : };
     691             : 
     692             : /*
     693             :  * S-1-5 'NT AUTHORITY'
     694             :  */
     695             : static const struct predefined_name_mapping predefined_names_S_1_5a[] = {
     696             :         {
     697             :                 .name = "DIALUP",
     698             :                 .type = SID_NAME_WKN_GRP,
     699             :                 .sid = _SID1(5, 1), /* S-1-5-1 */
     700             :         },
     701             :         {
     702             :                 .name = "NETWORK",
     703             :                 .type = SID_NAME_WKN_GRP,
     704             :                 .sid = _SID1(5, 2), /* S-1-5-2 */
     705             :         },
     706             :         {
     707             :                 .name = "BATCH",
     708             :                 .type = SID_NAME_WKN_GRP,
     709             :                 .sid = _SID1(5, 3), /* S-1-5-3 */
     710             :         },
     711             :         {
     712             :                 .name = "INTERACTIVE",
     713             :                 .type = SID_NAME_WKN_GRP,
     714             :                 .sid = _SID1(5, 4), /* S-1-5-4 */
     715             :         },
     716             :         {
     717             :                 .name = "SERVICE",
     718             :                 .type = SID_NAME_WKN_GRP,
     719             :                 .sid = _SID1(5, 6), /* S-1-5-6 */
     720             :         },
     721             :         {
     722             :                 .name = "ANONYMOUS LOGON",
     723             :                 .type = SID_NAME_WKN_GRP,
     724             :                 .sid = _SID1(5, 7), /* S-1-5-7 */
     725             :         },
     726             :         {
     727             :                 .name = "PROXY",
     728             :                 .type = SID_NAME_WKN_GRP,
     729             :                 .sid = _SID1(5, 8), /* S-1-5-8 */
     730             :         },
     731             :         {
     732             :                 .name = "ENTERPRISE DOMAIN CONTROLLERS",
     733             :                 .type = SID_NAME_WKN_GRP,
     734             :                 .sid = _SID1(5, 9), /* S-1-5-9 */
     735             :         },
     736             :         {
     737             :                 .name = "SELF",
     738             :                 .type = SID_NAME_WKN_GRP,
     739             :                 .sid = _SID1(5, 10), /* S-1-5-10 */
     740             :         },
     741             :         {
     742             :                 .name = "Authenticated Users",
     743             :                 .type = SID_NAME_WKN_GRP,
     744             :                 .sid = _SID1(5, 11), /* S-1-5-11 */
     745             :         },
     746             :         {
     747             :                 .name = "RESTRICTED",
     748             :                 .type = SID_NAME_WKN_GRP,
     749             :                 .sid = _SID1(5, 12), /* S-1-5-12 */
     750             :         },
     751             :         {
     752             :                 .name = "TERMINAL SERVER USER",
     753             :                 .type = SID_NAME_WKN_GRP,
     754             :                 .sid = _SID1(5, 13), /* S-1-5-13 */
     755             :         },
     756             :         {
     757             :                 .name = "REMOTE INTERACTIVE LOGON",
     758             :                 .type = SID_NAME_WKN_GRP,
     759             :                 .sid = _SID1(5, 14), /* S-1-5-14 */
     760             :         },
     761             :         {
     762             :                 .name = "This Organization",
     763             :                 .type = SID_NAME_WKN_GRP,
     764             :                 .sid = _SID1(5, 15), /* S-1-5-15 */
     765             :         },
     766             :         {
     767             :                 .name = "IUSR",
     768             :                 .type = SID_NAME_WKN_GRP,
     769             :                 .sid = _SID1(5, 17), /* S-1-5-17 */
     770             :         },
     771             :         {
     772             :                 .name = "SYSTEM",
     773             :                 .type = SID_NAME_WKN_GRP,
     774             :                 .sid = _SID1(5, 18), /* S-1-5-18 */
     775             :         },
     776             :         {
     777             :                 .name = "LOCAL SERVICE",
     778             :                 .type = SID_NAME_WKN_GRP,
     779             :                 .sid = _SID1(5, 19), /* S-1-5-19 */
     780             :         },
     781             :         {
     782             :                 .name = "NETWORK SERVICE",
     783             :                 .type = SID_NAME_WKN_GRP,
     784             :                 .sid = _SID1(5, 20), /* S-1-5-20 */
     785             :         },
     786             :         {
     787             :                 .name = "WRITE RESTRICTED",
     788             :                 .type = SID_NAME_WKN_GRP,
     789             :                 .sid = _SID1(5, 33), /* S-1-5-33 */
     790             :         },
     791             :         {
     792             :                 .name = "Other Organization",
     793             :                 .type = SID_NAME_WKN_GRP,
     794             :                 .sid = _SID1(5, 1000), /* S-1-5-1000 */
     795             :         },
     796             : };
     797             : 
     798             : /*
     799             :  * S-1-5-32
     800             :  */
     801             : static const struct predefined_name_mapping predefined_names_S_1_5_32[] = {
     802             :         {
     803             :                 .name = "BUILTIN",
     804             :                 .type = SID_NAME_DOMAIN,
     805             :                 .sid = _SID1(5, 32), /* S-1-5-32 */
     806             :         },
     807             : };
     808             : 
     809             : /*
     810             :  * S-1-5-64
     811             :  */
     812             : static const struct predefined_name_mapping predefined_names_S_1_5_64[] = {
     813             :         {
     814             :                 .name = "NTLM Authentication",
     815             :                 .type = SID_NAME_WKN_GRP,
     816             :                 .sid = _SID2(5, 64, 10), /* S-1-5-64-10 */
     817             :         },
     818             :         {
     819             :                 .name = "SChannel Authentication",
     820             :                 .type = SID_NAME_WKN_GRP,
     821             :                 .sid = _SID2(5, 64, 14), /* S-1-5-64-14 */
     822             :         },
     823             :         {
     824             :                 .name = "Digest Authentication",
     825             :                 .type = SID_NAME_WKN_GRP,
     826             :                 .sid = _SID2(5, 64, 21), /* S-1-5-64-21 */
     827             :         },
     828             : };
     829             : 
     830             : /*
     831             :  * S-1-7
     832             :  */
     833             : static const struct predefined_name_mapping predefined_names_S_1_7[] = {
     834             :         {
     835             :                 .name = "Internet$",
     836             :                 .type = SID_NAME_DOMAIN,
     837             :                 .sid = _SID0(7), /* S-1-7 */
     838             :         },
     839             : };
     840             : 
     841             : /*
     842             :  * S-1-16
     843             :  */
     844             : static const struct predefined_name_mapping predefined_names_S_1_16[] = {
     845             :         {
     846             :                 .name = "Mandatory Label",
     847             :                 .type = SID_NAME_DOMAIN,
     848             :                 .sid = _SID0(16), /* S-1-16 */
     849             :         },
     850             :         {
     851             :                 .name = "Untrusted Mandatory Level",
     852             :                 .type = SID_NAME_LABEL,
     853             :                 .sid = _SID1(16, 0), /* S-1-16-0 */
     854             :         },
     855             :         {
     856             :                 .name = "Low Mandatory Level",
     857             :                 .type = SID_NAME_LABEL,
     858             :                 .sid = _SID1(16, 4096), /* S-1-16-4096 */
     859             :         },
     860             :         {
     861             :                 .name = "Medium Mandatory Level",
     862             :                 .type = SID_NAME_LABEL,
     863             :                 .sid = _SID1(16, 8192), /* S-1-16-8192 */
     864             :         },
     865             :         {
     866             :                 .name = "High Mandatory Level",
     867             :                 .type = SID_NAME_LABEL,
     868             :                 .sid = _SID1(16, 12288), /* S-1-16-12288 */
     869             :         },
     870             :         {
     871             :                 .name = "System Mandatory Level",
     872             :                 .type = SID_NAME_LABEL,
     873             :                 .sid = _SID1(16, 16384), /* S-1-16-16384 */
     874             :         },
     875             :         {
     876             :                 .name = "Protected Process Mandatory Level",
     877             :                 .type = SID_NAME_LABEL,
     878             :                 .sid = _SID1(16, 20480), /* S-1-16-20480 */
     879             :         },
     880             : };
     881             : 
     882             : static const struct predefined_domain_mapping predefined_domains[] = {
     883             :         {
     884             :                 .domain = "",
     885             :                 .sid = _SID0(0), /* S-1-0 */
     886             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_0),
     887             :                 .names = predefined_names_S_1_0,
     888             :         },
     889             :         {
     890             :                 .domain = "",
     891             :                 .sid = _SID0(1), /* S-1-1 */
     892             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_1),
     893             :                 .names = predefined_names_S_1_1,
     894             :         },
     895             :         {
     896             :                 .domain = "",
     897             :                 .sid = _SID0(2), /* S-1-2 */
     898             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_2),
     899             :                 .names = predefined_names_S_1_2,
     900             :         },
     901             :         {
     902             :                 .domain = "",
     903             :                 .sid = _SID0(3), /* S-1-3 */
     904             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_3),
     905             :                 .names = predefined_names_S_1_3,
     906             :         },
     907             :         {
     908             :                 .domain = "",
     909             :                 .sid = _SID0(3), /* S-1-3 */
     910             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_3),
     911             :                 .names = predefined_names_S_1_3,
     912             :         },
     913             :         /*
     914             :          * S-1-5 is split here
     915             :          *
     916             :          * 'NT Pseudo Domain' has precedence before 'NT AUTHORITY'.
     917             :          *
     918             :          * In a LookupSids with multiple sids e.g. S-1-5 and S-1-5-7
     919             :          * the domain section (struct lsa_DomainInfo) gets
     920             :          * 'NT Pseudo Domain' with S-1-5. If asked in reversed order
     921             :          * S-1-5-7 and then S-1-5, you get struct lsa_DomainInfo
     922             :          * with 'NT AUTHORITY' and S-1-5.
     923             :          */
     924             :         {
     925             :                 .domain = "NT Pseudo Domain",
     926             :                 .sid = _SID0(5), /* S-1-5 */
     927             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_5p),
     928             :                 .names = predefined_names_S_1_5p,
     929             :         },
     930             :         {
     931             :                 .domain = "NT AUTHORITY",
     932             :                 .sid = _SID0(5), /* S-1-5 */
     933             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_5a),
     934             :                 .names = predefined_names_S_1_5a,
     935             :         },
     936             :         {
     937             :                 .domain = "BUILTIN",
     938             :                 .sid = _SID1(5, 32), /* S-1-5-32 */
     939             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_5_32),
     940             :                 .names = predefined_names_S_1_5_32,
     941             :         },
     942             :         /*
     943             :          * 'NT AUTHORITY' again with S-1-5-64 this time
     944             :          */
     945             :         {
     946             :                 .domain = "NT AUTHORITY",
     947             :                 .sid = _SID1(5, 64), /* S-1-5-64 */
     948             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_5_64),
     949             :                 .names = predefined_names_S_1_5_64,
     950             :         },
     951             :         {
     952             :                 .domain = "Internet$",
     953             :                 .sid = _SID0(7), /* S-1-7 */
     954             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_7),
     955             :                 .names = predefined_names_S_1_7,
     956             :         },
     957             :         {
     958             :                 .domain = "Mandatory Label",
     959             :                 .sid = _SID0(16), /* S-1-16 */
     960             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_16),
     961             :                 .names = predefined_names_S_1_16,
     962             :         },
     963             : };
     964             : 
     965       27407 : NTSTATUS dom_sid_lookup_predefined_name(const char *name,
     966             :                                         const struct dom_sid **sid,
     967             :                                         enum lsa_SidType *type,
     968             :                                         const struct dom_sid **authority_sid,
     969             :                                         const char **authority_name)
     970             : {
     971        4800 :         size_t di;
     972       27407 :         const char *domain = "";
     973       27407 :         size_t domain_len = 0;
     974        4800 :         const char *p;
     975        4800 :         bool match;
     976             : 
     977       27407 :         *sid = NULL;
     978       27407 :         *type = SID_NAME_UNKNOWN;
     979       27407 :         *authority_sid = NULL;
     980       27407 :         *authority_name = NULL;
     981             : 
     982       27407 :         if (name == NULL) {
     983           3 :                 name = "";
     984             :         }
     985             : 
     986       27407 :         p = strchr(name, '\\');
     987       27407 :         if (p != NULL) {
     988         458 :                 domain = name;
     989         458 :                 domain_len = PTR_DIFF(p, domain);
     990         458 :                 name = p + 1;
     991             :         }
     992             : 
     993       27407 :         match = strequal(name, "");
     994       27407 :         if (match) {
     995             :                 /*
     996             :                  * Strange, but that's what W2012R2 does.
     997             :                  */
     998         102 :                 name = "BUILTIN";
     999             :         }
    1000             : 
    1001      328708 :         for (di = 0; di < ARRAY_SIZE(predefined_domains); di++) {
    1002      301337 :                 const struct predefined_domain_mapping *d =
    1003             :                         &predefined_domains[di];
    1004       52800 :                 size_t ni;
    1005             : 
    1006      301337 :                 if (domain_len != 0) {
    1007           0 :                         int cmp;
    1008             : 
    1009        4985 :                         cmp = strncasecmp(d->domain, domain, domain_len);
    1010        4985 :                         if (cmp != 0) {
    1011        4962 :                                 continue;
    1012             :                         }
    1013             :                 }
    1014             : 
    1015     1535812 :                 for (ni = 0; ni < d->num_names; ni++) {
    1016     1239473 :                         const struct predefined_name_mapping *n =
    1017     1239473 :                                 &d->names[ni];
    1018             : 
    1019     1239473 :                         match = strequal(n->name, name);
    1020     1239473 :                         if (!match) {
    1021     1239437 :                                 continue;
    1022             :                         }
    1023             : 
    1024          36 :                         *sid = &n->sid;
    1025          36 :                         *type = n->type;
    1026          36 :                         *authority_sid = &d->sid;
    1027          36 :                         *authority_name = d->domain;
    1028          36 :                         return NT_STATUS_OK;
    1029             :                 }
    1030             :         }
    1031             : 
    1032       27371 :         return NT_STATUS_NONE_MAPPED;
    1033             : }
    1034             : 
    1035       96813 : bool dom_sid_lookup_is_predefined_domain(const char *domain)
    1036             : {
    1037           0 :         size_t di;
    1038           0 :         bool match;
    1039             : 
    1040       96813 :         if (domain == NULL) {
    1041           0 :                 domain = "";
    1042             :         }
    1043             : 
    1044       96813 :         match = strequal(domain, "");
    1045       96813 :         if (match) {
    1046             :                 /*
    1047             :                  * Strange, but that's what W2012R2 does.
    1048             :                  */
    1049           0 :                 domain = "BUILTIN";
    1050             :         }
    1051             : 
    1052     1161266 :         for (di = 0; di < ARRAY_SIZE(predefined_domains); di++) {
    1053     1064551 :                 const struct predefined_domain_mapping *d =
    1054             :                         &predefined_domains[di];
    1055           0 :                 int cmp;
    1056             : 
    1057     1064551 :                 cmp = strcasecmp(d->domain, domain);
    1058     1064551 :                 if (cmp != 0) {
    1059     1064453 :                         continue;
    1060             :                 }
    1061             : 
    1062          98 :                 return true;
    1063             :         }
    1064             : 
    1065       96715 :         return false;
    1066             : }
    1067             : 
    1068       32046 : NTSTATUS dom_sid_lookup_predefined_sid(const struct dom_sid *sid,
    1069             :                                        const char **name,
    1070             :                                        enum lsa_SidType *type,
    1071             :                                        const struct dom_sid **authority_sid,
    1072             :                                        const char **authority_name)
    1073             : {
    1074        4800 :         size_t di;
    1075       32046 :         bool match_domain = false;
    1076             : 
    1077       32046 :         *name = NULL;
    1078       32046 :         *type = SID_NAME_UNKNOWN;
    1079       32046 :         *authority_sid = NULL;
    1080       32046 :         *authority_name = NULL;
    1081             : 
    1082       32046 :         if (sid == NULL) {
    1083           0 :                 return NT_STATUS_INVALID_SID;
    1084             :         }
    1085             : 
    1086      383051 :         for (di = 0; di < ARRAY_SIZE(predefined_domains); di++) {
    1087      351228 :                 const struct predefined_domain_mapping *d =
    1088             :                         &predefined_domains[di];
    1089       52800 :                 size_t ni;
    1090       52800 :                 int cmp;
    1091             : 
    1092      351228 :                 cmp = dom_sid_compare_auth(&d->sid, sid);
    1093      351228 :                 if (cmp != 0) {
    1094      228920 :                         continue;
    1095             :                 }
    1096             : 
    1097      242308 :                 match_domain = true;
    1098             : 
    1099      885306 :                 for (ni = 0; ni < d->num_names; ni++) {
    1100      763221 :                         const struct predefined_name_mapping *n =
    1101      763221 :                                 &d->names[ni];
    1102             : 
    1103      763221 :                         cmp = dom_sid_compare(&n->sid, sid);
    1104      763221 :                         if (cmp != 0) {
    1105      762998 :                                 continue;
    1106             :                         }
    1107             : 
    1108         223 :                         *name = n->name;
    1109         223 :                         *type = n->type;
    1110         223 :                         *authority_sid = &d->sid;
    1111         223 :                         *authority_name = d->domain;
    1112         223 :                         return NT_STATUS_OK;
    1113             :                 }
    1114             :         }
    1115             : 
    1116       31823 :         if (!match_domain) {
    1117        1337 :                 return NT_STATUS_INVALID_SID;
    1118             :         }
    1119             : 
    1120       30486 :         return NT_STATUS_NONE_MAPPED;
    1121             : }

Generated by: LCOV version 1.14