~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/lib/util_sid.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
10
 
      
 
10
 
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.
15
 
   
 
15
 
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.
20
 
   
 
20
 
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/>.
23
23
*/
24
24
 
25
25
#include "includes.h"
26
 
 
27
 
/*
28
 
 * Some useful sids, more well known sids can be found at
29
 
 * http://support.microsoft.com/kb/243330/EN-US/
30
 
 */
31
 
 
32
 
 
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}};
47
 
#if 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}};
51
 
#endif
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}};
54
 
 
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}};
61
 
 
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}};
84
 
 
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}};
89
 
 
90
 
/* Unused, left here for documentary purposes */
91
 
#if 0
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
97
 
#endif
98
 
 
99
 
/*
100
 
 * An NT compatible anonymous token.
101
 
 */
102
 
 
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 };
108
 
 
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 };
112
 
 
113
 
/****************************************************************************
114
 
 Lookup string names for SID types.
115
 
****************************************************************************/
116
 
 
117
 
static const struct {
118
 
        enum lsa_SidType sid_type;
119
 
        const char *string;
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"},
130
 
 
131
 
        {(enum lsa_SidType)0, NULL}
132
 
};
133
 
 
134
 
const char *sid_type_lookup(uint32 sid_type) 
135
 
{
136
 
        int i = 0;
137
 
 
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;
142
 
                i++;
143
 
        }
144
 
 
145
 
        /* Default return */
146
 
        return "SID *TYPE* is INVALID";
147
 
}
148
 
 
149
 
/**************************************************************************
150
 
 Create the SYSTEM token.
151
 
***************************************************************************/
152
 
 
153
 
NT_USER_TOKEN *get_system_token(void) 
154
 
{
155
 
        return &system_token;
156
 
}
157
 
 
158
 
/******************************************************************
159
 
 get the default domain/netbios name to be used when dealing 
160
 
 with our passdb list of accounts
161
 
******************************************************************/
162
 
 
163
 
const char *get_global_sam_name(void) 
164
 
{
165
 
        if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
166
 
                return lp_workgroup();
167
 
        }
168
 
        return global_myname();
169
 
}
 
26
#include "../librpc/gen_ndr/ndr_security.h"
 
27
#include "../librpc/gen_ndr/netlogon.h"
 
28
#include "../libcli/security/security.h"
 
29
 
170
30
 
171
31
/*****************************************************************
172
32
 Convert a SID to an ascii string.
173
33
*****************************************************************/
174
34
 
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)
176
36
{
177
 
        char *str = sid_string_talloc(talloc_tos(), sid);
178
 
        fstrcpy(sidstr_out, str);
179
 
        TALLOC_FREE(str);
 
37
        dom_sid_string_buf(sid, sidstr_out, sizeof(fstring));
180
38
        return sidstr_out;
181
39
}
182
40
 
183
41
/*****************************************************************
184
 
 Essentially a renamed dom_sid_string from librpc/ndr with a
185
 
 panic if it didn't work
186
 
 
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
*****************************************************************/
190
45
 
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)
192
47
{
193
48
        char *result = dom_sid_string(mem_ctx, sid);
194
49
        SMB_ASSERT(result != NULL);
199
54
 Useful function for debug lines.
200
55
*****************************************************************/
201
56
 
202
 
char *sid_string_dbg(const DOM_SID *sid)
 
57
char *sid_string_dbg(const struct dom_sid *sid)
203
58
{
204
59
        return sid_string_talloc(talloc_tos(), sid);
205
60
}
208
63
 Use with care!
209
64
*****************************************************************/
210
65
 
211
 
char *sid_string_tos(const DOM_SID *sid)
 
66
char *sid_string_tos(const struct dom_sid *sid)
212
67
{
213
68
        return sid_string_talloc(talloc_tos(), sid);
214
69
}
215
70
 
216
71
/*****************************************************************
217
 
 Convert a string to a SID. Returns True on success, False on fail.
218
 
*****************************************************************/  
219
 
   
220
 
bool string_to_sid(DOM_SID *sidout, const char *sidstr)
221
 
{
222
 
        const char *p;
223
 
        char *q;
224
 
        /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
225
 
        uint32 conv;
226
 
  
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));
229
 
                return False;
230
 
        }
231
 
 
232
 
        ZERO_STRUCTP(sidout);
233
 
 
234
 
        /* Get the revision number. */
235
 
        p = sidstr + 2;
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));
239
 
                return False;
240
 
        }
241
 
        sidout->sid_rev_num = (uint8) conv;
242
 
        q++;
243
 
 
244
 
        /* get identauth */
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));
248
 
                return False;
249
 
        }
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);
258
 
 
259
 
        q++;
260
 
        sidout->num_auths = 0;
