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

Generated by: LCOV version 1.14