7
7
Copyright (C) Stefan (metze) Metzmacher 2002
8
8
Copyright (C) Simo Sorce 2002
9
9
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
11
11
This program is free software; you can redistribute it and/or modify
12
12
it under the terms of the GNU General Public License as published by
13
13
the Free Software Foundation; either version 3 of the License, or
14
14
(at your option) any later version.
16
16
This program is distributed in the hope that it will be useful,
17
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
19
GNU General Public License for more details.
21
21
You should have received a copy of the GNU General Public License
22
22
along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
#include "includes.h"
28
* Some useful sids, more well known sids can be found at
29
* http://support.microsoft.com/kb/243330/EN-US/
33
const DOM_SID global_sid_World_Domain = /* Everyone domain */
34
{ 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
35
const DOM_SID global_sid_World = /* Everyone */
36
{ 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
37
const DOM_SID global_sid_Creator_Owner_Domain = /* Creator Owner domain */
38
{ 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
39
const DOM_SID global_sid_NT_Authority = /* NT Authority */
40
{ 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
41
const DOM_SID global_sid_System = /* System */
42
{ 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
43
const DOM_SID global_sid_NULL = /* NULL sid */
44
{ 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
45
const DOM_SID global_sid_Authenticated_Users = /* All authenticated rids */
46
{ 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
48
/* for documentation */
49
const DOM_SID global_sid_Restriced = /* Restriced Code */
50
{ 1, 1, {0,0,0,0,0,5}, {12,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
52
const DOM_SID global_sid_Network = /* Network rids */
53
{ 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
55
const DOM_SID global_sid_Creator_Owner = /* Creator Owner */
56
{ 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
57
const DOM_SID global_sid_Creator_Group = /* Creator Group */
58
{ 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
59
const DOM_SID global_sid_Anonymous = /* Anonymous login */
60
{ 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
62
const DOM_SID global_sid_Builtin = /* Local well-known domain */
63
{ 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
64
const DOM_SID global_sid_Builtin_Administrators = /* Builtin administrators */
65
{ 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}};
66
const DOM_SID global_sid_Builtin_Users = /* Builtin users */
67
{ 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}};
68
const DOM_SID global_sid_Builtin_Guests = /* Builtin guest users */
69
{ 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}};
70
const DOM_SID global_sid_Builtin_Power_Users = /* Builtin power users */
71
{ 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}};
72
const DOM_SID global_sid_Builtin_Account_Operators = /* Builtin account operators */
73
{ 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}};
74
const DOM_SID global_sid_Builtin_Server_Operators = /* Builtin server operators */
75
{ 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}};
76
const DOM_SID global_sid_Builtin_Print_Operators = /* Builtin print operators */
77
{ 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}};
78
const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators */
79
{ 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
80
const DOM_SID global_sid_Builtin_Replicator = /* Builtin replicator */
81
{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
82
const DOM_SID global_sid_Builtin_PreWin2kAccess = /* Builtin pre win2k access */
83
{ 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}};
85
const DOM_SID global_sid_Unix_Users = /* Unmapped Unix users */
86
{ 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
87
const DOM_SID global_sid_Unix_Groups = /* Unmapped Unix groups */
88
{ 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
90
/* Unused, left here for documentary purposes */
92
#define SECURITY_NULL_SID_AUTHORITY 0
93
#define SECURITY_WORLD_SID_AUTHORITY 1
94
#define SECURITY_LOCAL_SID_AUTHORITY 2
95
#define SECURITY_CREATOR_SID_AUTHORITY 3
96
#define SECURITY_NT_AUTHORITY 5
100
* An NT compatible anonymous token.
103
static DOM_SID anon_sid_array[3] =
104
{ { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
105
{ 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
106
{ 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
107
NT_USER_TOKEN anonymous_token = { 3, anon_sid_array, SE_NONE };
109
static DOM_SID system_sid_array[1] =
110
{ { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
111
NT_USER_TOKEN system_token = { 1, system_sid_array, SE_ALL_PRIVS };
113
/****************************************************************************
114
Lookup string names for SID types.
115
****************************************************************************/
117
static const struct {
118
enum lsa_SidType sid_type;
120
} sid_name_type[] = {
121
{SID_NAME_USER, "User"},
122
{SID_NAME_DOM_GRP, "Domain Group"},
123
{SID_NAME_DOMAIN, "Domain"},
124
{SID_NAME_ALIAS, "Local Group"},
125
{SID_NAME_WKN_GRP, "Well-known Group"},
126
{SID_NAME_DELETED, "Deleted Account"},
127
{SID_NAME_INVALID, "Invalid Account"},
128
{SID_NAME_UNKNOWN, "UNKNOWN"},
129
{SID_NAME_COMPUTER, "Computer"},
131
{(enum lsa_SidType)0, NULL}
134
const char *sid_type_lookup(uint32 sid_type)
138
/* Look through list */
139
while(sid_name_type[i].sid_type != 0) {
140
if (sid_name_type[i].sid_type == sid_type)
141
return sid_name_type[i].string;
146
return "SID *TYPE* is INVALID";
149
/**************************************************************************
150
Create the SYSTEM token.
151
***************************************************************************/
153
NT_USER_TOKEN *get_system_token(void)
155
return &system_token;
158
/******************************************************************
159
get the default domain/netbios name to be used when dealing
160
with our passdb list of accounts
161
******************************************************************/
163
const char *get_global_sam_name(void)
165
if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
166
return lp_workgroup();
168
return global_myname();
26
#include "../librpc/gen_ndr/ndr_security.h"
27
#include "../librpc/gen_ndr/netlogon.h"
28
#include "../libcli/security/security.h"
171
31
/*****************************************************************
172
32
Convert a SID to an ascii string.
173
33
*****************************************************************/
175
char *sid_to_fstring(fstring sidstr_out, const DOM_SID *sid)
35
char *sid_to_fstring(fstring sidstr_out, const struct dom_sid *sid)
177
char *str = sid_string_talloc(talloc_tos(), sid);
178
fstrcpy(sidstr_out, str);
37
dom_sid_string_buf(sid, sidstr_out, sizeof(fstring));
180
38
return sidstr_out;
183
41
/*****************************************************************
184
Essentially a renamed dom_sid_string from librpc/ndr with a
185
panic if it didn't work
187
This introduces a dependency on librpc/ndr/sid.o which can easily
188
be turned around if necessary
42
Essentially a renamed dom_sid_string from
43
../libcli/security/dom_sid.c with a panic if it didn't work.
189
44
*****************************************************************/
191
char *sid_string_talloc(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
46
char *sid_string_talloc(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
193
48
char *result = dom_sid_string(mem_ctx, sid);
194
49
SMB_ASSERT(result != NULL);
209
64
*****************************************************************/
211
char *sid_string_tos(const DOM_SID *sid)
66
char *sid_string_tos(const struct dom_sid *sid)
213
68
return sid_string_talloc(talloc_tos(), sid);
216
71
/*****************************************************************
217
Convert a string to a SID. Returns True on success, False on fail.
218
*****************************************************************/
220
bool string_to_sid(DOM_SID *sidout, const char *sidstr)
224
/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
227
if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
228
DEBUG(3,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
232
ZERO_STRUCTP(sidout);
234
/* Get the revision number. */
236
conv = (uint32) strtoul(p, &q, 10);
237
if (!q || (*q != '-')) {
238
DEBUG(3,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
241
sidout->sid_rev_num = (uint8) conv;
245
conv = (uint32) strtoul(q, &q, 10);
246
if (!q || (*q != '-')) {
247
DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
250
/* identauth in decimal should be < 2^32 */
251
/* NOTE - the conv value is in big-endian format. */
252
sidout->id_auth[0] = 0;
253
sidout->id_auth[1] = 0;
254
sidout->id_auth[2] = (conv & 0xff000000) >> 24;
255
sidout->id_auth[3] = (conv & 0x00ff0000) >> 16;
256
sidout->id_auth[4] = (conv & 0x0000ff00) >> 8;
257
sidout->id_auth[5] = (conv & 0x000000ff);
260
sidout->num_auths = 0;
262
for(conv = (uint32) strtoul(q, &q, 10);
263
q && (*q =='-' || *q =='\0') && (sidout->num_auths < MAXSUBAUTHS);
264
conv = (uint32) strtoul(q, &q, 10)) {
265
sid_append_rid(sidout, conv);
274
DOM_SID *string_sid_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
276
DOM_SID *result = TALLOC_P(mem_ctx, DOM_SID);
281
if (!string_to_sid(result, sidstr))
287
/*****************************************************************
288
Add a rid to the end of a sid
289
*****************************************************************/
291
bool sid_append_rid(DOM_SID *sid, uint32 rid)
293
if (sid->num_auths < MAXSUBAUTHS) {
294
sid->sub_auths[sid->num_auths++] = rid;
300
bool sid_compose(DOM_SID *dst, const DOM_SID *domain_sid, uint32 rid)
302
sid_copy(dst, domain_sid);
303
return sid_append_rid(dst, rid);
306
/*****************************************************************
307
Removes the last rid from the end of a sid
308
*****************************************************************/
310
bool sid_split_rid(DOM_SID *sid, uint32 *rid)
312
if (sid->num_auths > 0) {
314
*rid = sid->sub_auths[sid->num_auths];
320
/*****************************************************************
321
Return the last rid from the end of a sid
322
*****************************************************************/
324
bool sid_peek_rid(const DOM_SID *sid, uint32 *rid)
329
if (sid->num_auths > 0) {
330
*rid = sid->sub_auths[sid->num_auths - 1];
336
/*****************************************************************
337
Return the last rid from the end of a sid
338
and check the sid against the exp_dom_sid
339
*****************************************************************/
341
bool sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *rid)
343
if (!exp_dom_sid || !sid || !rid)
346
if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
350
if (sid_compare_domain(exp_dom_sid, sid)!=0){
355
return sid_peek_rid(sid, rid);
358
/*****************************************************************
360
*****************************************************************/
362
void sid_copy(DOM_SID *dst, const DOM_SID *src)
368
dst->sid_rev_num = src->sid_rev_num;
369
dst->num_auths = src->num_auths;
371
memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
373
for (i = 0; i < src->num_auths; i++)
374
dst->sub_auths[i] = src->sub_auths[i];
377
/*****************************************************************
378
72
Write a sid out into on-the-wire format.
379
73
*****************************************************************/
381
bool sid_linearize(char *outbuf, size_t len, const DOM_SID *sid)
75
bool sid_linearize(char *outbuf, size_t len, const struct dom_sid *sid)
385
if (len < ndr_size_dom_sid(sid, NULL, 0))
79
if (len < ndr_size_dom_sid(sid, 0))
388
82
SCVAL(outbuf,0,sid->sid_rev_num);
397
91
/*****************************************************************
398
Parse a on-the-wire SID to a DOM_SID.
399
*****************************************************************/
401
bool sid_parse(const char *inbuf, size_t len, DOM_SID *sid)
409
sid->sid_rev_num = CVAL(inbuf, 0);
410
sid->num_auths = CVAL(inbuf, 1);
411
if (sid->num_auths > MAXSUBAUTHS) {
414
memcpy(sid->id_auth, inbuf+2, 6);
415
if (len < 8 + sid->num_auths*4)
417
for (i=0;i<sid->num_auths;i++)
418
sid->sub_auths[i] = IVAL(inbuf, 8+i*4);
422
/*****************************************************************
423
Compare the auth portion of two sids.
424
*****************************************************************/
426
static int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
437
if (sid1->sid_rev_num != sid2->sid_rev_num)
438
return sid1->sid_rev_num - sid2->sid_rev_num;
440
for (i = 0; i < 6; i++)
441
if (sid1->id_auth[i] != sid2->id_auth[i])
442
return sid1->id_auth[i] - sid2->id_auth[i];
447
/*****************************************************************
449
*****************************************************************/
451
int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
462
/* Compare most likely different rids, first: i.e start at end */
463
if (sid1->num_auths != sid2->num_auths)
464
return sid1->num_auths - sid2->num_auths;
466
for (i = sid1->num_auths-1; i >= 0; --i)
467
if (sid1->sub_auths[i] != sid2->sub_auths[i])
468
return sid1->sub_auths[i] - sid2->sub_auths[i];
470
return sid_compare_auth(sid1, sid2);
473
/*****************************************************************
474
See if 2 SIDs are in the same domain
475
this just compares the leading sub-auths
476
*****************************************************************/
478
int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
482
n = MIN(sid1->num_auths, sid2->num_auths);
484
for (i = n-1; i >= 0; --i)
485
if (sid1->sub_auths[i] != sid2->sub_auths[i])
486
return sid1->sub_auths[i] - sid2->sub_auths[i];
488
return sid_compare_auth(sid1, sid2);
491
/*****************************************************************
493
*****************************************************************/
495
bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
497
return sid_compare(sid1, sid2) == 0;
500
/*****************************************************************
501
92
Returns true if SID is internal (and non-mappable).
502
93
*****************************************************************/
504
bool non_mappable_sid(DOM_SID *sid)
95
bool non_mappable_sid(struct dom_sid *sid)
509
99
sid_copy(&dom, sid);
510
sid_split_rid(&dom, &rid);
100
sid_split_rid(&dom, NULL);
512
if (sid_equal(&dom, &global_sid_Builtin))
102
if (dom_sid_equal(&dom, &global_sid_Builtin))
515
if (sid_equal(&dom, &global_sid_NT_Authority))
105
if (dom_sid_equal(&dom, &global_sid_NT_Authority))
521
111
/*****************************************************************
522
Return the binary string representation of a DOM_SID.
524
*****************************************************************/
526
char *sid_binstring(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
530
int len = ndr_size_dom_sid(sid, NULL, 0);
531
buf = talloc_array(mem_ctx, uint8_t, len);
535
sid_linearize((char *)buf, len, sid);
536
s = binary_string_rfc2254(mem_ctx, buf, len);
541
/*****************************************************************
542
Return the binary string representation of a DOM_SID.
544
*****************************************************************/
546
char *sid_binstring_hex(const DOM_SID *sid)
112
Return the binary string representation of a struct dom_sid.
114
*****************************************************************/
116
char *sid_binstring_hex(const struct dom_sid *sid)
549
int len = ndr_size_dom_sid(sid, NULL, 0);
119
int len = ndr_size_dom_sid(sid, 0);
550
120
buf = (char *)SMB_MALLOC(len);
553
123
sid_linearize(buf, len, sid);
554
s = binary_string(buf, len);
124
hex_encode((const unsigned char *)buf, len, &s);
559
/*******************************************************************
560
Tallocs a duplicate SID.
561
********************************************************************/
563
DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
570
if((dst = TALLOC_ZERO_P(ctx, DOM_SID)) != NULL) {
577
/********************************************************************
578
Add SID to an array SIDs
579
********************************************************************/
581
NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
582
DOM_SID **sids, size_t *num)
584
*sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
588
return NT_STATUS_NO_MEMORY;
591
sid_copy(&((*sids)[*num]), sid);
598
/********************************************************************
599
Add SID to an array SIDs ensuring that it is not already there
600
********************************************************************/
602
NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
603
DOM_SID **sids, size_t *num_sids)
607
for (i=0; i<(*num_sids); i++) {
608
if (sid_compare(sid, &(*sids)[i]) == 0)
612
return add_sid_to_array(mem_ctx, sid, sids, num_sids);
615
/********************************************************************
616
Remove SID from an array
617
********************************************************************/
619
void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num)
621
DOM_SID *sid_list = *sids;
624
for ( i=0; i<*num; i++ ) {
626
/* if we find the SID, then decrement the count
627
and break out of the loop */
629
if ( sid_equal(sid, &sid_list[i]) ) {
635
/* This loop will copy the remainder of the array
636
if i < num of sids ni the array */
638
for ( ; i<*num; i++ )
639
sid_copy( &sid_list[i], &sid_list[i+1] );
644
bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
645
uint32 rid, uint32 **pp_rids, size_t *p_num)
649
for (i=0; i<*p_num; i++) {
650
if ((*pp_rids)[i] == rid)
654
*pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1);
656
if (*pp_rids == NULL) {
661
(*pp_rids)[*p_num] = rid;
666
bool is_null_sid(const DOM_SID *sid)
668
static const DOM_SID null_sid = {0};
669
return sid_equal(sid, &null_sid);
672
bool is_sid_in_token(const NT_USER_TOKEN *token, const DOM_SID *sid)
676
for (i=0; i<token->num_sids; i++) {
677
if (sid_compare(sid, &token->user_sids[i]) == 0)
683
129
NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx,
684
130
const struct netr_SamInfo3 *info3,
686
size_t *num_user_sids,
131
struct dom_sid **user_sids,
132
uint32_t *num_user_sids,
687
133
bool include_user_group_rid,
688
134
bool skip_ressource_groups)
692
DOM_SID *sid_array = NULL;
138
struct dom_sid *sid_array = NULL;
139
uint32_t num_sids = 0;
696
142
if (include_user_group_rid) {