261
 
 
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);
266
 
                if (*q == '\0')
267
 
                        break;
268
 
                q++;
269
 
        }
270
 
                
271
 
        return True;
272
 
}
273
 
 
274
 
DOM_SID *string_sid_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
275
 
{
276
 
        DOM_SID *result = TALLOC_P(mem_ctx, DOM_SID);
277
 
 
278
 
        if (result == NULL)
279
 
                return NULL;
280
 
 
281
 
        if (!string_to_sid(result, sidstr))
282
 
                return NULL;
283
 
 
284
 
        return result;
285
 
}
286
 
 
287
 
/*****************************************************************
288
 
 Add a rid to the end of a sid
289
 
*****************************************************************/  
290
 
 
291
 
bool sid_append_rid(DOM_SID *sid, uint32 rid)
292
 
{
293
 
        if (sid->num_auths < MAXSUBAUTHS) {
294
 
                sid->sub_auths[sid->num_auths++] = rid;
295
 
                return True;
296
 
        }
297
 
        return False;
298
 
}
299
 
 
300
 
bool sid_compose(DOM_SID *dst, const DOM_SID *domain_sid, uint32 rid)
301
 
{
302
 
        sid_copy(dst, domain_sid);
303
 
        return sid_append_rid(dst, rid);
304
 
}
305
 
 
306
 
/*****************************************************************
307
 
 Removes the last rid from the end of a sid
308
 
*****************************************************************/  
309
 
 
310
 
bool sid_split_rid(DOM_SID *sid, uint32 *rid)
311
 
{
312
 
        if (sid->num_auths > 0) {
313
 
                sid->num_auths--;
314
 
                *rid = sid->sub_auths[sid->num_auths];
315
 
                return True;
316
 
        }
317
 
        return False;
318
 
}
319
 
 
320
 
/*****************************************************************
321
 
 Return the last rid from the end of a sid
322
 
*****************************************************************/  
323
 
 
324
 
bool sid_peek_rid(const DOM_SID *sid, uint32 *rid)
325
 
{
326
 
        if (!sid || !rid)
327
 
                return False;           
328
 
        
329
 
        if (sid->num_auths > 0) {
330
 
                *rid = sid->sub_auths[sid->num_auths - 1];
331
 
                return True;
332
 
        }
333
 
        return False;
334
 
}
335
 
 
336
 
/*****************************************************************
337
 
 Return the last rid from the end of a sid
338
 
 and check the sid against the exp_dom_sid  
339
 
*****************************************************************/  
340
 
 
341
 
bool sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *rid)
342
 
{
343
 
        if (!exp_dom_sid || !sid || !rid)
344
 
                return False;
345
 
                        
346
 
        if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
347
 
                return False;
348
 
        }
349
 
 
350
 
        if (sid_compare_domain(exp_dom_sid, sid)!=0){
351
 
                *rid=(-1);
352
 
                return False;
353
 
        }
354
 
        
355
 
        return sid_peek_rid(sid, rid);
356
 
}
357
 
 
358
 
/*****************************************************************
359
 
 Copies a sid
360
 
*****************************************************************/  
361
 
 
362
 
void sid_copy(DOM_SID *dst, const DOM_SID *src)
363
 
{
364
 
        int i;
365
 
 
366
 
        ZERO_STRUCTP(dst);
367
 
 
368
 
        dst->sid_rev_num = src->sid_rev_num;
369
 
        dst->num_auths = src->num_auths;
370
 
 
371
 
        memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
372
 
 
373
 
        for (i = 0; i < src->num_auths; i++)
374
 
                dst->sub_auths[i] = src->sub_auths[i];
375
 
}
376
 
 
377
 
/*****************************************************************
378
72
 Write a sid out into on-the-wire format.
379
73
*****************************************************************/  
380
74
 
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)
382
76
{
383
77
        size_t i;
384
78
 
385
 
        if (len < ndr_size_dom_sid(sid, NULL, 0))
 
79
        if (len < ndr_size_dom_sid(sid, 0))
386
80
                return False;
387
81
 
388
82
        SCVAL(outbuf,0,sid->sid_rev_num);
395
89
}
396
90
 
397
91
/*****************************************************************
398
 
 Parse a on-the-wire SID to a DOM_SID.
399
 
*****************************************************************/  
400
 
 
401
 
bool sid_parse(const char *inbuf, size_t len, DOM_SID *sid)
402
 
