netapi: add -f switch for DsGetDCName() example and be more verbose on output.
[kai/samba.git] / source3 / lib / privileges.c
index df7a2a7748dc93dfbf94e6da82c88562b46b04fc..c1bb783fbc2174ed28d97cedfe5e1b89952765bd 100644 (file)
@@ -17,8 +17,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
  
@@ -32,15 +31,16 @@ typedef struct {
 } SID_LIST;
 
 typedef struct {
+       TALLOC_CTX *mem_ctx;
        SE_PRIV privilege;
        SID_LIST sids;
 } PRIV_SID_LIST;
 
 
-static BOOL get_privileges( const DOM_SID *sid, SE_PRIV *mask )
+static bool get_privileges( const DOM_SID *sid, SE_PRIV *mask )
 {
-       TDB_CONTEXT *tdb = get_account_pol_tdb();
-       fstring keystr;
+       struct db_context *db = get_account_pol_db();
+       fstring tmp, keystr;
        TDB_DATA data;
 
        /* Fail if the admin has not enable privileges */
@@ -49,25 +49,25 @@ static BOOL get_privileges( const DOM_SID *sid, SE_PRIV *mask )
                return False;
        }
        
-       if ( !tdb )
+       if ( db == NULL )
                return False;
 
        /* PRIV_<SID> (NULL terminated) as the key */
        
-       fstr_sprintf( keystr, "%s%s", PRIVPREFIX, sid_string_static(sid) );
+       fstr_sprintf(keystr, "%s%s", PRIVPREFIX, sid_to_fstring(tmp, sid));
 
-       data = tdb_fetch_bystring( tdb, keystr );
+       data = dbwrap_fetch_bystring( db, talloc_tos(), keystr );
        
        if ( !data.dptr ) {
-               DEBUG(3,("get_privileges: No privileges assigned to SID [%s]\n",
-                       sid_string_static(sid)));
+               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 );
-       SAFE_FREE(data.dptr);
+       TALLOC_FREE(data.dptr);
 
        return True;
 }
@@ -76,16 +76,16 @@ static BOOL get_privileges( const DOM_SID *sid, SE_PRIV *mask )
  Store the privilege mask (set) for a given SID
 ****************************************************************************/
 
-static BOOL set_privileges( const DOM_SID *sid, SE_PRIV *mask )
+static bool set_privileges( const DOM_SID *sid, SE_PRIV *mask )
 {
-       TDB_CONTEXT *tdb = get_account_pol_tdb();
-       fstring keystr;
+       struct db_context *db = get_account_pol_db();
+       fstring tmp, keystr;
        TDB_DATA data;
        
        if ( !lp_enable_privileges() )
                return False;
 
-       if ( !tdb )
+       if ( db == NULL )
                return False;
 
        if ( !sid || (sid->num_auths == 0) ) {
@@ -95,25 +95,26 @@ static BOOL set_privileges( const DOM_SID *sid, SE_PRIV *mask )
 
        /* PRIV_<SID> (NULL terminated) as the key */
        
-       fstr_sprintf( keystr, "%s%s", PRIVPREFIX, sid_string_static(sid) );
+       fstr_sprintf(keystr, "%s%s", PRIVPREFIX, sid_to_fstring(tmp, sid));
        
        /* no packing.  static size structure, just write it out */
        
        data.dptr  = (uint8 *)mask;
        data.dsize = sizeof(SE_PRIV);
 
-       return ( tdb_store_bystring(tdb, keystr, data, TDB_REPLACE) != -1 );
+       return NT_STATUS_IS_OK(dbwrap_store_bystring(db, keystr, data,
+                                                    TDB_REPLACE));
 }
 
 /*********************************************************************
- get a list of all privleges for all sids the in list
+ get a list of all privileges for all sids in the list
 *********************************************************************/
 
-BOOL get_privileges_for_sids(SE_PRIV *privileges, DOM_SID *slist, int scount)
+bool get_privileges_for_sids(SE_PRIV *privileges, DOM_SID *slist, int scount)
 {
        SE_PRIV mask;
        int i;
-       BOOL found = False;
+       bool found = False;
 
        se_priv_copy( privileges, &se_priv_none );
        
@@ -123,8 +124,8 @@ BOOL get_privileges_for_sids(SE_PRIV *privileges, DOM_SID *slist, int scount)
                if ( !get_privileges( &slist[i], &mask ) )
                        continue;
 
-               DEBUG(5,("get_privileges_for_sids: sid = %s\nPrivilege set:\n", 
-                       sid_string_static(&slist[i])));
+               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 );
@@ -136,10 +137,10 @@ BOOL get_privileges_for_sids(SE_PRIV *privileges, DOM_SID *slist, int scount)
 
 
 /*********************************************************************
- travseral functions for privilege_enumerate_accounts
+ traversal functions for privilege_enumerate_accounts
 *********************************************************************/
 
-static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
+static int priv_traverse_fn(struct db_record *rec, void *state)
 {
        PRIV_SID_LIST *priv = (PRIV_SID_LIST *)state;
        int  prefixlen = strlen(PRIVPREFIX);
@@ -148,12 +149,12 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s
        
        /* easy check first */
        
-       if ( data.dsize != sizeof(SE_PRIV) )
+       if (rec->value.dsize != sizeof(SE_PRIV) )
                return 0;
 
        /* check we have a PRIV_+SID entry */
 
-       if ( strncmp((const char *)key.dptr, PRIVPREFIX, prefixlen) != 0)
+       if ( strncmp((char *)rec->key.dptr, PRIVPREFIX, prefixlen) != 0)
                return 0;
                
        /* check to see if we are looking for a particular privilege */
@@ -161,7 +162,7 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s
        if ( !se_priv_equal(&priv->privilege, &se_priv_none) ) {
                SE_PRIV mask;
                
-               se_priv_copy( &mask, (SE_PRIV*)data.dptr );
+               se_priv_copy( &mask, (SE_PRIV*)rec->value.dptr );
                
                /* if the SID does not have the specified privilege 
                   then just return */
@@ -170,7 +171,7 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s
                        return 0;
        }
                
-       fstrcpy( sid_string, (const char *)&key.dptr[strlen(PRIVPREFIX)] );
+       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) */
@@ -184,7 +185,10 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s
                return 0;
        }
 
