LCOV - code coverage report
Current view: top level - libcli/security - util_sid.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 149 168 88.7 %
Date: 2024-06-13 04:01:37 Functions: 16 17 94.1 %

          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 "includes.h"
      27             : #include "../librpc/gen_ndr/ndr_security.h"
      28             : #include "../librpc/gen_ndr/netlogon.h"
      29             : #include "../libcli/security/security.h"
      30             : 
      31             : #undef strcasecmp
      32             : #undef strncasecmp
      33             : 
      34             : /*
      35             :  * Some useful sids, more well known sids can be found at
      36             :  * http://support.microsoft.com/kb/243330/EN-US/
      37             :  */
      38             : 
      39             : 
      40             : /* S-1-1 */
      41             : const struct dom_sid global_sid_World_Domain =               /* Everyone domain */
      42             : { 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      43             : /* S-1-1-0 */
      44             : const struct dom_sid global_sid_World =                      /* Everyone */
      45             : { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      46             : /* S-1-2 */
      47             : const struct dom_sid global_sid_Local_Authority =            /* Local Authority */
      48             : { 1, 0, {0,0,0,0,0,2}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      49             : /* S-1-3 */
      50             : const struct dom_sid global_sid_Creator_Owner_Domain =       /* Creator Owner domain */
      51             : { 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      52             : /* S-1-5 */
      53             : const struct dom_sid global_sid_NT_Authority =                  /* NT Authority */
      54             : { 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      55             : /* S-1-5-18 */
      56             : const struct dom_sid global_sid_System =                        /* System */
      57             : { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      58             : /* S-1-0-0 */
      59             : const struct dom_sid global_sid_NULL =                          /* NULL sid */
      60             : { 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      61             : /* S-1-5-11 */
      62             : const struct dom_sid global_sid_Authenticated_Users =   /* All authenticated rids */
      63             : { 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      64             : #if 0
      65             : /* for documentation S-1-5-12 */
      66             : const struct dom_sid global_sid_Restriced =                     /* Restriced Code */
      67             : { 1, 1, {0,0,0,0,0,5}, {12,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      68             : #endif
      69             : 
      70             : /* S-1-18 */
      71             : const struct dom_sid global_sid_Asserted_Identity =       /* Asserted Identity */
      72             : { 1, 0, {0,0,0,0,0,18}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      73             : /* S-1-18-1 */
      74             : const struct dom_sid global_sid_Asserted_Identity_Service =     /* Asserted Identity Service */
      75             : { 1, 1, {0,0,0,0,0,18}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      76             : /* S-1-18-2 */
      77             : const struct dom_sid global_sid_Asserted_Identity_Authentication_Authority =    /* Asserted Identity Authentication Authority */
      78             : { 1, 1, {0,0,0,0,0,18}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      79             : 
      80             : /* S-1-5-2 */
      81             : const struct dom_sid global_sid_Network =                       /* Network rids */
      82             : { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      83             : 
      84             : /* S-1-3 */
      85             : const struct dom_sid global_sid_Creator_Owner =         /* Creator Owner */
      86             : { 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      87             : /* S-1-3-1 */
      88             : const struct dom_sid global_sid_Creator_Group =         /* Creator Group */
      89             : { 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      90             : /* S-1-3-4 */
      91             : const struct dom_sid global_sid_Owner_Rights =          /* Owner Rights */
      92             : { 1, 1, {0,0,0,0,0,3}, {4,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      93             : /* S-1-5-7 */
      94             : const struct dom_sid global_sid_Anonymous =                     /* Anonymous login */
      95             : { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      96             : /* S-1-5-9 */
      97             : const struct dom_sid global_sid_Enterprise_DCs =                /* Enterprise DCs */
      98             : { 1, 1, {0,0,0,0,0,5}, {9,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
      99             : /* S-1-5-32 */
     100             : const struct dom_sid global_sid_Builtin =                       /* Local well-known domain */
     101             : { 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     102             : /* S-1-5-32-544 */
     103             : const struct dom_sid global_sid_Builtin_Administrators =        /* Builtin administrators */
     104             : { 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     105             : /* S-1-5-32-545 */
     106             : const struct dom_sid global_sid_Builtin_Users =         /* Builtin users */
     107             : { 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     108             : /* S-1-5-32-546 */
     109             : const struct dom_sid global_sid_Builtin_Guests =                /* Builtin guest users */
     110             : { 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     111             : /* S-1-5-32-547 */
     112             : const struct dom_sid global_sid_Builtin_Power_Users =   /* Builtin power users */
     113             : { 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     114             : /* S-1-5-32-548 */
     115             : const struct dom_sid global_sid_Builtin_Account_Operators =     /* Builtin account operators */
     116             : { 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     117             : /* S-1-5-32-549 */
     118             : const struct dom_sid global_sid_Builtin_Server_Operators =      /* Builtin server operators */
     119             : { 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     120             : /* S-1-5-32-550 */
     121             : const struct dom_sid global_sid_Builtin_Print_Operators =       /* Builtin print operators */
     122             : { 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     123             : /* S-1-5-32-551 */
     124             : const struct dom_sid global_sid_Builtin_Backup_Operators =      /* Builtin backup operators */
     125             : { 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     126             : /* S-1-5-32-552 */
     127             : const struct dom_sid global_sid_Builtin_Replicator =            /* Builtin replicator */
     128             : { 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     129             : /* S-1-5-32-554 */
     130             : const struct dom_sid global_sid_Builtin_PreWin2kAccess =        /* Builtin pre win2k access */
     131             : { 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     132             : 
     133             : /* S-1-22-1 */
     134             : const struct dom_sid global_sid_Unix_Users =                    /* Unmapped Unix users */
     135             : { 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     136             : /* S-1-22-2 */
     137             : const struct dom_sid global_sid_Unix_Groups =                   /* Unmapped Unix groups */
     138             : { 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     139             : 
     140             : /*
     141             :  * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
     142             :  */
     143             : /* S-1-5-88 */
     144             : const struct dom_sid global_sid_Unix_NFS =             /* MS NFS and Apple style */
     145             : { 1, 1, {0,0,0,0,0,5}, {88,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     146             : /* S-1-5-88-1 */
     147             : const struct dom_sid global_sid_Unix_NFS_Users =                /* Unix uid, MS NFS and Apple style */
     148             : { 1, 2, {0,0,0,0,0,5}, {88,1,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     149             : /* S-1-5-88-2 */
     150             : const struct dom_sid global_sid_Unix_NFS_Groups =               /* Unix gid, MS NFS and Apple style */
     151             : { 1, 2, {0,0,0,0,0,5}, {88,2,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     152             : /* S-1-5-88-3 */
     153             : const struct dom_sid global_sid_Unix_NFS_Mode =                 /* Unix mode */
     154             : { 1, 2, {0,0,0,0,0,5}, {88,3,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     155             : /* Unused, left here for documentary purposes */
     156             : #if 0
     157             : const struct dom_sid global_sid_Unix_NFS_Other =                /* Unix other, MS NFS and Apple style */
     158             : { 1, 2, {0,0,0,0,0,5}, {88,4,0,0,0,0,0,0,0,0,0,0,0,0,0}};
     159             : #endif
     160             : 
     161             : /* Information passing via security token */
     162             : const struct dom_sid global_sid_Samba_SMB3 =
     163             : {1, 1, {0,0,0,0,0,22}, {1397571891, }};
     164             : 
     165             : const struct dom_sid global_sid_Samba_NPA_Flags = {1,
     166             :                                                    1,
     167             :                                                    {0, 0, 0, 0, 0, 22},
     168             :                                                    {
     169             :                                                            2041152804,
     170             :                                                    }};
     171             : 
     172             : /* Unused, left here for documentary purposes */
     173             : #if 0
     174             : #define SECURITY_NULL_SID_AUTHORITY    0
     175             : #define SECURITY_WORLD_SID_AUTHORITY   1
     176             : #define SECURITY_LOCAL_SID_AUTHORITY   2
     177             : #define SECURITY_CREATOR_SID_AUTHORITY 3
     178             : #define SECURITY_NT_AUTHORITY          5
     179             : #endif
     180             : 
     181             : static struct dom_sid system_sid_array[1] =
     182             : { { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
     183             : static const struct security_token system_token = {
     184             :         .num_sids       = ARRAY_SIZE(system_sid_array),
     185             :         .sids           = system_sid_array,
     186             :         .privilege_mask = SE_ALL_PRIVS
     187             : };
     188             : 
     189             : /****************************************************************************
     190             :  Lookup string names for SID types.
     191             : ****************************************************************************/
     192             : 
     193             : static const struct {
     194             :         enum lsa_SidType sid_type;
     195             :         const char *string;
     196             : } sid_name_type[] = {
     197             :         {SID_NAME_USE_NONE, "None"},
     198             :         {SID_NAME_USER, "User"},
     199             :         {SID_NAME_DOM_GRP, "Domain Group"},
     200             :         {SID_NAME_DOMAIN, "Domain"},
     201             :         {SID_NAME_ALIAS, "Local Group"},
     202             :         {SID_NAME_WKN_GRP, "Well-known Group"},
     203             :         {SID_NAME_DELETED, "Deleted Account"},
     204             :         {SID_NAME_INVALID, "Invalid Account"},
     205             :         {SID_NAME_UNKNOWN, "UNKNOWN"},
     206             :         {SID_NAME_COMPUTER, "Computer"},
     207             :         {SID_NAME_LABEL, "Mandatory Label"}
     208             : };
     209             : 
     210          62 : const char *sid_type_lookup(uint32_t sid_type)
     211             : {
     212             :         size_t i;
     213             : 
     214             :         /* Look through list */
     215         184 :         for (i=0; i < ARRAY_SIZE(sid_name_type); i++) {
     216         184 :                 if (sid_name_type[i].sid_type == sid_type) {
     217          62 :                         return sid_name_type[i].string;
     218             :                 }
     219             :         }
     220             : 
     221             :         /* Default return */
     222           0 :         return "SID *TYPE* is INVALID";
     223             : }
     224             : 
     225             : /**************************************************************************
     226             :  Create the SYSTEM token.
     227             : ***************************************************************************/
     228             : 
     229           0 : const struct security_token *get_system_token(void)
     230             : {
     231           0 :         return &system_token;
     232             : }
     233             : 
     234       54797 : bool sid_compose(struct dom_sid *dst, const struct dom_sid *domain_sid, uint32_t rid)
     235             : {
     236       54797 :         sid_copy(dst, domain_sid);
     237       54797 :         return sid_append_rid(dst, rid);
     238             : }
     239             : 
     240             : /*****************************************************************
     241             :  Removes the last rid from the end of a sid
     242             : *****************************************************************/
     243             : 
     244      175372 : bool sid_split_rid(struct dom_sid *sid, uint32_t *rid)
     245             : {
     246      175372 :         if (sid->num_auths > 0) {
     247      175372 :                 sid->num_auths--;
     248      175372 :                 if (rid != NULL) {
     249       67136 :                         *rid = sid->sub_auths[sid->num_auths];
     250             :                 }
     251      175372 :                 return true;
     252             :         }
     253           0 :         return false;
     254             : }
     255             : 
     256             : /*****************************************************************
     257             :  Return the last rid from the end of a sid
     258             : *****************************************************************/
     259             : 
     260       28856 : bool sid_peek_rid(const struct dom_sid *sid, uint32_t *rid)
     261             : {
     262       28856 :         if (!sid || !rid)
     263           0 :                 return false;
     264             : 
     265       28856 :         if (sid->num_auths > 0) {
     266       28856 :                 *rid = sid->sub_auths[sid->num_auths - 1];
     267       28856 :                 return true;
     268             :         }
     269           0 :         return false;
     270             : }
     271             : 
     272             : /*****************************************************************
     273             :  Return the last rid from the end of a sid
     274             :  and check the sid against the exp_dom_sid
     275             : *****************************************************************/
     276             : 
     277       70297 : bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, const struct dom_sid *sid, uint32_t *rid)
     278             : {
     279       70297 :         if (!exp_dom_sid || !sid || !rid)
     280           0 :                 return false;
     281             : 
     282       70297 :         if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
     283       37945 :                 return false;
     284             :         }
     285             : 
     286       32352 :         if (sid_compare_domain(exp_dom_sid, sid)!=0){
     287       11740 :                 *rid=(-1);
     288       11740 :                 return false;
     289             :         }
     290             : 
     291       20612 :         return sid_peek_rid(sid, rid);
     292             : }
     293             : 
     294             : /*****************************************************************
     295             :  Copies a sid
     296             : *****************************************************************/
     297             : 
     298      601854 : void sid_copy(struct dom_sid *dst, const struct dom_sid *src)
     299             : {
     300             :         int i;
     301             : 
     302      601854 :         *dst = (struct dom_sid) {
     303      601854 :                 .sid_rev_num = src->sid_rev_num,
     304      601854 :                 .num_auths = src->num_auths,
     305             :         };
     306             : 
     307      601854 :         memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
     308             : 
     309     2396034 :         for (i = 0; i < src->num_auths; i++)
     310     1794180 :                 dst->sub_auths[i] = src->sub_auths[i];
     311      601854 : }
     312             : 
     313             : /*****************************************************************
     314             :  Parse a on-the-wire SID to a struct dom_sid.
     315             : *****************************************************************/
     316             : 
     317     4435104 : ssize_t sid_parse(const uint8_t *inbuf, size_t len, struct dom_sid *sid)
     318             : {
     319     4435104 :         DATA_BLOB in = data_blob_const(inbuf, len);
     320             :         enum ndr_err_code ndr_err;
     321             : 
     322     4435104 :         ndr_err = ndr_pull_struct_blob_all(
     323             :                 &in, NULL, sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
     324     4435104 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     325           0 :                 return -1;
     326             :         }
     327     4435104 :         return ndr_size_dom_sid(sid, 0);
     328             : }
     329             : 
     330             : /*****************************************************************
     331             :  See if 2 SIDs are in the same domain
     332             :  this just compares the leading sub-auths
     333             : *****************************************************************/
     334             : 
     335       32352 : int sid_compare_domain(const struct dom_sid *sid1, const struct dom_sid *sid2)
     336             : {
     337             :         int n, i;
     338             : 
     339       32352 :         n = MIN(sid1->num_auths, sid2->num_auths);
     340             : 
     341       99893 :         for (i = n-1; i >= 0; --i)
     342       79281 :                 if (sid1->sub_auths[i] != sid2->sub_auths[i])
     343       11740 :                         return sid1->sub_auths[i] - sid2->sub_auths[i];
     344             : 
     345       20612 :         return dom_sid_compare_auth(sid1, sid2);
     346             : }
     347             : 
     348             : /********************************************************************
     349             :  Add SID to an array SIDs
     350             : ********************************************************************/
     351             : 
     352      117417 : NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
     353             :                           struct dom_sid **sids, uint32_t *num)
     354             : {
     355             :         struct dom_sid *tmp;
     356             : 
     357      117417 :         if ((*num) == UINT32_MAX) {
     358           0 :                 return NT_STATUS_INTEGER_OVERFLOW;
     359             :         }
     360             : 
     361      117417 :         tmp = talloc_realloc(mem_ctx, *sids, struct dom_sid, (*num)+1);
     362      117417 :         if (tmp == NULL) {
     363           0 :                 *num = 0;
     364           0 :                 return NT_STATUS_NO_MEMORY;
     365             :         }
     366      117417 :         *sids = tmp;
     367             : 
     368      117417 :         sid_copy(&((*sids)[*num]), sid);
     369      117417 :         *num += 1;
     370             : 
     371      117417 :         return NT_STATUS_OK;
     372             : }
     373             : 
     374             : 
     375             : /********************************************************************
     376             :  Add SID to an array SIDs ensuring that it is not already there
     377             : ********************************************************************/
     378             : 
     379       70632 : NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
     380             :                                  struct dom_sid **sids, uint32_t *num_sids)
     381             : {
     382             :         uint32_t i;
     383             : 
     384      650417 :         for (i=0; i<(*num_sids); i++) {
     385      588254 :                 if (dom_sid_equal(sid, &(*sids)[i])) {
     386        8469 :                         return NT_STATUS_OK;
     387             :                 }
     388             :         }
     389             : 
     390       62163 :         return add_sid_to_array(mem_ctx, sid, sids, num_sids);
     391             : }
     392             : 
     393             : /********************************************************************
     394             :  Remove SID from an array
     395             : ********************************************************************/
     396             : 
     397         281 : void del_sid_from_array(const struct dom_sid *sid, struct dom_sid **sids,
     398             :                         uint32_t *num)
     399             : {
     400         281 :         struct dom_sid *sid_list = *sids;
     401             :         uint32_t i;
     402             : 
     403        2656 :         for ( i=0; i<*num; i++ ) {
     404             : 
     405             :                 /* if we find the SID, then decrement the count
     406             :                    and break out of the loop */
     407             : 
     408        2656 :                 if (dom_sid_equal(sid, &sid_list[i])) {
     409         281 :                         *num -= 1;
     410         281 :                         break;
     411             :                 }
     412             :         }
     413             : 
     414             :         /* This loop will copy the remainder of the array
     415             :            if i < num of sids in the array */
     416             : 
     417         281 :         for ( ; i<*num; i++ ) {
     418           0 :                 sid_copy( &sid_list[i], &sid_list[i+1] );
     419             :         }
     420             : 
     421         281 :         return;
     422             : }
     423             : 
     424           1 : bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
     425             :                              uint32_t rid, uint32_t **pp_rids, size_t *p_num)
     426             : {
     427             :         size_t i;
     428             : 
     429           1 :         for (i=0; i<*p_num; i++) {
     430           0 :                 if ((*pp_rids)[i] == rid)
     431           0 :                         return true;
     432             :         }
     433             : 
     434           1 :         *pp_rids = talloc_realloc(mem_ctx, *pp_rids, uint32_t, *p_num+1);
     435             : 
     436           1 :         if (*pp_rids == NULL) {
     437           0 :                 *p_num = 0;
     438           0 :                 return false;
     439             :         }
     440             : 
     441           1 :         (*pp_rids)[*p_num] = rid;
     442           1 :         *p_num += 1;
     443           1 :         return true;
     444             : }
     445             : 
     446       56666 : bool is_null_sid(const struct dom_sid *sid)
     447             : {
     448       56666 :         const struct dom_sid null_sid = {0};
     449       56666 :         return dom_sid_equal(sid, &null_sid);
     450             : }
     451             : 
     452             : /*
     453             :  * See [MS-LSAT] 3.1.1.1.1 Predefined Translation Database and Corresponding View
     454             :  */
     455             : struct predefined_name_mapping {
     456             :         const char *name;
     457             :         enum lsa_SidType type;
     458             :         struct dom_sid sid;
     459             : };
     460             : 
     461             : struct predefined_domain_mapping {
     462             :         const char *domain;
     463             :         struct dom_sid sid;
     464             :         size_t num_names;
     465             :         const struct predefined_name_mapping *names;
     466             : };
     467             : 
     468             : /* S-1-${AUTHORITY} */
     469             : #define _SID0(authority) \
     470             :         { 1, 0, {0,0,0,0,0,authority}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
     471             : /* S-1-${AUTHORITY}-${SUB1} */
     472             : #define _SID1(authority,sub1) \
     473             :         { 1, 1, {0,0,0,0,0,authority}, {sub1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
     474             : /* S-1-${AUTHORITY}-${SUB1}-${SUB2} */
     475             : #define _SID2(authority,sub1,sub2) \
     476             :         { 1, 2, {0,0,0,0,0,authority}, {sub1,sub2,0,0,0,0,0,0,0,0,0,0,0,0,0}}
     477             : 
     478             : /*
     479             :  * S-1-0
     480             :  */
     481             : static const struct predefined_name_mapping predefined_names_S_1_0[] = {
     482             :         {
     483             :                 .name = "NULL SID",
     484             :                 .type = SID_NAME_WKN_GRP,
     485             :                 .sid = _SID1(0, 0), /* S-1-0-0 */
     486             :         },
     487             : };
     488             : 
     489             : /*
     490             :  * S-1-1
     491             :  */
     492             : static const struct predefined_name_mapping predefined_names_S_1_1[] = {
     493             :         {
     494             :                 .name = "Everyone",
     495             :                 .type = SID_NAME_WKN_GRP,
     496             :                 .sid = _SID1(1, 0), /* S-1-1-0 */
     497             :         },
     498             : };
     499             : 
     500             : /*
     501             :  * S-1-2
     502             :  */
     503             : static const struct predefined_name_mapping predefined_names_S_1_2[] = {
     504             :         {
     505             :                 .name = "LOCAL",
     506             :                 .type = SID_NAME_WKN_GRP,
     507             :                 .sid = _SID1(2, 0), /* S-1-2-0 */
     508             :         },
     509             : };
     510             : 
     511             : /*
     512             :  * S-1-3
     513             :  */
     514             : static const struct predefined_name_mapping predefined_names_S_1_3[] = {
     515             :         {
     516             :                 .name = "CREATOR OWNER",
     517             :                 .type = SID_NAME_WKN_GRP,
     518             :                 .sid = _SID1(3, 0), /* S-1-3-0 */
     519             :         },
     520             :         {
     521             :                 .name = "CREATOR GROUP",
     522             :                 .type = SID_NAME_WKN_GRP,
     523             :                 .sid = _SID1(3, 1), /* S-1-3-1 */
     524             :         },
     525             :         {
     526             :                 .name = "CREATOR OWNER SERVER",
     527             :                 .type = SID_NAME_WKN_GRP,
     528             :                 .sid = _SID1(3, 0), /* S-1-3-2 */
     529             :         },
     530             :         {
     531             :                 .name = "CREATOR GROUP SERVER",
     532             :                 .type = SID_NAME_WKN_GRP,
     533             :                 .sid = _SID1(3, 1), /* S-1-3-3 */
     534             :         },
     535             :         {
     536             :                 .name = "OWNER RIGHTS",
     537             :                 .type = SID_NAME_WKN_GRP,
     538             :                 .sid = _SID1(3, 4), /* S-1-3-4 */
     539             :         },
     540             : };
     541             : 
     542             : /*
     543             :  * S-1-5 only 'NT Pseudo Domain'
     544             :  */
     545             : static const struct predefined_name_mapping predefined_names_S_1_5p[] = {
     546             :         {
     547             :                 .name = "NT Pseudo Domain",
     548             :                 .type = SID_NAME_DOMAIN,
     549             :                 .sid = _SID0(5), /* S-1-5 */
     550             :         },
     551             : };
     552             : 
     553             : /*
     554             :  * S-1-5 'NT AUTHORITY'
     555             :  */
     556             : static const struct predefined_name_mapping predefined_names_S_1_5a[] = {
     557             :         {
     558             :                 .name = "DIALUP",
     559             :                 .type = SID_NAME_WKN_GRP,
     560             :                 .sid = _SID1(5, 1), /* S-1-5-1 */
     561             :         },
     562             :         {
     563             :                 .name = "NETWORK",
     564             :                 .type = SID_NAME_WKN_GRP,
     565             :                 .sid = _SID1(5, 2), /* S-1-5-2 */
     566             :         },
     567             :         {
     568             :                 .name = "BATCH",
     569             :                 .type = SID_NAME_WKN_GRP,
     570             :                 .sid = _SID1(5, 3), /* S-1-5-3 */
     571             :         },
     572             :         {
     573             :                 .name = "INTERACTIVE",
     574             :                 .type = SID_NAME_WKN_GRP,
     575             :                 .sid = _SID1(5, 4), /* S-1-5-4 */
     576             :         },
     577             :         {
     578             :                 .name = "SERVICE",
     579             :                 .type = SID_NAME_WKN_GRP,
     580             :                 .sid = _SID1(5, 6), /* S-1-5-6 */
     581             :         },
     582             :         {
     583             :                 .name = "ANONYMOUS LOGON",
     584             :                 .type = SID_NAME_WKN_GRP,
     585             :                 .sid = _SID1(5, 7), /* S-1-5-7 */
     586             :         },
     587             :         {
     588             :                 .name = "PROXY",
     589             :                 .type = SID_NAME_WKN_GRP,
     590             :                 .sid = _SID1(5, 8), /* S-1-5-8 */
     591             :         },
     592             :         {
     593             :                 .name = "ENTERPRISE DOMAIN CONTROLLERS",
     594             :                 .type = SID_NAME_WKN_GRP,
     595             :                 .sid = _SID1(5, 9), /* S-1-5-9 */
     596             :         },
     597             :         {
     598             :                 .name = "SELF",
     599             :                 .type = SID_NAME_WKN_GRP,
     600             :                 .sid = _SID1(5, 10), /* S-1-5-10 */
     601             :         },
     602             :         {
     603             :                 .name = "Authenticated Users",
     604             :                 .type = SID_NAME_WKN_GRP,
     605             :                 .sid = _SID1(5, 11), /* S-1-5-11 */
     606             :         },
     607             :         {
     608             :                 .name = "RESTRICTED",
     609             :                 .type = SID_NAME_WKN_GRP,
     610             :                 .sid = _SID1(5, 12), /* S-1-5-12 */
     611             :         },
     612             :         {
     613             :                 .name = "TERMINAL SERVER USER",
     614             :                 .type = SID_NAME_WKN_GRP,
     615             :                 .sid = _SID1(5, 13), /* S-1-5-13 */
     616             :         },
     617             :         {
     618             :                 .name = "REMOTE INTERACTIVE LOGON",
     619             :                 .type = SID_NAME_WKN_GRP,
     620             :                 .sid = _SID1(5, 14), /* S-1-5-14 */
     621             :         },
     622             :         {
     623             :                 .name = "This Organization",
     624             :                 .type = SID_NAME_WKN_GRP,
     625             :                 .sid = _SID1(5, 15), /* S-1-5-15 */
     626             :         },
     627             :         {
     628             :                 .name = "IUSR",
     629             :                 .type = SID_NAME_WKN_GRP,
     630             :                 .sid = _SID1(5, 17), /* S-1-5-17 */
     631             :         },
     632             :         {
     633             :                 .name = "SYSTEM",
     634             :                 .type = SID_NAME_WKN_GRP,
     635             :                 .sid = _SID1(5, 18), /* S-1-5-18 */
     636             :         },
     637             :         {
     638             :                 .name = "LOCAL SERVICE",
     639             :                 .type = SID_NAME_WKN_GRP,
     640             :                 .sid = _SID1(5, 19), /* S-1-5-19 */
     641             :         },
     642             :         {
     643             :                 .name = "NETWORK SERVICE",
     644             :                 .type = SID_NAME_WKN_GRP,
     645             :                 .sid = _SID1(5, 20), /* S-1-5-20 */
     646             :         },
     647             :         {
     648             :                 .name = "WRITE RESTRICTED",
     649             :                 .type = SID_NAME_WKN_GRP,
     650             :                 .sid = _SID1(5, 33), /* S-1-5-33 */
     651             :         },
     652             :         {
     653             :                 .name = "Other Organization",
     654             :                 .type = SID_NAME_WKN_GRP,
     655             :                 .sid = _SID1(5, 1000), /* S-1-5-1000 */
     656             :         },
     657             : };
     658             : 
     659             : /*
     660             :  * S-1-5-32
     661             :  */
     662             : static const struct predefined_name_mapping predefined_names_S_1_5_32[] = {
     663             :         {
     664             :                 .name = "BUILTIN",
     665             :                 .type = SID_NAME_DOMAIN,
     666             :                 .sid = _SID1(5, 32), /* S-1-5-32 */
     667             :         },
     668             : };
     669             : 
     670             : /*
     671             :  * S-1-5-64
     672             :  */
     673             : static const struct predefined_name_mapping predefined_names_S_1_5_64[] = {
     674             :         {
     675             :                 .name = "NTLM Authentication",
     676             :                 .type = SID_NAME_WKN_GRP,
     677             :                 .sid = _SID2(5, 64, 10), /* S-1-5-64-10 */
     678             :         },
     679             :         {
     680             :                 .name = "SChannel Authentication",
     681             :                 .type = SID_NAME_WKN_GRP,
     682             :                 .sid = _SID2(5, 64, 14), /* S-1-5-64-14 */
     683             :         },
     684             :         {
     685             :                 .name = "Digest Authentication",
     686             :                 .type = SID_NAME_WKN_GRP,
     687             :                 .sid = _SID2(5, 64, 21), /* S-1-5-64-21 */
     688             :         },
     689             : };
     690             : 
     691             : /*
     692             :  * S-1-7
     693             :  */
     694             : static const struct predefined_name_mapping predefined_names_S_1_7[] = {
     695             :         {
     696             :                 .name = "Internet$",
     697             :                 .type = SID_NAME_DOMAIN,
     698             :                 .sid = _SID0(7), /* S-1-7 */
     699             :         },
     700             : };
     701             : 
     702             : /*
     703             :  * S-1-16
     704             :  */
     705             : static const struct predefined_name_mapping predefined_names_S_1_16[] = {
     706             :         {
     707             :                 .name = "Mandatory Label",
     708             :                 .type = SID_NAME_DOMAIN,
     709             :                 .sid = _SID0(16), /* S-1-16 */
     710             :         },
     711             :         {
     712             :                 .name = "Untrusted Mandatory Level",
     713             :                 .type = SID_NAME_LABEL,
     714             :                 .sid = _SID1(16, 0), /* S-1-16-0 */
     715             :         },
     716             :         {
     717             :                 .name = "Low Mandatory Level",
     718             :                 .type = SID_NAME_LABEL,
     719             :                 .sid = _SID1(16, 4096), /* S-1-16-4096 */
     720             :         },
     721             :         {
     722             :                 .name = "Medium Mandatory Level",
     723             :                 .type = SID_NAME_LABEL,
     724             :                 .sid = _SID1(16, 8192), /* S-1-16-8192 */
     725             :         },
     726             :         {
     727             :                 .name = "High Mandatory Level",
     728             :                 .type = SID_NAME_LABEL,
     729             :                 .sid = _SID1(16, 12288), /* S-1-16-12288 */
     730             :         },
     731             :         {
     732             :                 .name = "System Mandatory Level",
     733             :                 .type = SID_NAME_LABEL,
     734             :                 .sid = _SID1(16, 16384), /* S-1-16-16384 */
     735             :         },
     736             :         {
     737             :                 .name = "Protected Process Mandatory Level",
     738             :                 .type = SID_NAME_LABEL,
     739             :                 .sid = _SID1(16, 20480), /* S-1-16-20480 */
     740             :         },
     741             : };
     742             : 
     743             : static const struct predefined_domain_mapping predefined_domains[] = {
     744             :         {
     745             :                 .domain = "",
     746             :                 .sid = _SID0(0), /* S-1-0 */
     747             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_0),
     748             :                 .names = predefined_names_S_1_0,
     749             :         },
     750             :         {
     751             :                 .domain = "",
     752             :                 .sid = _SID0(1), /* S-1-1 */
     753             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_1),
     754             :                 .names = predefined_names_S_1_1,
     755             :         },
     756             :         {
     757             :                 .domain = "",
     758             :                 .sid = _SID0(2), /* S-1-2 */
     759             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_2),
     760             :                 .names = predefined_names_S_1_2,
     761             :         },
     762             :         {
     763             :                 .domain = "",
     764             :                 .sid = _SID0(3), /* S-1-3 */
     765             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_3),
     766             :                 .names = predefined_names_S_1_3,
     767             :         },
     768             :         {
     769             :                 .domain = "",
     770             :                 .sid = _SID0(3), /* S-1-3 */
     771             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_3),
     772             :                 .names = predefined_names_S_1_3,
     773             :         },
     774             :         /*
     775             :          * S-1-5 is split here
     776             :          *
     777             :          * 'NT Pseudo Domain' has precedence before 'NT AUTHORITY'.
     778             :          *
     779             :          * In a LookupSids with multiple sids e.g. S-1-5 and S-1-5-7
     780             :          * the domain section (struct lsa_DomainInfo) gets
     781             :          * 'NT Pseudo Domain' with S-1-5. If asked in reversed order
     782             :          * S-1-5-7 and then S-1-5, you get struct lsa_DomainInfo
     783             :          * with 'NT AUTHORITY' and S-1-5.
     784             :          */
     785             :         {
     786             :                 .domain = "NT Pseudo Domain",
     787             :                 .sid = _SID0(5), /* S-1-5 */
     788             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_5p),
     789             :                 .names = predefined_names_S_1_5p,
     790             :         },
     791             :         {
     792             :                 .domain = "NT AUTHORITY",
     793             :                 .sid = _SID0(5), /* S-1-5 */
     794             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_5a),
     795             :                 .names = predefined_names_S_1_5a,
     796             :         },
     797             :         {
     798             :                 .domain = "BUILTIN",
     799             :                 .sid = _SID1(5, 32), /* S-1-5-32 */
     800             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_5_32),
     801             :                 .names = predefined_names_S_1_5_32,
     802             :         },
     803             :         /*
     804             :          * 'NT AUTHORITY' again with S-1-5-64 this time
     805             :          */
     806             :         {
     807             :                 .domain = "NT AUTHORITY",
     808             :                 .sid = _SID1(5, 64), /* S-1-5-64 */
     809             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_5_64),
     810             :                 .names = predefined_names_S_1_5_64,
     811             :         },
     812             :         {
     813             :                 .domain = "Internet$",
     814             :                 .sid = _SID0(7), /* S-1-7 */
     815             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_7),
     816             :                 .names = predefined_names_S_1_7,
     817             :         },
     818             :         {
     819             :                 .domain = "Mandatory Label",
     820             :                 .sid = _SID0(16), /* S-1-16 */
     821             :                 .num_names = ARRAY_SIZE(predefined_names_S_1_16),
     822             :                 .names = predefined_names_S_1_16,
     823             :         },
     824             : };
     825             : 
     826       12061 : NTSTATUS dom_sid_lookup_predefined_name(const char *name,
     827             :                                         const struct dom_sid **sid,
     828             :                                         enum lsa_SidType *type,
     829             :                                         const struct dom_sid **authority_sid,
     830             :                                         const char **authority_name)
     831             : {
     832             :         size_t di;
     833       12061 :         const char *domain = "";
     834       12061 :         size_t domain_len = 0;
     835             :         const char *p;
     836             :         bool match;
     837             : 
     838       12061 :         *sid = NULL;
     839       12061 :         *type = SID_NAME_UNKNOWN;
     840       12061 :         *authority_sid = NULL;
     841       12061 :         *authority_name = NULL;
     842             : 
     843       12061 :         if (name == NULL) {
     844           3 :                 name = "";
     845             :         }
     846             : 
     847       12061 :         p = strchr(name, '\\');
     848       12061 :         if (p != NULL) {
     849         256 :                 domain = name;
     850         256 :                 domain_len = PTR_DIFF(p, domain);
     851         256 :                 name = p + 1;
     852             :         }
     853             : 
     854       12061 :         match = strequal(name, "");
     855       12061 :         if (match) {
     856             :                 /*
     857             :                  * Strange, but that's what W2012R2 does.
     858             :                  */
     859          54 :                 name = "BUILTIN";
     860             :         }
     861             : 
     862      144566 :         for (di = 0; di < ARRAY_SIZE(predefined_domains); di++) {
     863      132539 :                 const struct predefined_domain_mapping *d =
     864             :                         &predefined_domains[di];
     865             :                 size_t ni;
     866             : 
     867      132539 :                 if (domain_len != 0) {
     868             :                         int cmp;
     869             : 
     870        2771 :                         cmp = strncasecmp(d->domain, domain, domain_len);
     871        2771 :                         if (cmp != 0) {
     872        2750 :                                 continue;
     873             :                         }
     874             :                 }
     875             : 
     876     1340510 :                 for (ni = 0; ni < d->num_names; ni++) {
     877      542837 :                         const struct predefined_name_mapping *n =
     878      542837 :                                 &d->names[ni];
     879             : 
     880      542837 :                         match = strequal(n->name, name);
     881      542837 :                         if (!match) {
     882      542803 :                                 continue;
     883             :                         }
     884             : 
     885          34 :                         *sid = &n->sid;
     886          34 :                         *type = n->type;
     887          34 :                         *authority_sid = &d->sid;
     888          34 :                         *authority_name = d->domain;
     889          34 :                         return NT_STATUS_OK;
     890             :                 }
     891             :         }
     892             : 
     893       12027 :         return NT_STATUS_NONE_MAPPED;
     894             : }
     895             : 
     896        2661 : bool dom_sid_lookup_is_predefined_domain(const char *domain)
     897             : {
     898             :         size_t di;
     899             :         bool match;
     900             : 
     901        2661 :         if (domain == NULL) {
     902           0 :                 domain = "";
     903             :         }
     904             : 
     905        2661 :         match = strequal(domain, "");
     906        2661 :         if (match) {
     907             :                 /*
     908             :                  * Strange, but that's what W2012R2 does.
     909             :                  */
     910           0 :                 domain = "BUILTIN";
     911             :         }
     912             : 
     913       48158 :         for (di = 0; di < ARRAY_SIZE(predefined_domains); di++) {
     914       29047 :                 const struct predefined_domain_mapping *d =
     915             :                         &predefined_domains[di];
     916             :                 int cmp;
     917             : 
     918       29047 :                 cmp = strcasecmp(d->domain, domain);
     919       29047 :                 if (cmp != 0) {
     920       28991 :                         continue;
     921             :                 }
     922             : 
     923          56 :                 return true;
     924             :         }
     925             : 
     926        2605 :         return false;
     927             : }
     928             : 
     929       14172 : NTSTATUS dom_sid_lookup_predefined_sid(const struct dom_sid *sid,
     930             :                                        const char **name,
     931             :                                        enum lsa_SidType *type,
     932             :                                        const struct dom_sid **authority_sid,
     933             :                                        const char **authority_name)
     934             : {
     935             :         size_t di;
     936       14172 :         bool match_domain = false;
     937             : 
     938       14172 :         *name = NULL;
     939       14172 :         *type = SID_NAME_UNKNOWN;
     940       14172 :         *authority_sid = NULL;
     941       14172 :         *authority_name = NULL;
     942             : 
     943       14172 :         if (sid == NULL) {
     944           0 :                 return NT_STATUS_INVALID_SID;
     945             :         }
     946             : 
     947      168927 :         for (di = 0; di < ARRAY_SIZE(predefined_domains); di++) {
     948      154935 :                 const struct predefined_domain_mapping *d =
     949             :                         &predefined_domains[di];
     950             :                 size_t ni;
     951             :                 int cmp;
     952             : 
     953      154935 :                 cmp = dom_sid_compare_auth(&d->sid, sid);
     954      154935 :                 if (cmp != 0) {
     955      103148 :                         continue;
     956             :                 }
     957             : 
     958       51787 :                 match_domain = true;
     959             : 
     960      740433 :                 for (ni = 0; ni < d->num_names; ni++) {
     961      322805 :                         const struct predefined_name_mapping *n =
     962      322805 :                                 &d->names[ni];
     963             : 
     964      322805 :                         cmp = dom_sid_compare(&n->sid, sid);
     965      322805 :                         if (cmp != 0) {
     966      322625 :                                 continue;
     967             :                         }
     968             : 
     969         180 :                         *name = n->name;
     970         180 :                         *type = n->type;
     971         180 :                         *authority_sid = &d->sid;
     972         180 :                         *authority_name = d->domain;
     973         180 :                         return NT_STATUS_OK;
     974             :                 }
     975             :         }
     976             : 
     977       13992 :         if (!match_domain) {
     978        1130 :                 return NT_STATUS_INVALID_SID;
     979             :         }
     980             : 
     981       12862 :         return NT_STATUS_NONE_MAPPED;
     982             : }

Generated by: LCOV version 1.13