s3-privs Overhaul PRIVILEGE_SET handling, avoid dealing with the bitmap
authorAndrew Bartlett <abartlet@samba.org>
Mon, 30 Aug 2010 05:38:18 +0000 (15:38 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 11 Sep 2010 08:46:11 +0000 (18:46 +1000)
This avoids us dealing with the privilege bitmap in the LSA server, and
overhauls much of the rest of the handling to be currnet with the modern
world of talloc.

Andrew Bartlett

Signed-off-by: Andrew Tridgell <tridge@samba.org>
source3/include/proto.h
source3/lib/privileges.c
source3/rpc_server/srv_lsa_nt.c

index 65a27dc404d2541781514bda79bce43c257bcbc6..e15dc7b5a1becd4f31325a09763df8afea1cb6d6 100644 (file)
@@ -634,6 +634,7 @@ void pidfile_unlink(void);
 /* The following definitions come from lib/privileges.c  */
 
 bool get_privileges_for_sids(uint64_t *privileges, struct dom_sid *slist, int scount);
+NTSTATUS get_privileges_for_sid_as_set(TALLOC_CTX *mem_ctx, PRIVILEGE_SET **privileges, struct dom_sid *sid);
 NTSTATUS privilege_enumerate_accounts(struct dom_sid **sids, int *num_sids);
 NTSTATUS privilege_enum_sids(enum sec_privilege privilege, TALLOC_CTX *mem_ctx,
                             struct dom_sid **sids, int *num_sids);
index 181ea5c986e8834dd3472449c6c1c9d0ff147a4d..31b0e7dc555fd98d98c479e0c64bcc07c8d36407 100644 (file)
@@ -149,6 +149,23 @@ bool get_privileges_for_sids(uint64_t *privileges, struct dom_sid *slist, int sc
        return found;
 }
 
+NTSTATUS get_privileges_for_sid_as_set(TALLOC_CTX *mem_ctx, PRIVILEGE_SET **privileges, struct dom_sid *sid)
+{
+       uint64_t mask;
+       if (!get_privileges(sid, &mask)) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       *privileges = talloc_zero(mem_ctx, PRIVILEGE_SET);
+       if (!*privileges) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!se_priv_to_privilege_set(*privileges, mask)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
 
 /*********************************************************************
  traversal functions for privilege_enumerate_accounts
@@ -434,56 +451,6 @@ NTSTATUS privilege_delete_account(const struct dom_sid *sid)
        return dbwrap_delete_bystring(db, keystr);
 }
 
-/****************************************************************************
- initialise a privilege list and set the talloc context
- ****************************************************************************/
-
-NTSTATUS privilege_set_init(PRIVILEGE_SET *priv_set)
-{
-       TALLOC_CTX *mem_ctx;
-
-       ZERO_STRUCTP( priv_set );
-
-       mem_ctx = talloc_init("privilege set");
-       if ( !mem_ctx ) {
-               DEBUG(0,("privilege_set_init: failed to initialize talloc ctx!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       priv_set->mem_ctx = mem_ctx;
-
-       return NT_STATUS_OK;
-}
-
-/****************************************************************************
-  initialise a privilege list and with someone else's talloc context
-****************************************************************************/
-
-NTSTATUS privilege_set_init_by_ctx(TALLOC_CTX *mem_ctx, PRIVILEGE_SET *priv_set)
-{
-       ZERO_STRUCTP( priv_set );
-
-       priv_set->mem_ctx = mem_ctx;
-       priv_set->ext_ctx = True;
-
-       return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Free all memory used by a PRIVILEGE_SET
-****************************************************************************/
-
-void privilege_set_free(PRIVILEGE_SET *priv_set)
-{
-       if ( !priv_set )
-               return;
-
-       if ( !( priv_set->ext_ctx ) )
-               talloc_destroy( priv_set->mem_ctx );
-
-       ZERO_STRUCTP( priv_set );
-}
-
 /****************************************************************************
  duplicate alloc luid_attr
  ****************************************************************************/
index d0cf4e4716af885b632dacc3d859d66fa517adea..49bdca7b7f59d3351bb98b4080672d10b59fba56 100644 (file)
@@ -11,6 +11,7 @@
  *  Copyright (C) Gerald (Jerry) Carter             2005.
  *  Copyright (C) Volker Lendecke                   2005.
  *  Copyright (C) Guenther Deschner                2008.
+ *  Copyright (C) Andrew Bartlett                  2010.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -1831,11 +1832,8 @@ NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
 {
        NTSTATUS status = NT_STATUS_OK;
        struct lsa_info *info=NULL;
-       uint64_t mask;
-       PRIVILEGE_SET privileges;
+       PRIVILEGE_SET *privileges;
        struct lsa_PrivilegeSet *priv_set = NULL;
-       struct lsa_LUIDAttribute *luid_attrs = NULL;
-       int i;
 
        /* find the connection policy handle. */
        if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
@@ -1848,48 +1846,23 @@ NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
        if (!(info->access & LSA_ACCOUNT_VIEW))
                return NT_STATUS_ACCESS_DENIED;
 
-       get_privileges_for_sids(&mask, &info->sid, 1);
-
-       privilege_set_init( &privileges );
-
-       priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
-       if (!priv_set) {
-               status = NT_STATUS_NO_MEMORY;
-               goto done;
+       status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
-       if ( se_priv_to_privilege_set( &privileges, mask ) ) {
-
-               DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
-                         sid_string_dbg(&info->sid),
-                         privileges.count));
-
-               luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
-                                              struct lsa_LUIDAttribute,
-                                              privileges.count);
-               if (!luid_attrs) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto done;
-               }
-
-               for (i=0; i<privileges.count; i++) {
-                       luid_attrs[i] = privileges.set[i];
-               }
-
-               priv_set->count = privileges.count;
-               priv_set->unknown = 0;
-               priv_set->set = luid_attrs;
-
-       } else {
-               priv_set->count = 0;
-               priv_set->unknown = 0;
-               priv_set->set = NULL;
+       *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
+       if (!priv_set) {
+               return NT_STATUS_NO_MEMORY;
        }
 
-       *r->out.privs = priv_set;
+       DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
+                 sid_string_dbg(&info->sid),
+                 privileges->count));
 
- done:
-       privilege_set_free( &privileges );
+       priv_set->count = privileges->count;
+       priv_set->unknown = 0;
+       priv_set->set = talloc_move(priv_set, &privileges->set);
 
        return status;
 }
@@ -2339,8 +2312,7 @@ NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
        NTSTATUS status;
        struct lsa_info *info = NULL;
        struct dom_sid sid;
-       PRIVILEGE_SET privileges;
-       uint64_t mask;
+       PRIVILEGE_SET *privileges;
 
        /* find the connection policy handle. */
 
@@ -2358,29 +2330,19 @@ NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
        /* according to an NT4 PDC, you can add privileges to SIDs even without
           call_lsa_create_account() first.  And you can use any arbitrary SID. */
 
-       sid_copy( &sid, r->in.sid );
-
        /* according to MS-LSAD 3.1.4.5.10 it is required to return
         * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
         * the lsa database */
 
-       if (!get_privileges_for_sids(&mask, &sid, 1)) {
-               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       status = privilege_set_init(&privileges);
+       status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       se_priv_to_privilege_set(&privileges, mask);
-
        DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
-                 sid_string_dbg(&sid), privileges.count));
-
-       status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
+                 sid_string_dbg(&sid), privileges->count));
 
-       privilege_set_free( &privileges );
+       status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
 
        return status;
 }