{
403
 
        int i;
404
 
        if (len < 8)
405
 
                return False;
406
 
 
407
 
        ZERO_STRUCTP(sid);
408
 
 
409
 
        sid->sid_rev_num = CVAL(inbuf, 0);
410
 
        sid->num_auths = CVAL(inbuf, 1);
411
 
        if (sid->num_auths > MAXSUBAUTHS) {
412
 
                return false;
413
 
        }
414
 
        memcpy(sid->id_auth, inbuf+2, 6);
415
 
        if (len < 8 + sid->num_auths*4)
416
 
                return False;
417
 
        for (i=0;i<sid->num_auths;i++)
418
 
                sid->sub_auths[i] = IVAL(inbuf, 8+i*4);
419
 
        return True;
420
 
}
421
 
 
422
 
/*****************************************************************
423
 
 Compare the auth portion of two sids.
424
 
*****************************************************************/  
425
 
 
426
 
static int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
427
 
{
428
 
        int i;
429
 
 
430
 
        if (sid1 == sid2)
431
 
                return 0;
432
 
        if (!sid1)
433
 
                return -1;
434
 
        if (!sid2)
435
 
                return 1;
436
 
 
437
 
        if (sid1->sid_rev_num != sid2->sid_rev_num)
438
 
                return sid1->sid_rev_num - sid2->sid_rev_num;
439
 
 
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];
443
 
 
444
 
        return 0;
445
 
}
446
 
 
447
 
/*****************************************************************
448
 
 Compare two sids.
449
 
*****************************************************************/  
450
 
 
451
 
int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
452
 
{
453
 
        int i;
454
 
 
455
 
        if (sid1 == sid2)
456
 
                return 0;
457
 
        if (!sid1)
458
 
                return -1;
459
 
        if (!sid2)
460
 
                return 1;
461
 
 
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;
465
 
 
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];
469
 
 
470
 
        return sid_compare_auth(sid1, sid2);
471
 
}
472
 
 
473
 
/*****************************************************************
474
 
 See if 2 SIDs are in the same domain
475
 
 this just compares the leading sub-auths
476
 
*****************************************************************/  
477
 
 
478
 
int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
479
 
{
480
 
        int n, i;
481
 
 
482
 
        n = MIN(sid1->num_auths, sid2->num_auths);
483
 
 
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];
487
 
 
488
 
        return sid_compare_auth(sid1, sid2);
489
 
}
490
 
 
491
 
/*****************************************************************
492
 
 Compare two sids.
493
 
*****************************************************************/  
494
 
 
495
 
bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
496
 
{
497
 
        return sid_compare(sid1, sid2) == 0;
498
 
}
499
 
 
500
 
/*****************************************************************
501
92
 Returns true if SID is internal (and non-mappable).
502
93
*****************************************************************/
503
94
 
504
 
bool non_mappable_sid(DOM_SID *sid)
 
95
bool non_mappable_sid(struct dom_sid *sid)
505
96
{
506
 
        DOM_SID dom;
507
 
        uint32 rid;
 
97
        struct dom_sid dom;
508
98
 
509
99
        sid_copy(&dom, sid);
510
 
        sid_split_rid(&dom, &rid);
 
100
        sid_split_rid(&dom, NULL);
511
101
 
512
 
        if (sid_equal(&dom, &global_sid_Builtin))
 
102
        if (dom_sid_equal(&dom, &global_sid_Builtin))
513
103
                return True;
514
104
 
515
 
        if (sid_equal(&dom, &global_sid_NT_Authority))
 
105
        if (dom_sid_equal(&dom, &global_sid_NT_Authority))
516
106
                return True;
517
107
 
518
108
        return False;
519
109
}
520
110
 
521
111
/*****************************************************************
522
 
 Return the binary string representation of a DOM_SID.
523
 
 Caller must free.
524
 
*****************************************************************/
525
 
 
526
 
char *sid_binstring(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
527
 
{
528
 
        uint8_t *buf;
529
 
        char *s;
530
 
        int len = ndr_size_dom_sid(sid, NULL, 0);
531
 
        buf = talloc_array(mem_ctx, uint8_t, len);
532
 
        if (!buf) {
533
 
                return NULL;
534
 
        }
535
 
        sid_linearize((char *)buf, len, sid);
536
 
        s = binary_string_rfc2254(mem_ctx, buf, len);
537
 
        TALLOC_FREE(buf);
538
 
        return s;
539
 
}
540
 
 
541
 
/*****************************************************************
542
 
 Return the binary string representation of a DOM_SID.
543
 
 Caller must free.
544
 
*****************************************************************/
545
 
 
546
 
char *sid_binstring_hex(const DOM_SID *sid)
 
112
 Return the binary string representation of a struct dom_sid.
 
113
 Caller must free.
 
114
*****************************************************************/
 
115
 
 
116
char *sid_binstring_hex(const struct dom_sid *sid)
547
117
{
548
118
        char *buf, *s;
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);
551
121
        if (!buf)
552
122
                return NULL;
553
123
        sid_linearize(buf, len, sid);
554
 
        s = binary_string(buf, len);
 
124
        hex_encode((const unsigned char *)buf, len, &s);
555
125
        free(buf);
556
126
        return s;
557
127
}
558
128
 
