Changeset 740 for vendor/current/source3/lib/privileges.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/lib/privileges.c
r414 r740 23 23 24 24 #include "includes.h" 25 #include "lib/privileges.h" 26 #include "dbwrap.h" 27 #include "libcli/security/privileges_private.h" 28 #include "../libcli/security/security.h" 29 #include "passdb.h" 25 30 26 31 #define PRIVPREFIX "PRIV_" 27 32 28 33 typedef struct { 29 size_t count;30 DOM_SID*list;34 uint32_t count; 35 struct dom_sid *list; 31 36 } SID_LIST; 32 37 33 38 typedef struct { 34 39 TALLOC_CTX *mem_ctx; 35 SE_PRIVprivilege;40 uint64_t privilege; 36 41 SID_LIST sids; 37 42 } PRIV_SID_LIST; 38 43 39 40 static bool get_privileges( const DOM_SID *sid, SE_PRIV *mask ) 44 /* 45 interpret an old style SE_PRIV structure 46 */ 47 static uint64_t map_old_SE_PRIV(unsigned char *dptr) 48 { 49 uint32_t *old_masks = (uint32_t *)dptr; 50 /* 51 * the old privileges code only ever used up to 0x800, except 52 * for a special case of 'SE_ALL_PRIVS' which was 0xFFFFFFFF 53 */ 54 if (old_masks[0] == 0xFFFFFFFF) { 55 /* they set all privileges */ 56 return SE_ALL_PRIVS; 57 } 58 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 63 */ 64 if (dptr[0] || dptr[1]) { 65 /* it was little endian */ 66 return IVAL(dptr, 0); 67 } 68 69 /* it was either zero or big-endian */ 70 return RIVAL(dptr, 0); 71 } 72 73 74 static bool get_privileges( const struct dom_sid *sid, uint64_t *mask ) 41 75 { 42 76 struct db_context *db = get_account_pol_db(); … … 60 94 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))); 64 98 return False; 65 99 } 66 100 67 SMB_ASSERT( data.dsize == sizeof( SE_PRIV ) ); 68 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); 104 } else { 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))); 108 return False; 109 } 110 111 *mask = BVAL(data.dptr, 0); 112 } 113 70 114 TALLOC_FREE(data.dptr); 71 115 … … 77 121 ****************************************************************************/ 78 122 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 ) 80 124 { 81 125 struct db_context *db = get_account_pol_db(); 126 uint8_t privbuf[8]; 82 127 fstring tmp, keystr; 83 128 TDB_DATA data; … … 98 143 fstr_sprintf(keystr, "%s%s", PRIVPREFIX, sid_to_fstring(tmp, sid)); 99 144 100 /* no packing. static size structure, just write it out */ 101 102 data.dptr = (uint8 *)mask; 103 data.dsize = sizeof(SE_PRIV); 145 /* This writes the 64 bit bitmask out in little endian format */ 146 SBVAL(privbuf,0,mask); 147 148 data.dptr = privbuf; 149 data.dsize = sizeof(privbuf); 104 150 105 151 return NT_STATUS_IS_OK(dbwrap_store_bystring(db, keystr, data, … … 111 157 *********************************************************************/ 112 158 113 bool get_privileges_for_sids( SE_PRIV *privileges, DOM_SID*slist, int scount)114 { 115 SE_PRIVmask;159 bool get_privileges_for_sids(uint64_t *privileges, struct dom_sid *slist, int scount) 160 { 161 uint64_t mask; 116 162 int i; 117 163 bool found = False; 118 164 119 se_priv_copy( privileges, &se_priv_none );165 *privileges = 0; 120 166 121 167 for ( i=0; i<scount; i++ ) { … … 126 172 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);130 131 se_priv_add( privileges, &mask );174 "set: 0x%llx\n", sid_string_dbg(&slist[i]), 175 (unsigned long long)mask)); 176 177 *privileges |= mask; 132 178 found = True; 133 179 } … … 136 182 } 137 183 184 NTSTATUS get_privileges_for_sid_as_set(TALLOC_CTX *mem_ctx, PRIVILEGE_SET **privileges, struct dom_sid *sid) 185 { 186 uint64_t mask; 187 if (!get_privileges(sid, &mask)) { 188 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 189 } 190 191 *privileges = talloc_zero(mem_ctx, PRIVILEGE_SET); 192 if (!*privileges) { 193 return NT_STATUS_NO_MEMORY; 194 } 195 196 if (!se_priv_to_privilege_set(*privileges, mask)) { 197 return NT_STATUS_NO_MEMORY; 198 } 199 return NT_STATUS_OK; 200 } 138 201 139 202 /********************************************************************* … … 145 208 PRIV_SID_LIST *priv = (PRIV_SID_LIST *)state; 146 209 int prefixlen = strlen(PRIVPREFIX); 147 DOM_SIDsid;210 struct dom_sid sid; 148 211 fstring sid_string; 149 150 /* easy check first */151 152 if (rec->value.dsize != sizeof(SE_PRIV) )153 return 0;154 212 155 213 /* check we have a PRIV_+SID entry */ … … 160 218 /* check to see if we are looking for a particular privilege */ 161 219 162 if ( !se_priv_equal(&priv->privilege, &se_priv_none) ) { 163 SE_PRIV mask; 164 165 se_priv_copy( &mask, (SE_PRIV*)rec->value.dptr ); 220 fstrcpy( sid_string, (char *)&(rec->key.dptr[strlen(PRIVPREFIX)]) ); 221 222 if (priv->privilege != 0) { 223 uint64_t mask; 224 225 if (rec->value.dsize == 4*4) { 226 mask = map_old_SE_PRIV(rec->value.dptr); 227 } else { 228 if (rec->value.dsize != sizeof( uint64_t ) ) { 229 DEBUG(3, ("get_privileges: Invalid privileges record assigned to SID " 230 "[%s]\n", sid_string)); 231 return 0; 232 } 233 mask = BVAL(rec->value.dptr, 0); 234 } 166 235 167 236 /* if the SID does not have the specified privilege 168 237 then just return */ 169 238 170 if ( !is_privilege_assigned( &mask, &priv->privilege) )239 if ((mask & priv->privilege) == 0) { 171 240 return 0; 172 } 173 174 fstrcpy( sid_string, (char *)&(rec->key.dptr[strlen(PRIVPREFIX)]) ); 241 } 242 } 175 243 176 244 /* this is a last ditch safety check to preventing returning … … 200 268 *********************************************************************/ 201 269 202 NTSTATUS privilege_enumerate_accounts( DOM_SID**sids, int *num_sids)270 NTSTATUS privilege_enumerate_accounts(struct dom_sid **sids, int *num_sids) 203 271 { 204 272 struct db_context *db = get_account_pol_db(); … … 211 279 ZERO_STRUCT(priv); 212 280 213 se_priv_copy( &priv.privilege, &se_priv_none );214 215 281 db->traverse_read(db, priv_traverse_fn, &priv); 216 282 … … 227 293 *********************************************************************/ 228 294 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) 231 297 { 232 298 struct db_context *db = get_account_pol_db(); … … 239 305 ZERO_STRUCT(priv); 240 306 241 se_priv_copy(&priv.privilege, mask);307 priv.privilege = sec_privilege_mask(privilege); 242 308 priv.mem_ctx = mem_ctx; 243 309 … … 256 322 ****************************************************************************/ 257 323 258 bool grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)259 { 260 SE_PRIVold_mask, new_mask;324 static bool grant_privilege_bitmap(const struct dom_sid *sid, const uint64_t priv_mask) 325 { 326 uint64_t old_mask, new_mask; 261 327 262 328 ZERO_STRUCT( old_mask ); … … 264 330 265 331 if ( get_privileges( sid, &old_mask ) ) 266 se_priv_copy( &new_mask, &old_mask );332 new_mask = old_mask; 267 333 else 268 se_priv_copy( &new_mask, &se_priv_none );269 270 se_priv_add( &new_mask, priv_mask );334 new_mask = 0; 335 336 new_mask |= priv_mask; 271 337 272 338 DEBUG(10,("grant_privilege: %s\n", sid_string_dbg(sid))); 273 339 274 DEBUGADD( 10, ("original privilege mask:\n")); 275 dump_se_priv( DBGC_ALL, 10, &old_mask ); 276 277 DEBUGADD( 10, ("new privilege mask:\n")); 278 dump_se_priv( DBGC_ALL, 10, &new_mask ); 279 280 return set_privileges( sid, &new_mask ); 340 DEBUGADD( 10, ("original privilege mask: 0x%llx\n", (unsigned long long)new_mask)); 341 342 DEBUGADD( 10, ("new privilege mask: 0x%llx\n", (unsigned long long)new_mask)); 343 344 return set_privileges( sid, new_mask ); 281 345 } 282 346 … … 285 349 *********************************************************************/ 286 350 287 bool grant_privilege_by_name( DOM_SID*sid, const char *name)288 { 289 SE_PRIVmask;351 bool grant_privilege_by_name(const struct dom_sid *sid, const char *name) 352 { 353 uint64_t mask; 290 354 291 355 if (! se_priv_from_name(name, &mask)) { … … 295 359 } 296 360 297 return grant_privilege( sid, &mask ); 361 return grant_privilege_bitmap( sid, mask ); 362 } 363 364 /*************************************************************************** 365 Grant a privilege set (list of LUID values) from a sid 366 ****************************************************************************/ 367 368 bool grant_privilege_set(const struct dom_sid *sid, struct lsa_PrivilegeSet *set) 369 { 370 uint64_t privilege_mask; 371 if (!privilege_set_to_se_priv(&privilege_mask, set)) { 372 return false; 373 } 374 return grant_privilege_bitmap(sid, privilege_mask); 298 375 } 299 376 … … 302 379 ****************************************************************************/ 303 380 304 bool revoke_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)305 { 306 SE_PRIVmask;381 static bool revoke_privilege_bitmap(const struct dom_sid *sid, const uint64_t priv_mask) 382 { 383 uint64_t mask; 307 384 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))); 314 391 315 DEBUGADD( 10, ("original privilege mask:\n")); 316 dump_se_priv( DBGC_ALL, 10, &mask ); 317 318 se_priv_remove( &mask, priv_mask ); 319 320 DEBUGADD( 10, ("new privilege mask:\n")); 321 dump_se_priv( DBGC_ALL, 10, &mask ); 322 323 return set_privileges( sid, &mask ); 392 DEBUGADD( 10, ("original privilege mask: 0x%llx\n", (unsigned long long)mask)); 393 394 mask &= ~priv_mask; 395 396 DEBUGADD( 10, ("new privilege mask: 0x%llx\n", (unsigned long long)mask)); 397 398 return set_privileges( sid, mask ); 399 } 400 401 /*************************************************************************** 402 Remove a privilege set (list of LUID values) from a sid 403 ****************************************************************************/ 404 405 bool revoke_privilege_set(const struct dom_sid *sid, struct lsa_PrivilegeSet *set) 406 { 407 uint64_t privilege_mask; 408 if (!privilege_set_to_se_priv(&privilege_mask, set)) { 409 return false; 410 } 411 return revoke_privilege_bitmap(sid, privilege_mask); 324 412 } 325 413 … … 328 416 *********************************************************************/ 329 417 330 bool revoke_all_privileges( DOM_SID*sid )331 { 332 return revoke_privilege ( sid, &se_priv_all);418 bool revoke_all_privileges( const struct dom_sid *sid ) 419 { 420 return revoke_privilege_bitmap( sid, SE_ALL_PRIVS); 333 421 } 334 422 … … 337 425 *********************************************************************/ 338 426 339 bool revoke_privilege_by_name( DOM_SID*sid, const char *name)340 { 341 SE_PRIVmask;427 bool revoke_privilege_by_name(const struct dom_sid *sid, const char *name) 428 { 429 uint64_t mask; 342 430 343 431 if (! se_priv_from_name(name, &mask)) { … … 347 435 } 348 436 349 return revoke_privilege (sid, &mask);437 return revoke_privilege_bitmap(sid, mask); 350 438 351 439 } … … 355 443 ****************************************************************************/ 356 444 357 NTSTATUS privilege_create_account(const DOM_SID*sid )358 { 359 return ( grant_privilege (sid, &se_priv_none) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL);445 NTSTATUS privilege_create_account(const struct dom_sid *sid ) 446 { 447 return ( grant_privilege_bitmap(sid, 0) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL); 360 448 } 361 449 … … 388 476 } 389 477 390 /****************************************************************************391 initialise a privilege list and set the talloc context392 ****************************************************************************/393 394 NTSTATUS privilege_set_init(PRIVILEGE_SET *priv_set)395 {396 TALLOC_CTX *mem_ctx;397 398 ZERO_STRUCTP( priv_set );399 400 mem_ctx = talloc_init("privilege set");401 if ( !mem_ctx ) {402 DEBUG(0,("privilege_set_init: failed to initialize talloc ctx!\n"));403 return NT_STATUS_NO_MEMORY;404 }405 406 priv_set->mem_ctx = mem_ctx;407 408 return NT_STATUS_OK;409 }410 411 /****************************************************************************412 initialise a privilege list and with someone else's talloc context413 ****************************************************************************/414 415 NTSTATUS privilege_set_init_by_ctx(TALLOC_CTX *mem_ctx, PRIVILEGE_SET *priv_set)416 {417 ZERO_STRUCTP( priv_set );418 419 priv_set->mem_ctx = mem_ctx;420 priv_set->ext_ctx = True;421 422 return NT_STATUS_OK;423 }424 425 /****************************************************************************426 Free all memory used by a PRIVILEGE_SET427 ****************************************************************************/428 429 void privilege_set_free(PRIVILEGE_SET *priv_set)430 {431 if ( !priv_set )432 return;433 434 if ( !( priv_set->ext_ctx ) )435 talloc_destroy( priv_set->mem_ctx );436 437 ZERO_STRUCTP( priv_set );438 }439 440 /****************************************************************************441 duplicate alloc luid_attr442 ****************************************************************************/443 444 NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_la, int count)445 {446 int i;447 448 if ( !old_la )449 return NT_STATUS_OK;450 451 if (count) {452 *new_la = TALLOC_ARRAY(mem_ctx, LUID_ATTR, count);453 if ( !*new_la ) {454 DEBUG(0,("dup_luid_attr: failed to alloc new LUID_ATTR array [%d]\n", count));455 return NT_STATUS_NO_MEMORY;456 }457 } else {458 *new_la = NULL;459 }460 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;465 }466 467 return NT_STATUS_OK;468 }469 470 478 /******************************************************************* 471 479 *******************************************************************/ 472 480 473 bool is_privileged_sid( const DOM_SID*sid )474 { 475 SE_PRIVmask;481 bool is_privileged_sid( const struct dom_sid *sid ) 482 { 483 uint64_t mask; 476 484 477 485 return get_privileges( sid, &mask ); … … 481 489 *******************************************************************/ 482 490 483 bool grant_all_privileges( const DOM_SID *sid ) 484 { 485 SE_PRIV mask; 486 487 if (!se_priv_put_all_privileges(&mask)) { 488 return False; 489 } 490 491 return grant_privilege( sid, &mask ); 492 } 491 bool grant_all_privileges( const struct dom_sid *sid ) 492 { 493 uint64_t mask; 494 495 se_priv_put_all_privileges(&mask); 496 497 return grant_privilege_bitmap( sid, mask ); 498 }
Note:
See TracChangeset
for help on using the changeset viewer.