-       if (!add_sid_to_array( NULL, &sid, &priv->sids.list, &priv->sids.count )) {
+       if (!NT_STATUS_IS_OK(add_sid_to_array(priv->mem_ctx, &sid,
+                                             &priv->sids.list,
+                                             &priv->sids.count)))
+       {
                return 0;
        }
        
@@ -197,10 +201,10 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s
 
 NTSTATUS privilege_enumerate_accounts(DOM_SID **sids, int *num_sids)
 {
-       TDB_CONTEXT *tdb = get_account_pol_tdb();
+       struct db_context *db = get_account_pol_db();
        PRIV_SID_LIST priv;
        
-       if (!tdb) {
+       if (db == NULL) {
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -208,7 +212,7 @@ NTSTATUS privilege_enumerate_accounts(DOM_SID **sids, int *num_sids)
 
        se_priv_copy( &priv.privilege, &se_priv_none );
 
-       tdb_traverse( tdb, priv_traverse_fn, &priv);
+       db->traverse_read(db, priv_traverse_fn, &priv);
 
        /* give the memory away; caller will free */
        
@@ -218,11 +222,40 @@ NTSTATUS privilege_enumerate_accounts(DOM_SID **sids, int *num_sids)
        return NT_STATUS_OK;
 }
 
+/*********************************************************************
+ Retrieve list of SIDs granted a particular privilege
+*********************************************************************/
+
+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;
+}
+
 /***************************************************************************
  Add privilege to sid
 ****************************************************************************/
 
-BOOL grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
+bool grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
 {
        SE_PRIV old_mask, new_mask;
        
@@ -236,7 +269,7 @@ BOOL grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
 
        se_priv_add( &new_mask, priv_mask );
 
-       DEBUG(10,("grant_privilege: %s\n", sid_string_static(sid)));
+       DEBUG(10,("grant_privilege: %s\n", sid_string_dbg(sid)));
        
        DEBUGADD( 10, ("original privilege mask:\n"));
        dump_se_priv( DBGC_ALL, 10, &old_mask );
@@ -251,7 +284,7 @@ BOOL grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
  Add a privilege based on its name
 *********************************************************************/
 
-BOOL grant_privilege_by_name(DOM_SID *sid, const char *name)
+bool grant_privilege_by_name(DOM_SID *sid, const char *name)
 {
        SE_PRIV mask;
 
@@ -268,7 +301,7 @@ BOOL grant_privilege_by_name(DOM_SID *sid, const char *name)
  Remove privilege from sid
 ****************************************************************************/
 
-BOOL revoke_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
+bool revoke_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
 {
        SE_PRIV mask;
        
@@ -277,7 +310,7 @@ BOOL revoke_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
        if ( !get_privileges( sid, &mask ) )
                return True;
        
-       DEBUG(10,("revoke_privilege: %s\n", sid_string_static(sid)));
+       DEBUG(10,("revoke_privilege: %s\n", sid_string_dbg(sid)));
        
        DEBUGADD( 10, ("original privilege mask:\n"));
        dump_se_priv( DBGC_ALL, 10, &mask );
@@ -294,7 +327,7 @@ BOOL revoke_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
  Revoke all privileges
 *********************************************************************/
 
-BOOL revoke_all_privileges( DOM_SID *sid )
+bool revoke_all_privileges( DOM_SID *sid )
 {
        return revoke_privilege( sid, &se_priv_all );
 }
@@ -303,7 +336,7 @@ BOOL revoke_all_privileges( DOM_SID *sid )
  Add a privilege based on its name
 *********************************************************************/
 
-BOOL revoke_privilege_by_name(DOM_SID *sid, const char *name)
+bool revoke_privilege_by_name(DOM_SID *sid, const char *name)
 {
        SE_PRIV mask;
 
@@ -409,7 +442,7 @@ NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_l
 /*******************************************************************
 *******************************************************************/
 
-BOOL is_privileged_sid( const DOM_SID *sid )
+bool is_privileged_sid( const DOM_SID *sid )
 {
        SE_PRIV mask;
        
@@ -419,7 +452,7 @@ BOOL is_privileged_sid( const DOM_SID *sid )
 /*******************************************************************
 *******************************************************************/
 
-BOOL grant_all_privileges( const DOM_SID *sid )
+bool grant_all_privileges( const DOM_SID *sid )
 {
        SE_PRIV mask;