static bool is_any_privilege_assigned( SE_PRIV *privileges, const SE_PRIV *check ) { SE_PRIV p1, p2; if ( !privileges || !check ) return False; /* everyone has privileges if you aren't checking for any */ if ( se_priv_empty( check ) ) { DEBUG(1,("is_any_privilege_assigned: no privileges in check_mask!\n")); return True; } se_priv_copy( &p1, check ); /* invert the SE_PRIV we want to check for and remove that from the original set. If we are left with the SE_PRIV we are checking for then return True */ se_priv_invert( &p1, check ); se_priv_copy( &p2, privileges ); se_priv_remove( &p2, &p1 ); /* see if we have any bits left */ return !se_priv_empty( &p2 ); }
static void se_priv_invert( SE_PRIV *new_mask, const SE_PRIV *mask ) { SE_PRIV allprivs; se_priv_copy( &allprivs, &se_priv_all ); se_priv_remove( &allprivs, mask ); se_priv_copy( new_mask, &allprivs ); }
static bool get_privileges( const DOM_SID *sid, SE_PRIV *mask ) { struct db_context *db = get_account_pol_db(); fstring tmp, keystr; TDB_DATA data; /* Fail if the admin has not enable privileges */ if ( !lp_enable_privileges() ) { return False; } if ( db == NULL ) return False; /* PRIV_<SID> (NULL terminated) as the key */ fstr_sprintf(keystr, "%s%s", PRIVPREFIX, sid_to_fstring(tmp, sid)); data = dbwrap_fetch_bystring( db, talloc_tos(), keystr ); if ( !data.dptr ) { DEBUG(3, ("get_privileges: No privileges assigned to SID " "[%s]\n", sid_string_dbg(sid))); return False; } SMB_ASSERT( data.dsize == sizeof( SE_PRIV ) ); se_priv_copy( mask, (SE_PRIV*)data.dptr ); TALLOC_FREE(data.dptr); return True; }
NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken) { NT_USER_TOKEN *token; if (!ptoken) return NULL; token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN); if (token == NULL) { DEBUG(0, ("talloc failed\n")); return NULL; } if (ptoken->user_sids && ptoken->num_sids) { token->user_sids = (DOM_SID *)talloc_memdup( token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids ); if (token->user_sids == NULL) { DEBUG(0, ("talloc_memdup failed\n")); TALLOC_FREE(token); return NULL; } token->num_sids = ptoken->num_sids; } /* copy the privileges; don't consider failure to be critical here */ if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) { DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. " "Continuing with 0 privileges assigned.\n")); } return token; }
static int priv_traverse_fn(struct db_record *rec, void *state) { PRIV_SID_LIST *priv = (PRIV_SID_LIST *)state; int prefixlen = strlen(PRIVPREFIX); DOM_SID sid; fstring sid_string; /* easy check first */ if (rec->value.dsize != sizeof(SE_PRIV) ) return 0; /* check we have a PRIV_+SID entry */ if ( strncmp((char *)rec->key.dptr, PRIVPREFIX, prefixlen) != 0) return 0; /* check to see if we are looking for a particular privilege */ if ( !se_priv_equal(&priv->privilege, &se_priv_none) ) { SE_PRIV mask; se_priv_copy( &mask, (SE_PRIV*)rec->value.dptr ); /* if the SID does not have the specified privilege then just return */ if ( !is_privilege_assigned( &mask, &priv->privilege) ) return 0; } fstrcpy( sid_string, (char *)&(rec->key.dptr[strlen(PRIVPREFIX)]) ); /* this is a last ditch safety check to preventing returning and invalid SID (i've somehow run into this on development branches) */ if ( strcmp( "S-0-0", sid_string ) == 0 ) return 0; if ( !string_to_sid(&sid, sid_string) ) { DEBUG(0,("travsersal_fn_enum__acct: Could not convert SID [%s]\n", sid_string)); return 0; } if (!NT_STATUS_IS_OK(add_sid_to_array(priv->mem_ctx, &sid, &priv->sids.list, &priv->sids.count))) { return 0; } return 0; }
bool se_priv_put_all_privileges(SE_PRIV *mask) { int i; uint32 num_privs = count_all_privileges(); if (!se_priv_copy(mask, &se_priv_none)) { return False; } for ( i=0; i<num_privs; i++ ) { se_priv_add(mask, &privs[i].se_priv); } return True; }
static bool se_priv_empty( const SE_PRIV *mask ) { SE_PRIV p1; int i; se_priv_copy( &p1, mask ); for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { p1.mask[i] &= se_priv_all.mask[i]; } return se_priv_equal( &p1, &se_priv_none ); }
bool se_priv_from_name( const char *name, SE_PRIV *mask ) { int i; for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { if ( strequal( privs[i].name, name ) ) { se_priv_copy( mask, &privs[i].se_priv ); return True; } } return False; }
BOOL grant_all_privileges( const DOM_SID *sid ) { int i; SE_PRIV mask; uint32 num_privs = count_all_privileges(); se_priv_copy( &mask, &se_priv_none ); for ( i=0; i<num_privs; i++ ) { se_priv_add(&mask, &privs[i].se_priv); } return grant_privilege( sid, &mask ); }
static bool luid_to_se_priv( struct lsa_LUID *luid, SE_PRIV *mask ) { int i; uint32 num_privs = count_all_privileges(); for ( i=0; i<num_privs; i++ ) { if ( luid->low == privs[i].luid.low ) { se_priv_copy( mask, &privs[i].se_priv ); return True; } } return False; }
static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { PRIV_SID_LIST *priv = state; int prefixlen = strlen(PRIVPREFIX); DOM_SID sid; fstring sid_string; /* easy check first */ if ( data.dsize != sizeof(SE_PRIV) ) return 0; /* check we have a PRIV_+SID entry */ if ( strncmp(key.dptr, PRIVPREFIX, prefixlen) != 0) return 0; /* check to see if we are looking for a particular privilege */ if ( !se_priv_equal(&priv->privilege, &se_priv_none) ) { SE_PRIV mask; se_priv_copy( &mask, (SE_PRIV*)data.dptr ); /* if the SID does not have the specified privilege then just return */ if ( !is_privilege_assigned( &mask, &priv->privilege) ) return 0; } fstrcpy( sid_string, &key.dptr[strlen(PRIVPREFIX)] ); /* this is a last ditch safety check to preventing returning and invalid SID (i've somehow run into this on development branches) */ if ( strcmp( "S-0-0", sid_string ) == 0 ) return 0; if ( !string_to_sid(&sid, sid_string) ) { DEBUG(0,("travsersal_fn_enum__acct: Could not convert SID [%s]\n", sid_string)); return 0; } add_sid_to_array( NULL, &sid, &priv->sids.list, &priv->sids.count ); return 0; }
bool grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask) { SE_PRIV old_mask, new_mask; ZERO_STRUCT( old_mask ); ZERO_STRUCT( new_mask ); if ( get_privileges( sid, &old_mask ) ) se_priv_copy( &new_mask, &old_mask ); else se_priv_copy( &new_mask, &se_priv_none ); se_priv_add( &new_mask, priv_mask ); DEBUG(10,("grant_privilege: %s\n", sid_string_dbg(sid))); DEBUGADD( 10, ("original privilege mask:\n")); dump_se_priv( DBGC_ALL, 10, &old_mask ); DEBUGADD( 10, ("new privilege mask:\n")); dump_se_priv( DBGC_ALL, 10, &new_mask ); return set_privileges( sid, &new_mask ); }
NTSTATUS privilege_enumerate_accounts(DOM_SID **sids, int *num_sids) { TDB_CONTEXT *tdb = get_account_pol_tdb(); PRIV_SID_LIST priv; if (!tdb) { return NT_STATUS_ACCESS_DENIED; } ZERO_STRUCT(priv); se_priv_copy( &priv.privilege, &se_priv_none ); tdb_traverse( tdb, priv_traverse_fn, &priv); /* give the memory away; caller will free */ *sids = priv.sids.list; *num_sids = priv.sids.count; return NT_STATUS_OK; }
NTSTATUS privilege_enumerate_accounts(DOM_SID **sids, int *num_sids) { struct db_context *db = get_account_pol_db(); PRIV_SID_LIST priv; if (db == NULL) { return NT_STATUS_ACCESS_DENIED; } ZERO_STRUCT(priv); se_priv_copy( &priv.privilege, &se_priv_none ); db->traverse_read(db, priv_traverse_fn, &priv); /* give the memory away; caller will free */ *sids = priv.sids.list; *num_sids = priv.sids.count; return NT_STATUS_OK; }
static BOOL get_privileges( const DOM_SID *sid, SE_PRIV *mask ) { TDB_CONTEXT *tdb = get_account_pol_tdb(); fstring keystr; TDB_DATA key, data; /* Fail if the admin has not enable privileges */ if ( !lp_enable_privileges() ) { return False; } if ( !tdb ) return False; /* PRIV_<SID> (NULL terminated) as the key */ fstr_sprintf( keystr, "%s%s", PRIVPREFIX, sid_string_static(sid) ); key.dptr = keystr; key.dsize = strlen(keystr) + 1; data = tdb_fetch( tdb, key ); if ( !data.dptr ) { DEBUG(3,("get_privileges: No privileges assigned to SID [%s]\n", sid_string_static(sid))); return False; } SMB_ASSERT( data.dsize == sizeof( SE_PRIV ) ); se_priv_copy( mask, (SE_PRIV*)data.dptr ); SAFE_FREE(data.dptr); return True; }
bool get_privileges_for_sids(SE_PRIV *privileges, DOM_SID *slist, int scount) { SE_PRIV mask; int i; bool found = False; se_priv_copy( privileges, &se_priv_none ); for ( i=0; i<scount; i++ ) { /* don't add unless we actually have a privilege assigned */ if ( !get_privileges( &slist[i], &mask ) ) continue; DEBUG(5,("get_privileges_for_sids: sid = %s\nPrivilege " "set:\n", sid_string_dbg(&slist[i]))); dump_se_priv( DBGC_ALL, 5, &mask ); se_priv_add( privileges, &mask ); found = True; } return found; }
NTSTATUS privilege_enum_sids(const SE_PRIV *mask, TALLOC_CTX *mem_ctx, DOM_SID **sids, int *num_sids) { struct db_context *db = get_account_pol_db(); PRIV_SID_LIST priv; if (db == NULL) { return NT_STATUS_ACCESS_DENIED; } ZERO_STRUCT(priv); se_priv_copy(&priv.privilege, mask); priv.mem_ctx = mem_ctx; db->traverse_read(db, priv_traverse_fn, &priv); /* give the memory away; caller will free */ *sids = priv.sids.list; *num_sids = priv.sids.count; return NT_STATUS_OK; }