24
24
#include "includes.h"
25
#include "lib/privileges.h"
27
#include "libcli/security/privileges_private.h"
28
#include "../libcli/security/security.h"
26
31
#define PRIVPREFIX "PRIV_"
34
39
TALLOC_CTX *mem_ctx;
40
static bool get_privileges( const DOM_SID *sid, SE_PRIV *mask )
45
interpret an old style SE_PRIV structure
47
static uint64_t map_old_SE_PRIV(unsigned char *dptr)
49
uint32_t *old_masks = (uint32_t *)dptr;
51
* the old privileges code only ever used up to 0x800, except
52
* for a special case of 'SE_ALL_PRIVS' which was 0xFFFFFFFF
54
if (old_masks[0] == 0xFFFFFFFF) {
55
/* they set all privileges */
59
/* the old code used the machine byte order, but we don't know
60
* the byte order of the machine that wrote it. However we can
61
* tell what byte order it was by taking advantage of the fact
62
* that it only ever use up to 0x800
64
if (dptr[0] || dptr[1]) {
65
/* it was little endian */
69
/* it was either zero or big-endian */
70
return RIVAL(dptr, 0);
74
static bool get_privileges( const struct dom_sid *sid, uint64_t *mask )
42
76
struct db_context *db = get_account_pol_db();
43
77
fstring tmp, keystr;
59
93
data = dbwrap_fetch_bystring( db, talloc_tos(), keystr );
61
95
if ( !data.dptr ) {
62
DEBUG(3, ("get_privileges: No privileges assigned to SID "
96
DEBUG(4, ("get_privileges: No privileges assigned to SID "
63
97
"[%s]\n", sid_string_dbg(sid)));
67
SMB_ASSERT( data.dsize == sizeof( SE_PRIV ) );
69
se_priv_copy( mask, (SE_PRIV*)data.dptr );
101
if (data.dsize == 4*4) {
102
/* it's an old style SE_PRIV structure. */
103
*mask = map_old_SE_PRIV(data.dptr);
105
if (data.dsize != sizeof( uint64_t ) ) {
106
DEBUG(3, ("get_privileges: Invalid privileges record assigned to SID "
107
"[%s]\n", sid_string_dbg(sid)));
111
*mask = BVAL(data.dptr, 0);
70
114
TALLOC_FREE(data.dptr);
76
120
Store the privilege mask (set) for a given SID
77
121
****************************************************************************/
79
static bool set_privileges( const DOM_SID *sid, SE_PRIV *mask )
123
static bool set_privileges( const struct dom_sid *sid, uint64_t mask )
81
125
struct db_context *db = get_account_pol_db();
82
127
fstring tmp, keystr;
98
143
fstr_sprintf(keystr, "%s%s", PRIVPREFIX, sid_to_fstring(tmp, sid));
100
/* no packing. static size structure, just write it out */
145
/* This writes the 64 bit bitmask out in little endian format */
146
SBVAL(privbuf,0,mask);
102
data.dptr = (uint8 *)mask;
103
data.dsize = sizeof(SE_PRIV);
149
data.dsize = sizeof(privbuf);
105
151
return NT_STATUS_IS_OK(dbwrap_store_bystring(db, keystr, data,
110
156
get a list of all privileges for all sids in the list
111
157
*********************************************************************/
113
bool get_privileges_for_sids(SE_PRIV *privileges, DOM_SID *slist, int scount)
159
bool get_privileges_for_sids(uint64_t *privileges, struct dom_sid *slist, int scount)
117
163
bool found = False;
119
se_priv_copy( privileges, &se_priv_none );
121
167
for ( i=0; i<scount; i++ ) {
122
168
/* don't add unless we actually have a privilege assigned */
127
173
DEBUG(5,("get_privileges_for_sids: sid = %s\nPrivilege "
128
"set:\n", sid_string_dbg(&slist[i])));
129
dump_se_priv( DBGC_ALL, 5, &mask );
174
"set: 0x%llx\n", sid_string_dbg(&slist[i]),
175
(unsigned long long)mask));
131
se_priv_add( privileges, &mask );
184
NTSTATUS get_privileges_for_sid_as_set(TALLOC_CTX *mem_ctx, PRIVILEGE_SET **privileges, struct dom_sid *sid)
187
if (!get_privileges(sid, &mask)) {
188
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
191
*privileges = talloc_zero(mem_ctx, PRIVILEGE_SET);
193
return NT_STATUS_NO_MEMORY;
196
if (!se_priv_to_privilege_set(*privileges, mask)) {
197
return NT_STATUS_NO_MEMORY;
139
202
/*********************************************************************
140
203
traversal functions for privilege_enumerate_accounts
160
218
/* check to see if we are looking for a particular privilege */
162
if ( !se_priv_equal(&priv->privilege, &se_priv_none) ) {
165
se_priv_copy( &mask, (SE_PRIV*)rec->value.dptr );
220
fstrcpy( sid_string, (char *)&(rec->key.dptr[strlen(PRIVPREFIX)]) );
222
if (priv->privilege != 0) {
225
if (rec->value.dsize == 4*4) {
226
mask = map_old_SE_PRIV(rec->value.dptr);
228
if (rec->value.dsize != sizeof( uint64_t ) ) {
229
DEBUG(3, ("get_privileges: Invalid privileges record assigned to SID "
230
"[%s]\n", sid_string));
233
mask = BVAL(rec->value.dptr, 0);
167
236
/* if the SID does not have the specified privilege
168
237
then just return */
170
if ( !is_privilege_assigned( &mask, &priv->privilege) )
239
if ((mask & priv->privilege) == 0) {
174
fstrcpy( sid_string, (char *)&(rec->key.dptr[strlen(PRIVPREFIX)]) );
176
244
/* this is a last ditch safety check to preventing returning
177
245
and invalid SID (i've somehow run into this on development branches) */
199
267
Retreive list of privileged SIDs (for _lsa_enumerate_accounts()
200
268
*********************************************************************/
202
NTSTATUS privilege_enumerate_accounts(DOM_SID **sids, int *num_sids)
270
NTSTATUS privilege_enumerate_accounts(struct dom_sid **sids, int *num_sids)
204
272
struct db_context *db = get_account_pol_db();
205
273
PRIV_SID_LIST priv;
226
292
Retrieve list of SIDs granted a particular privilege
227
293
*********************************************************************/
229
NTSTATUS privilege_enum_sids(const SE_PRIV *mask, TALLOC_CTX *mem_ctx,
230
DOM_SID **sids, int *num_sids)
295
NTSTATUS privilege_enum_sids(enum sec_privilege privilege, TALLOC_CTX *mem_ctx,
296
struct dom_sid **sids, int *num_sids)
232
298
struct db_context *db = get_account_pol_db();
233
299
PRIV_SID_LIST priv;
255
321
Add privilege to sid
256
322
****************************************************************************/
258
bool grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
324
static bool grant_privilege_bitmap(const struct dom_sid *sid, const uint64_t priv_mask)
260
SE_PRIV old_mask, new_mask;
326
uint64_t old_mask, new_mask;
262
328
ZERO_STRUCT( old_mask );
263
329
ZERO_STRUCT( new_mask );
265
331
if ( get_privileges( sid, &old_mask ) )
266
se_priv_copy( &new_mask, &old_mask );
268
se_priv_copy( &new_mask, &se_priv_none );
270
se_priv_add( &new_mask, priv_mask );
336
new_mask |= priv_mask;
272
338
DEBUG(10,("grant_privilege: %s\n", sid_string_dbg(sid)));
274
DEBUGADD( 10, ("original privilege mask:\n"));
275
dump_se_priv( DBGC_ALL, 10, &old_mask );
277
DEBUGADD( 10, ("new privilege mask:\n"));
278
dump_se_priv( DBGC_ALL, 10, &new_mask );
280
return set_privileges( sid, &new_mask );
340
DEBUGADD( 10, ("original privilege mask: 0x%llx\n", (unsigned long long)new_mask));
342
DEBUGADD( 10, ("new privilege mask: 0x%llx\n", (unsigned long long)new_mask));
344
return set_privileges( sid, new_mask );
283
347
/*********************************************************************
284
348
Add a privilege based on its name
285
349
*********************************************************************/
287
bool grant_privilege_by_name(DOM_SID *sid, const char *name)
351
bool grant_privilege_by_name(const struct dom_sid *sid, const char *name)
291
355
if (! se_priv_from_name(name, &mask)) {
292
356
DEBUG(3, ("grant_privilege_by_name: "
297
return grant_privilege( sid, &mask );
361
return grant_privilege_bitmap( sid, mask );
364
/***************************************************************************
365
Grant a privilege set (list of LUID values) from a sid
366
****************************************************************************/
368
bool grant_privilege_set(const struct dom_sid *sid, struct lsa_PrivilegeSet *set)
370
uint64_t privilege_mask;
371
if (!privilege_set_to_se_priv(&privilege_mask, set)) {
374
return grant_privilege_bitmap(sid, privilege_mask);
300
377
/***************************************************************************
301
378
Remove privilege from sid
302
379
****************************************************************************/
304
bool revoke_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
381
static bool revoke_privilege_bitmap(const struct dom_sid *sid, const uint64_t priv_mask)
308
385
/* if the user has no privileges, then we can't revoke any */
313
390
DEBUG(10,("revoke_privilege: %s\n", sid_string_dbg(sid)));
315
DEBUGADD( 10, ("original privilege mask:\n"));
316
dump_se_priv( DBGC_ALL, 10, &mask );
318
se_priv_remove( &mask, priv_mask );
320
DEBUGADD( 10, ("new privilege mask:\n"));
321
dump_se_priv( DBGC_ALL, 10, &mask );
323
return set_privileges( sid, &mask );
392
DEBUGADD( 10, ("original privilege mask: 0x%llx\n", (unsigned long long)mask));
396
DEBUGADD( 10, ("new privilege mask: 0x%llx\n", (unsigned long long)mask));
398
return set_privileges( sid, mask );
401
/***************************************************************************
402
Remove a privilege set (list of LUID values) from a sid
403
****************************************************************************/
405
bool revoke_privilege_set(const struct dom_sid *sid, struct lsa_PrivilegeSet *set)
407
uint64_t privilege_mask;
408
if (!privilege_set_to_se_priv(&privilege_mask, set)) {
411
return revoke_privilege_bitmap(sid, privilege_mask);
326
414
/*********************************************************************
327
415
Revoke all privileges
328
416
*********************************************************************/
330
bool revoke_all_privileges( DOM_SID *sid )
418
bool revoke_all_privileges( const struct dom_sid *sid )
332
return revoke_privilege( sid, &se_priv_all );
420
return revoke_privilege_bitmap( sid, SE_ALL_PRIVS);
335
423
/*********************************************************************
336
424
Add a privilege based on its name
337
425
*********************************************************************/
339
bool revoke_privilege_by_name(DOM_SID *sid, const char *name)
427
bool revoke_privilege_by_name(const struct dom_sid *sid, const char *name)
343
431
if (! se_priv_from_name(name, &mask)) {
344
432
DEBUG(3, ("revoke_privilege_by_name: "
354
442
Retrieve the SIDs assigned to a given privilege
355
443
****************************************************************************/
357
NTSTATUS privilege_create_account(const DOM_SID *sid )
445
NTSTATUS privilege_create_account(const struct dom_sid *sid )
359
return ( grant_privilege(sid, &se_priv_none) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL);
447
return ( grant_privilege_bitmap(sid, 0) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL);
362
450
/***************************************************************************
387
475
return dbwrap_delete_bystring(db, keystr);
390
/****************************************************************************
391
initialise a privilege list and set the talloc context
392
****************************************************************************/
394
NTSTATUS privilege_set_init(PRIVILEGE_SET *priv_set)
398
ZERO_STRUCTP( priv_set );
400
mem_ctx = talloc_init("privilege set");
402
DEBUG(0,("privilege_set_init: failed to initialize talloc ctx!\n"));
403
return NT_STATUS_NO_MEMORY;
406
priv_set->mem_ctx = mem_ctx;
411
/****************************************************************************
412
initialise a privilege list and with someone else's talloc context
413
****************************************************************************/
415
NTSTATUS privilege_set_init_by_ctx(TALLOC_CTX *mem_ctx, PRIVILEGE_SET *priv_set)
417
ZERO_STRUCTP( priv_set );
419
priv_set->mem_ctx = mem_ctx;
420
priv_set->ext_ctx = True;
425
/****************************************************************************
426
Free all memory used by a PRIVILEGE_SET
427
****************************************************************************/
429
void privilege_set_free(PRIVILEGE_SET *priv_set)
434
if ( !( priv_set->ext_ctx ) )
435
talloc_destroy( priv_set->mem_ctx );
437
ZERO_STRUCTP( priv_set );
440
/****************************************************************************
441
duplicate alloc luid_attr
442
****************************************************************************/
444
NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_la, int count)
452
*new_la = TALLOC_ARRAY(mem_ctx, LUID_ATTR, count);
454
DEBUG(0,("dup_luid_attr: failed to alloc new LUID_ATTR array [%d]\n", count));
455
return NT_STATUS_NO_MEMORY;
461
for (i=0; i<count; i++) {
462
(*new_la)[i].luid.high = old_la[i].luid.high;
463
(*new_la)[i].luid.low = old_la[i].luid.low;
464
(*new_la)[i].attr = old_la[i].attr;
470
478
/*******************************************************************
471
479
*******************************************************************/
473
bool is_privileged_sid( const DOM_SID *sid )
481
bool is_privileged_sid( const struct dom_sid *sid )
477
485
return get_privileges( sid, &mask );
480
488
/*******************************************************************
481
489
*******************************************************************/
483
bool grant_all_privileges( const DOM_SID *sid )
491
bool grant_all_privileges( const struct dom_sid *sid )
487
if (!se_priv_put_all_privileges(&mask)) {
491
return grant_privilege( sid, &mask );
495
se_priv_put_all_privileges(&mask);
497
return grant_privilege_bitmap( sid, mask );