559
 
/*******************************************************************
560
 
 Tallocs a duplicate SID. 
561
 
********************************************************************/ 
562
 
 
563
 
DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
564
 
{
565
 
        DOM_SID *dst;
566
 
        
567
 
        if(!src)
568
 
                return NULL;
569
 
        
570
 
        if((dst = TALLOC_ZERO_P(ctx, DOM_SID)) != NULL) {
571
 
                sid_copy( dst, src);
572
 
        }
573
 
        
574
 
        return dst;
575
 
}
576
 
 
577
 
/********************************************************************
578
 
 Add SID to an array SIDs
579
 
********************************************************************/
580
 
 
581
 
NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
582
 
                          DOM_SID **sids, size_t *num)
583
 
{
584
 
        *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
585
 
                                             (*num)+1);
586
 
        if (*sids == NULL) {
587
 
                *num = 0;
588
 
                return NT_STATUS_NO_MEMORY;
589
 
        }
590
 
 
591
 
        sid_copy(&((*sids)[*num]), sid);
592
 
        *num += 1;
593
 
 
594
 
        return NT_STATUS_OK;
595
 
}
596
 
 
597
 
 
598
 
/********************************************************************
599
 
 Add SID to an array SIDs ensuring that it is not already there
600
 
********************************************************************/
601
 
 
602
 
NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
603
 
                                 DOM_SID **sids, size_t *num_sids)
604
 
{
605
 
        size_t i;
606
 
 
607
 
        for (i=0; i<(*num_sids); i++) {
608
 
                if (sid_compare(sid, &(*sids)[i]) == 0)
609
 
                        return NT_STATUS_OK;
610
 
        }
611
 
 
612
 
        return add_sid_to_array(mem_ctx, sid, sids, num_sids);
613
 
}
614
 
 
615
 
/********************************************************************
616
 
 Remove SID from an array
617
 
********************************************************************/
618
 
 
619
 
void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num)
620
 
{
621
 
        DOM_SID *sid_list = *sids;
622
 
        size_t i;
623
 
 
624
 
        for ( i=0; i<*num; i++ ) {
625
 
 
626
 
                /* if we find the SID, then decrement the count
627
 
                   and break out of the loop */
628
 
 
629
 
                if ( sid_equal(sid, &sid_list[i]) ) {
630
 
                        *num -= 1;
631
 
                        break;
632
 
                }
633
 
        }
634
 
 
635
 
        /* This loop will copy the remainder of the array 
636
 
           if i < num of sids ni the array */
637
 
 
638
 
        for ( ; i<*num; i++ ) 
639
 
                sid_copy( &sid_list[i], &sid_list[i+1] );
640
 
        
641
 
        return;
642
 
}
643
 
 
644
 
bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
645
 
                                    uint32 rid, uint32 **pp_rids, size_t *p_num)
646
 
{
647
 
        size_t i;
648
 
 
649
 
        for (i=0; i<*p_num; i++) {
650
 
                if ((*pp_rids)[i] == rid)
651
 
                        return True;
652
 
        }
653
 
        
654
 
        *pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1);
655
 
 
656
 
        if (*pp_rids == NULL) {
657
 
                *p_num = 0;
658
 
                return False;
659
 
        }
660
 
 
661
 
        (*pp_rids)[*p_num] = rid;
662
 
        *p_num += 1;
663
 
        return True;
664
 
}
665
 
 
666
 
bool is_null_sid(const DOM_SID *sid)
667
 
{
668
 
        static const DOM_SID null_sid = {0};
669
 
        return sid_equal(sid, &null_sid);
670
 
}
671
 
 
672
 
bool is_sid_in_token(const NT_USER_TOKEN *token, const DOM_SID *sid)
673
 
{
674
 
        int i;
675
 
 
676
 
        for (i=0; i<token->num_sids; i++) {
677
 
                if (sid_compare(sid, &token->user_sids[i]) == 0)
678
 
                        return true;
679
 
        }
680
 
        return false;
681
 
}
682
 
 
683
129
NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx,
684
130
                              const struct netr_SamInfo3 *info3,
685
 
                              DOM_SID **user_sids,
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)
689
135
{
690
136
        NTSTATUS status;
691
 
        DOM_SID sid;
692
 
        DOM_SID *sid_array = NULL;
693
 
        size_t num_sids = 0;
 
137
        struct dom_sid sid;
 
138
        struct dom_sid *sid_array = NULL;
 
139
        uint32_t num_sids = 0;
694
140
        int i;
695
141
 
696
142
        if (include_user_group_rid) {