diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-08-30 15:38:18 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-09-11 18:46:11 +1000 |
commit | 9883993b66826d2f692ebdd3c928f4f7a0cddc7d (patch) | |
tree | 7b7e52da490f28770e18d3e051c189efda748957 | |
parent | ad5ec58a714aba1f6c0894ca4e7207f1c5072949 (diff) | |
download | samba-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.h | 1 | ||||
-rw-r--r-- | source3/lib/privileges.c | 67 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_nt.c | 74 |
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; } |