summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-08-30 15:38:18 +1000
committerAndrew Bartlett <abartlet@samba.org>2010-09-11 18:46:11 +1000
commit9883993b66826d2f692ebdd3c928f4f7a0cddc7d (patch)
tree7b7e52da490f28770e18d3e051c189efda748957
parentad5ec58a714aba1f6c0894ca4e7207f1c5072949 (diff)
downloadsamba-9883993b66826d2f692ebdd3c928f4f7a0cddc7d.tar.gz
samba-9883993b66826d2f692ebdd3c928f4f7a0cddc7d.tar.bz2
samba-9883993b66826d2f692ebdd3c928f4f7a0cddc7d.zip
s3-privs Overhaul PRIVILEGE_SET handling, avoid dealing with the bitmap
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>
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/lib/privileges.c67
-rw-r--r--source3/rpc_server/srv_lsa_nt.c74
3 files changed, 36 insertions, 106 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 65a27dc404..e15dc7b5a1 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c
index 181ea5c986..31b0e7dc55 100644
--- a/source3/lib/privileges.c
+++ b/source3/lib/privileges.c
@@ -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
@@ -435,56 +452,6 @@ NTSTATUS privilege_delete_account(const struct dom_sid *sid)
}
/****************************************************************************
- 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
****************************************************************************/
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index d0cf4e4716..49bdca7b7f 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -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;
}