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
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.
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.
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/>.
27 #include "../librpc/gen_ndr/ndr_security.h"
28 #include "../librpc/gen_ndr/netlogon.h"
29 #include "../libcli/security/security.h"
35 * Some useful sids, more well known sids can be found at
36 * http://support.microsoft.com/kb/243330/EN-US/
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
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}};
141 * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
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}};
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}};
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}};
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 */
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}};
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, }};
165 /* Unused, left here for documentary purposes */
167 #define SECURITY_NULL_SID_AUTHORITY 0
168 #define SECURITY_WORLD_SID_AUTHORITY 1
169 #define SECURITY_LOCAL_SID_AUTHORITY 2
170 #define SECURITY_CREATOR_SID_AUTHORITY 3
171 #define SECURITY_NT_AUTHORITY 5
174 static struct dom_sid system_sid_array
[1] =
175 { { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
176 static const struct security_token system_token
= {
177 .num_sids
= ARRAY_SIZE(system_sid_array
),
178 .sids
= system_sid_array
,
179 .privilege_mask
= SE_ALL_PRIVS
182 /****************************************************************************
183 Lookup string names for SID types.
184 ****************************************************************************/
186 static const struct {
187 enum lsa_SidType sid_type
;
189 } sid_name_type
[] = {
190 {SID_NAME_USE_NONE
, "None"},
191 {SID_NAME_USER
, "User"},
192 {SID_NAME_DOM_GRP
, "Domain Group"},
193 {SID_NAME_DOMAIN
, "Domain"},
194 {SID_NAME_ALIAS
, "Local Group"},
195 {SID_NAME_WKN_GRP
, "Well-known Group"},
196 {SID_NAME_DELETED
, "Deleted Account"},
197 {SID_NAME_INVALID
, "Invalid Account"},
198 {SID_NAME_UNKNOWN
, "UNKNOWN"},
199 {SID_NAME_COMPUTER
, "Computer"},
200 {SID_NAME_LABEL
, "Mandatory Label"}
203 const char *sid_type_lookup(uint32_t sid_type
)
207 /* Look through list */
208 for (i
=0; i
< ARRAY_SIZE(sid_name_type
); i
++) {
209 if (sid_name_type
[i
].sid_type
== sid_type
) {
210 return sid_name_type
[i
].string
;
215 return "SID *TYPE* is INVALID";
218 /**************************************************************************
219 Create the SYSTEM token.
220 ***************************************************************************/
222 const struct security_token
*get_system_token(void)
224 return &system_token
;
227 bool sid_compose(struct dom_sid
*dst
, const struct dom_sid
*domain_sid
, uint32_t rid
)
229 sid_copy(dst
, domain_sid
);
230 return sid_append_rid(dst
, rid
);
233 /*****************************************************************
234 Removes the last rid from the end of a sid
235 *****************************************************************/
237 bool sid_split_rid(struct dom_sid
*sid
, uint32_t *rid
)
239 if (sid
->num_auths
> 0) {
242 *rid
= sid
->sub_auths
[sid
->num_auths
];
249 /*****************************************************************
250 Return the last rid from the end of a sid
251 *****************************************************************/
253 bool sid_peek_rid(const struct dom_sid
*sid
, uint32_t *rid
)
258 if (sid
->num_auths
> 0) {
259 *rid
= sid
->sub_auths
[sid
->num_auths
- 1];
265 /*****************************************************************
266 Return the last rid from the end of a sid
267 and check the sid against the exp_dom_sid
268 *****************************************************************/
270 bool sid_peek_check_rid(const struct dom_sid
*exp_dom_sid
, const struct dom_sid
*sid
, uint32_t *rid
)
272 if (!exp_dom_sid
|| !sid
|| !rid
)
275 if (sid
->num_auths
!= (exp_dom_sid
->num_auths
+1)) {
279 if (sid_compare_domain(exp_dom_sid
, sid
)!=0){
284 return sid_peek_rid(sid
, rid
);
287 /*****************************************************************
289 *****************************************************************/
291 void sid_copy(struct dom_sid
*dst
, const struct dom_sid
*src
)
295 *dst
= (struct dom_sid
) {
296 .sid_rev_num
= src
->sid_rev_num
,
297 .num_auths
= src
->num_auths
,
300 memcpy(&dst
->id_auth
[0], &src
->id_auth
[0], sizeof(src
->id_auth
));
302 for (i
= 0; i
< src
->num_auths
; i
++)
303 dst
->sub_auths
[i
] = src
->sub_auths
[i
];
306 /*****************************************************************
307 Parse a on-the-wire SID to a struct dom_sid.
308 *****************************************************************/
310 ssize_t
sid_parse(const uint8_t *inbuf
, size_t len
, struct dom_sid
*sid
)
312 DATA_BLOB in
= data_blob_const(inbuf
, len
);
313 enum ndr_err_code ndr_err
;
315 ndr_err
= ndr_pull_struct_blob_all(
316 &in
, NULL
, sid
, (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
317 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
320 return ndr_size_dom_sid(sid
, 0);
323 /*****************************************************************
324 See if 2 SIDs are in the same domain
325 this just compares the leading sub-auths
326 *****************************************************************/
328 int sid_compare_domain(const struct dom_sid
*sid1
, const struct dom_sid
*sid2
)
332 n
= MIN(sid1
->num_auths
, sid2
->num_auths
);
334 for (i
= n
-1; i
>= 0; --i
)
335 if (sid1
->sub_auths
[i
] != sid2
->sub_auths
[i
])
336 return sid1
->sub_auths
[i
] - sid2
->sub_auths
[i
];
338 return dom_sid_compare_auth(sid1
, sid2
);
341 /********************************************************************
342 Add SID to an array SIDs
343 ********************************************************************/
345 NTSTATUS
add_sid_to_array(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
,
346 struct dom_sid
**sids
, uint32_t *num
)
350 if ((*num
) == UINT32_MAX
) {
351 return NT_STATUS_INTEGER_OVERFLOW
;
354 tmp
= talloc_realloc(mem_ctx
, *sids
, struct dom_sid
, (*num
)+1);
357 return NT_STATUS_NO_MEMORY
;
361 sid_copy(&((*sids
)[*num
]), sid
);
368 /********************************************************************
369 Add SID to an array SIDs ensuring that it is not already there
370 ********************************************************************/
372 NTSTATUS
add_sid_to_array_unique(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
,
373 struct dom_sid
**sids
, uint32_t *num_sids
)
377 for (i
=0; i
<(*num_sids
); i
++) {
378 if (dom_sid_equal(sid
, &(*sids
)[i
])) {
383 return add_sid_to_array(mem_ctx
, sid
, sids
, num_sids
);
386 /********************************************************************
387 Remove SID from an array
388 ********************************************************************/
390 void del_sid_from_array(const struct dom_sid
*sid
, struct dom_sid
**sids
,
393 struct dom_sid
*sid_list
= *sids
;
396 for ( i
=0; i
<*num
; i
++ ) {
398 /* if we find the SID, then decrement the count
399 and break out of the loop */
401 if (dom_sid_equal(sid
, &sid_list
[i
])) {
407 /* This loop will copy the remainder of the array
408 if i < num of sids in the array */
410 for ( ; i
<*num
; i
++ ) {
411 sid_copy( &sid_list
[i
], &sid_list
[i
+1] );
417 bool add_rid_to_array_unique(TALLOC_CTX
*mem_ctx
,
418 uint32_t rid
, uint32_t **pp_rids
, size_t *p_num
)
422 for (i
=0; i
<*p_num
; i
++) {
423 if ((*pp_rids
)[i
] == rid
)
427 *pp_rids
= talloc_realloc(mem_ctx
, *pp_rids
, uint32_t, *p_num
+1);
429 if (*pp_rids
== NULL
) {
434 (*pp_rids
)[*p_num
] = rid
;
439 bool is_null_sid(const struct dom_sid
*sid
)
441 const struct dom_sid null_sid
= {0};
442 return dom_sid_equal(sid
, &null_sid
);
446 * See [MS-LSAT] 3.1.1.1.1 Predefined Translation Database and Corresponding View
448 struct predefined_name_mapping
{
450 enum lsa_SidType type
;
454 struct predefined_domain_mapping
{
458 const struct predefined_name_mapping
*names
;
461 /* S-1-${AUTHORITY} */
462 #define _SID0(authority) \
463 { 1, 0, {0,0,0,0,0,authority}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
464 /* S-1-${AUTHORITY}-${SUB1} */
465 #define _SID1(authority,sub1) \
466 { 1, 1, {0,0,0,0,0,authority}, {sub1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
467 /* S-1-${AUTHORITY}-${SUB1}-${SUB2} */
468 #define _SID2(authority,sub1,sub2) \
469 { 1, 2, {0,0,0,0,0,authority}, {sub1,sub2,0,0,0,0,0,0,0,0,0,0,0,0,0}}
474 static const struct predefined_name_mapping predefined_names_S_1_0
[] = {
477 .type
= SID_NAME_WKN_GRP
,
478 .sid
= _SID1(0, 0), /* S-1-0-0 */
485 static const struct predefined_name_mapping predefined_names_S_1_1
[] = {
488 .type
= SID_NAME_WKN_GRP
,
489 .sid
= _SID1(1, 0), /* S-1-1-0 */
496 static const struct predefined_name_mapping predefined_names_S_1_2
[] = {
499 .type
= SID_NAME_WKN_GRP
,
500 .sid
= _SID1(2, 0), /* S-1-2-0 */
507 static const struct predefined_name_mapping predefined_names_S_1_3
[] = {
509 .name
= "CREATOR OWNER",
510 .type
= SID_NAME_WKN_GRP
,
511 .sid
= _SID1(3, 0), /* S-1-3-0 */
514 .name
= "CREATOR GROUP",
515 .type
= SID_NAME_WKN_GRP
,
516 .sid
= _SID1(3, 1), /* S-1-3-1 */
519 .name
= "CREATOR OWNER SERVER",
520 .type
= SID_NAME_WKN_GRP
,
521 .sid
= _SID1(3, 0), /* S-1-3-2 */
524 .name
= "CREATOR GROUP SERVER",
525 .type
= SID_NAME_WKN_GRP
,
526 .sid
= _SID1(3, 1), /* S-1-3-3 */
529 .name
= "OWNER RIGHTS",
530 .type
= SID_NAME_WKN_GRP
,
531 .sid
= _SID1(3, 4), /* S-1-3-4 */
536 * S-1-5 only 'NT Pseudo Domain'
538 static const struct predefined_name_mapping predefined_names_S_1_5p
[] = {
540 .name
= "NT Pseudo Domain",
541 .type
= SID_NAME_DOMAIN
,
542 .sid
= _SID0(5), /* S-1-5 */
547 * S-1-5 'NT AUTHORITY'
549 static const struct predefined_name_mapping predefined_names_S_1_5a
[] = {
552 .type
= SID_NAME_WKN_GRP
,
553 .sid
= _SID1(5, 1), /* S-1-5-1 */
557 .type
= SID_NAME_WKN_GRP
,
558 .sid
= _SID1(5, 2), /* S-1-5-2 */
562 .type
= SID_NAME_WKN_GRP
,
563 .sid
= _SID1(5, 3), /* S-1-5-3 */
566 .name
= "INTERACTIVE",
567 .type
= SID_NAME_WKN_GRP
,
568 .sid
= _SID1(5, 4), /* S-1-5-4 */
572 .type
= SID_NAME_WKN_GRP
,
573 .sid
= _SID1(5, 6), /* S-1-5-6 */
576 .name
= "ANONYMOUS LOGON",
577 .type
= SID_NAME_WKN_GRP
,
578 .sid
= _SID1(5, 7), /* S-1-5-7 */
582 .type
= SID_NAME_WKN_GRP
,
583 .sid
= _SID1(5, 8), /* S-1-5-8 */
586 .name
= "ENTERPRISE DOMAIN CONTROLLERS",
587 .type
= SID_NAME_WKN_GRP
,
588 .sid
= _SID1(5, 9), /* S-1-5-9 */
592 .type
= SID_NAME_WKN_GRP
,
593 .sid
= _SID1(5, 10), /* S-1-5-10 */
596 .name
= "Authenticated Users",
597 .type
= SID_NAME_WKN_GRP
,
598 .sid
= _SID1(5, 11), /* S-1-5-11 */
601 .name
= "RESTRICTED",
602 .type
= SID_NAME_WKN_GRP
,
603 .sid
= _SID1(5, 12), /* S-1-5-12 */
606 .name
= "TERMINAL SERVER USER",
607 .type
= SID_NAME_WKN_GRP
,
608 .sid
= _SID1(5, 13), /* S-1-5-13 */
611 .name
= "REMOTE INTERACTIVE LOGON",
612 .type
= SID_NAME_WKN_GRP
,
613 .sid
= _SID1(5, 14), /* S-1-5-14 */
616 .name
= "This Organization",
617 .type
= SID_NAME_WKN_GRP
,
618 .sid
= _SID1(5, 15), /* S-1-5-15 */
622 .type
= SID_NAME_WKN_GRP
,
623 .sid
= _SID1(5, 17), /* S-1-5-17 */
627 .type
= SID_NAME_WKN_GRP
,
628 .sid
= _SID1(5, 18), /* S-1-5-18 */
631 .name
= "LOCAL SERVICE",
632 .type
= SID_NAME_WKN_GRP
,
633 .sid
= _SID1(5, 19), /* S-1-5-19 */
636 .name
= "NETWORK SERVICE",
637 .type
= SID_NAME_WKN_GRP
,
638 .sid
= _SID1(5, 20), /* S-1-5-20 */
641 .name
= "WRITE RESTRICTED",
642 .type
= SID_NAME_WKN_GRP
,
643 .sid
= _SID1(5, 33), /* S-1-5-33 */
646 .name
= "Other Organization",
647 .type
= SID_NAME_WKN_GRP
,
648 .sid
= _SID1(5, 1000), /* S-1-5-1000 */
655 static const struct predefined_name_mapping predefined_names_S_1_5_32
[] = {
658 .type
= SID_NAME_DOMAIN
,
659 .sid
= _SID1(5, 32), /* S-1-5-32 */
666 static const struct predefined_name_mapping predefined_names_S_1_5_64
[] = {
668 .name
= "NTLM Authentication",
669 .type
= SID_NAME_WKN_GRP
,
670 .sid
= _SID2(5, 64, 10), /* S-1-5-64-10 */
673 .name
= "SChannel Authentication",
674 .type
= SID_NAME_WKN_GRP
,
675 .sid
= _SID2(5, 64, 14), /* S-1-5-64-14 */
678 .name
= "Digest Authentication",
679 .type
= SID_NAME_WKN_GRP
,
680 .sid
= _SID2(5, 64, 21), /* S-1-5-64-21 */
687 static const struct predefined_name_mapping predefined_names_S_1_7
[] = {
690 .type
= SID_NAME_DOMAIN
,
691 .sid
= _SID0(7), /* S-1-7 */
698 static const struct predefined_name_mapping predefined_names_S_1_16
[] = {
700 .name
= "Mandatory Label",
701 .type
= SID_NAME_DOMAIN
,
702 .sid
= _SID0(16), /* S-1-16 */
705 .name
= "Untrusted Mandatory Level",
706 .type
= SID_NAME_LABEL
,
707 .sid
= _SID1(16, 0), /* S-1-16-0 */
710 .name
= "Low Mandatory Level",
711 .type
= SID_NAME_LABEL
,
712 .sid
= _SID1(16, 4096), /* S-1-16-4096 */
715 .name
= "Medium Mandatory Level",
716 .type
= SID_NAME_LABEL
,
717 .sid
= _SID1(16, 8192), /* S-1-16-8192 */
720 .name
= "High Mandatory Level",
721 .type
= SID_NAME_LABEL
,
722 .sid
= _SID1(16, 12288), /* S-1-16-12288 */
725 .name
= "System Mandatory Level",
726 .type
= SID_NAME_LABEL
,
727 .sid
= _SID1(16, 16384), /* S-1-16-16384 */
730 .name
= "Protected Process Mandatory Level",
731 .type
= SID_NAME_LABEL
,
732 .sid
= _SID1(16, 20480), /* S-1-16-20480 */
736 static const struct predefined_domain_mapping predefined_domains
[] = {
739 .sid
= _SID0(0), /* S-1-0 */
740 .num_names
= ARRAY_SIZE(predefined_names_S_1_0
),
741 .names
= predefined_names_S_1_0
,
745 .sid
= _SID0(1), /* S-1-1 */
746 .num_names
= ARRAY_SIZE(predefined_names_S_1_1
),
747 .names
= predefined_names_S_1_1
,
751 .sid
= _SID0(2), /* S-1-2 */
752 .num_names
= ARRAY_SIZE(predefined_names_S_1_2
),
753 .names
= predefined_names_S_1_2
,
757 .sid
= _SID0(3), /* S-1-3 */
758 .num_names
= ARRAY_SIZE(predefined_names_S_1_3
),
759 .names
= predefined_names_S_1_3
,
763 .sid
= _SID0(3), /* S-1-3 */
764 .num_names
= ARRAY_SIZE(predefined_names_S_1_3
),
765 .names
= predefined_names_S_1_3
,
768 * S-1-5 is split here
770 * 'NT Pseudo Domain' has precedence before 'NT AUTHORITY'.
772 * In a LookupSids with multiple sids e.g. S-1-5 and S-1-5-7
773 * the domain section (struct lsa_DomainInfo) gets
774 * 'NT Pseudo Domain' with S-1-5. If asked in reversed order
775 * S-1-5-7 and then S-1-5, you get struct lsa_DomainInfo
776 * with 'NT AUTHORITY' and S-1-5.
779 .domain
= "NT Pseudo Domain",
780 .sid
= _SID0(5), /* S-1-5 */
781 .num_names
= ARRAY_SIZE(predefined_names_S_1_5p
),
782 .names
= predefined_names_S_1_5p
,
785 .domain
= "NT AUTHORITY",
786 .sid
= _SID0(5), /* S-1-5 */
787 .num_names
= ARRAY_SIZE(predefined_names_S_1_5a
),
788 .names
= predefined_names_S_1_5a
,
792 .sid
= _SID1(5, 32), /* S-1-5-32 */
793 .num_names
= ARRAY_SIZE(predefined_names_S_1_5_32
),
794 .names
= predefined_names_S_1_5_32
,
797 * 'NT AUTHORITY' again with S-1-5-64 this time
800 .domain
= "NT AUTHORITY",
801 .sid
= _SID1(5, 64), /* S-1-5-64 */
802 .num_names
= ARRAY_SIZE(predefined_names_S_1_5_64
),
803 .names
= predefined_names_S_1_5_64
,
806 .domain
= "Internet$",
807 .sid
= _SID0(7), /* S-1-7 */
808 .num_names
= ARRAY_SIZE(predefined_names_S_1_7
),
809 .names
= predefined_names_S_1_7
,
812 .domain
= "Mandatory Label",
813 .sid
= _SID0(16), /* S-1-16 */
814 .num_names
= ARRAY_SIZE(predefined_names_S_1_16
),
815 .names
= predefined_names_S_1_16
,
819 NTSTATUS
dom_sid_lookup_predefined_name(const char *name
,
820 const struct dom_sid
**sid
,
821 enum lsa_SidType
*type
,
822 const struct dom_sid
**authority_sid
,
823 const char **authority_name
)
826 const char *domain
= "";
827 size_t domain_len
= 0;
832 *type
= SID_NAME_UNKNOWN
;
833 *authority_sid
= NULL
;
834 *authority_name
= NULL
;
840 p
= strchr(name
, '\\');
843 domain_len
= PTR_DIFF(p
, domain
);
847 match
= strequal(name
, "");
850 * Strange, but that's what W2012R2 does.
855 for (di
= 0; di
< ARRAY_SIZE(predefined_domains
); di
++) {
856 const struct predefined_domain_mapping
*d
=
857 &predefined_domains
[di
];
860 if (domain_len
!= 0) {
863 cmp
= strncasecmp(d
->domain
, domain
, domain_len
);
869 for (ni
= 0; ni
< d
->num_names
; ni
++) {
870 const struct predefined_name_mapping
*n
=
873 match
= strequal(n
->name
, name
);
880 *authority_sid
= &d
->sid
;
881 *authority_name
= d
->domain
;
886 return NT_STATUS_NONE_MAPPED
;
889 bool dom_sid_lookup_is_predefined_domain(const char *domain
)
894 if (domain
== NULL
) {
898 match
= strequal(domain
, "");
901 * Strange, but that's what W2012R2 does.
906 for (di
= 0; di
< ARRAY_SIZE(predefined_domains
); di
++) {
907 const struct predefined_domain_mapping
*d
=
908 &predefined_domains
[di
];
911 cmp
= strcasecmp(d
->domain
, domain
);
922 NTSTATUS
dom_sid_lookup_predefined_sid(const struct dom_sid
*sid
,
924 enum lsa_SidType
*type
,
925 const struct dom_sid
**authority_sid
,
926 const char **authority_name
)
929 bool match_domain
= false;
932 *type
= SID_NAME_UNKNOWN
;
933 *authority_sid
= NULL
;
934 *authority_name
= NULL
;
937 return NT_STATUS_INVALID_SID
;
940 for (di
= 0; di
< ARRAY_SIZE(predefined_domains
); di
++) {
941 const struct predefined_domain_mapping
*d
=
942 &predefined_domains
[di
];
946 cmp
= dom_sid_compare_auth(&d
->sid
, sid
);
953 for (ni
= 0; ni
< d
->num_names
; ni
++) {
954 const struct predefined_name_mapping
*n
=
957 cmp
= dom_sid_compare(&n
->sid
, sid
);
964 *authority_sid
= &d
->sid
;
965 *authority_name
= d
->domain
;
971 return NT_STATUS_INVALID_SID
;
974 return NT_STATUS_NONE_MAPPED
;