mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
split some security related functions in their own files.
(no need to include all of smbd files to use some basic sec functions)
also minor compile fixes
couldn't compile to test these due to some kerberos problems wirh 3.0,
but on HEAD they're working well, so I suppose it's ok to commit
(This used to be commit c78f2d0bd1
)
This commit is contained in:
parent
487130a6df
commit
b1f610ebb1
@ -182,7 +182,8 @@ LIB_OBJ = lib/version.o lib/charcnv.o lib/debug.o lib/fault.o \
|
||||
nsswitch/wb_client.o nsswitch/wb_common.o \
|
||||
lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \
|
||||
lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
|
||||
lib/module.o lib/ldap_escape.o @CHARSET_STATIC@
|
||||
lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
|
||||
lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o
|
||||
|
||||
LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
|
||||
|
||||
@ -219,7 +220,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
|
||||
libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \
|
||||
libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \
|
||||
libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \
|
||||
libsmb/clistr.o \
|
||||
libsmb/clistr.o lib/util_seaccess.o \
|
||||
libsmb/cliquota.o libsmb/clifsinfo.o \
|
||||
libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
|
||||
libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \
|
||||
@ -346,7 +347,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
|
||||
smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
|
||||
smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \
|
||||
smbd/process.o smbd/service.o smbd/error.o \
|
||||
printing/printfsp.o lib/util_seaccess.o \
|
||||
printing/printfsp.o \
|
||||
lib/sysquotas.o smbd/change_trust_pw.o smbd/fake_file.o \
|
||||
smbd/quotas.o smbd/ntquotas.o lib/afs.o \
|
||||
$(MANGLE_OBJ) @VFS_STATIC@
|
||||
|
@ -53,6 +53,8 @@ typedef struct LUID_ATTR
|
||||
|
||||
typedef struct privilege_set
|
||||
{
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL ext_ctx;
|
||||
uint32 count;
|
||||
uint32 control;
|
||||
LUID_ATTR *set;
|
||||
|
@ -657,7 +657,7 @@ typedef struct lsa_r_enumprivsaccount
|
||||
{
|
||||
uint32 ptr;
|
||||
uint32 count;
|
||||
PRIVILEGE_SET set;
|
||||
PRIVILEGE_SET *set;
|
||||
NTSTATUS status;
|
||||
} LSA_R_ENUMPRIVSACCOUNT;
|
||||
|
||||
@ -703,7 +703,7 @@ typedef struct lsa_q_addprivs
|
||||
{
|
||||
POLICY_HND pol; /* policy handle */
|
||||
uint32 count;
|
||||
PRIVILEGE_SET set;
|
||||
PRIVILEGE_SET *set;
|
||||
} LSA_Q_ADDPRIVS;
|
||||
|
||||
typedef struct lsa_r_addprivs
|
||||
@ -718,7 +718,7 @@ typedef struct lsa_q_removeprivs
|
||||
uint32 allrights;
|
||||
uint32 ptr;
|
||||
uint32 count;
|
||||
PRIVILEGE_SET set;
|
||||
PRIVILEGE_SET *set;
|
||||
} LSA_Q_REMOVEPRIVS;
|
||||
|
||||
typedef struct lsa_r_removeprivs
|
||||
|
@ -30,6 +30,27 @@
|
||||
/**
|
||||
* talloc allocation pool. All allocated blocks can be freed in one go.
|
||||
**/
|
||||
|
||||
struct talloc_chunk {
|
||||
struct talloc_chunk *next;
|
||||
size_t size;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
struct talloc_ctx {
|
||||
struct talloc_chunk *list;
|
||||
size_t total_alloc_size;
|
||||
|
||||
/** The name recorded for this pool, if any. Should describe
|
||||
* the purpose for which it was allocated. The string is
|
||||
* allocated within the pool. **/
|
||||
char *name;
|
||||
|
||||
/** Pointer to the next allocate talloc pool, so that we can
|
||||
* summarize all talloc memory usage. **/
|
||||
struct talloc_ctx *next_ctx;
|
||||
};
|
||||
|
||||
typedef struct talloc_ctx TALLOC_CTX;
|
||||
|
||||
TALLOC_CTX *talloc_init(char const *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
|
||||
|
@ -54,27 +54,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
struct talloc_chunk {
|
||||
struct talloc_chunk *next;
|
||||
size_t size;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
|
||||
struct talloc_ctx {
|
||||
struct talloc_chunk *list;
|
||||
size_t total_alloc_size;
|
||||
|
||||
/** The name recorded for this pool, if any. Should describe
|
||||
* the purpose for which it was allocated. The string is
|
||||
* allocated within the pool. **/
|
||||
char *name;
|
||||
|
||||
/** Pointer to the next allocate talloc pool, so that we can
|
||||
* summarize all talloc memory usage. **/
|
||||
struct talloc_ctx *next_ctx;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Start of linked list of all talloc pools.
|
||||
|
@ -23,22 +23,6 @@
|
||||
|
||||
extern DOM_SID global_sid_Builtin;
|
||||
|
||||
/**********************************************************************************
|
||||
Check if this ACE has a SID in common with the token.
|
||||
**********************************************************************************/
|
||||
|
||||
static BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < token->num_sids; i++) {
|
||||
if (sid_equal(&ace->trustee, &token->user_sids[i]))
|
||||
return True;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/*********************************************************************************
|
||||
Check an ACE against a SID. We return the remaining needed permission
|
||||
bits not yet granted. Zero means permission allowed (no more needed bits).
|
||||
@ -332,119 +316,6 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Create a child security descriptor using another security descriptor as
|
||||
the parent container. This child object can either be a container or
|
||||
non-container object. */
|
||||
|
||||
SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
|
||||
BOOL child_container)
|
||||
{
|
||||
SEC_DESC_BUF *sdb;
|
||||
SEC_DESC *sd;
|
||||
SEC_ACL *new_dacl, *the_acl;
|
||||
SEC_ACE *new_ace_list = NULL;
|
||||
unsigned int new_ace_list_ndx = 0, i;
|
||||
size_t size;
|
||||
|
||||
/* Currently we only process the dacl when creating the child. The
|
||||
sacl should also be processed but this is left out as sacls are
|
||||
not implemented in Samba at the moment.*/
|
||||
|
||||
the_acl = parent_ctr->dacl;
|
||||
|
||||
if (!(new_ace_list = talloc(ctx, sizeof(SEC_ACE) * the_acl->num_aces)))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; the_acl && i < the_acl->num_aces; i++) {
|
||||
SEC_ACE *ace = &the_acl->ace[i];
|
||||
SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
|
||||
uint8 new_flags = 0;
|
||||
BOOL inherit = False;
|
||||
fstring sid_str;
|
||||
|
||||
/* The OBJECT_INHERIT_ACE flag causes the ACE to be
|
||||
inherited by non-container children objects. Container
|
||||
children objects will inherit it as an INHERIT_ONLY
|
||||
ACE. */
|
||||
|
||||
if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
|
||||
|
||||
if (!child_container) {
|
||||
new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
|
||||
} else {
|
||||
new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
|
||||
}
|
||||
|
||||
inherit = True;
|
||||
}
|
||||
|
||||
/* The CONAINER_INHERIT_ACE flag means all child container
|
||||
objects will inherit and use the ACE. */
|
||||
|
||||
if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
|
||||
if (!child_container) {
|
||||
inherit = False;
|
||||
} else {
|
||||
new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
|
||||
}
|
||||
}
|
||||
|
||||
/* The INHERIT_ONLY_ACE is not used by the se_access_check()
|
||||
function for the parent container, but is inherited by
|
||||
all child objects as a normal ACE. */
|
||||
|
||||
if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
|
||||
/* Move along, nothing to see here */
|
||||
}
|
||||
|
||||
/* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
|
||||
is inherited by child objects but not grandchildren
|
||||
objects. We clear the object inherit and container
|
||||
inherit flags in the inherited ACE. */
|
||||
|
||||
if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
|
||||
new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
|
||||
SEC_ACE_FLAG_CONTAINER_INHERIT);
|
||||
}
|
||||
|
||||
/* Add ACE to ACE list */
|
||||
|
||||
if (!inherit)
|
||||
continue;
|
||||
|
||||
init_sec_access(&new_ace->info, ace->info.mask);
|
||||
init_sec_ace(new_ace, &ace->trustee, ace->type,
|
||||
new_ace->info, new_flags);
|
||||
|
||||
sid_to_string(sid_str, &ace->trustee);
|
||||
|
||||
DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
|
||||
" inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
|
||||
ace->type, ace->flags, ace->info.mask,
|
||||
sid_str, new_ace->type, new_ace->flags,
|
||||
new_ace->info.mask));
|
||||
|
||||
new_ace_list_ndx++;
|
||||
}
|
||||
|
||||
/* Create child security descriptor to return */
|
||||
|
||||
new_dacl = make_sec_acl(ctx, ACL_REVISION, new_ace_list_ndx, new_ace_list);
|
||||
|
||||
/* Use the existing user and group sids. I don't think this is
|
||||
correct. Perhaps the user and group should be passed in as
|
||||
parameters by the caller? */
|
||||
|
||||
sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
|
||||
parent_ctr->owner_sid,
|
||||
parent_ctr->grp_sid,
|
||||
parent_ctr->sacl,
|
||||
new_dacl, &size);
|
||||
|
||||
sdb = make_sec_desc_buf(ctx, size, sd);
|
||||
|
||||
return sdb;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
samr_make_sam_obj_sd
|
||||
|
@ -638,7 +638,7 @@ void print_guid(GUID *guid)
|
||||
Tallocs a duplicate SID.
|
||||
********************************************************************/
|
||||
|
||||
DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src)
|
||||
DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
|
||||
{
|
||||
DOM_SID *dst;
|
||||
|
||||
|
@ -509,7 +509,7 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, DOM_SID *u_sid, enum pdb_value_state flag)
|
||||
BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
|
||||
{
|
||||
if (!sampass || !u_sid)
|
||||
return False;
|
||||
@ -545,7 +545,7 @@ BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, DOM_SID *g_sid, enum pdb_value_state flag)
|
||||
BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
|
||||
{
|
||||
if (!sampass || !g_sid)
|
||||
return False;
|
||||
|
@ -1035,9 +1035,9 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
for (i=0; i<r.count; i++) {
|
||||
(*set)[i].luid.low = r.set.set[i].luid.low;
|
||||
(*set)[i].luid.high = r.set.set[i].luid.high;
|
||||
(*set)[i].attr = r.set.set[i].attr;
|
||||
(*set)[i].luid.low = r.set->set[i].luid.low;
|
||||
(*set)[i].luid.high = r.set->set[i].luid.high;
|
||||
(*set)[i].attr = r.set->set[i].attr;
|
||||
}
|
||||
|
||||
*count=r.count;
|
||||
|
@ -1809,14 +1809,20 @@ static BOOL lsa_io_privilege_set(const char *desc, PRIVILEGE_SET *r_c, prs_struc
|
||||
return True;
|
||||
}
|
||||
|
||||
void init_lsa_r_enum_privsaccount(LSA_R_ENUMPRIVSACCOUNT *r_u, LUID_ATTR *set, uint32 count, uint32 control)
|
||||
NTSTATUS init_lsa_r_enum_privsaccount(TALLOC_CTX *mem_ctx, LSA_R_ENUMPRIVSACCOUNT *r_u, LUID_ATTR *set, uint32 count, uint32 control)
|
||||
{
|
||||
r_u->ptr=1;
|
||||
r_u->count=count;
|
||||
r_u->set.set=set;
|
||||
r_u->set.count=count;
|
||||
r_u->set.control=control;
|
||||
DEBUG(10,("init_lsa_r_enum_privsaccount: %d %d privileges\n", r_u->count, r_u->set.count));
|
||||
NTSTATUS ret;
|
||||
|
||||
r_u->ptr = 1;
|
||||
r_u->count = count;
|
||||
|
||||
if (!NT_STATUS_IS_OK(ret = init_priv_with_ctx(mem_ctx, &(r_u->set))))
|
||||
return ret;
|
||||
|
||||
if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(r_u->set->mem_ctx, &(r_u->set->set), set)))
|
||||
return ret;
|
||||
|
||||
DEBUG(10,("init_lsa_r_enum_privsaccount: %d %d privileges\n", r_u->count, r_u->set->count));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -1840,13 +1846,16 @@ BOOL lsa_io_r_enum_privsaccount(const char *desc, LSA_R_ENUMPRIVSACCOUNT *r_c, p
|
||||
|
||||
/* malloc memory if unmarshalling here */
|
||||
|
||||
if (UNMARSHALLING(ps) && r_c->count!=0) {
|
||||
if (!(r_c->set.set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count)))
|
||||
if (UNMARSHALLING(ps) && r_c->count != 0) {
|
||||
if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
|
||||
return False;
|
||||
|
||||
if (!(r_c->set->set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count)))
|
||||
return False;
|
||||
|
||||
}
|
||||
|
||||
if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
|
||||
if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -2008,11 +2017,14 @@ BOOL lsa_io_q_addprivs(const char *desc, LSA_Q_ADDPRIVS *r_c, prs_struct *ps, in
|
||||
return False;
|
||||
|
||||
if (UNMARSHALLING(ps) && r_c->count!=0) {
|
||||
if (!(r_c->set.set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count)))
|
||||
if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
|
||||
return False;
|
||||
|
||||
if (!(r_c->set->set = (LUID_ATTR *)prs_alloc_mem(ps, sizeof(LUID_ATTR) * r_c->count)))
|
||||
return False;
|
||||
}
|
||||
|
||||
if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
|
||||
if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
@ -2067,11 +2079,14 @@ BOOL lsa_io_q_removeprivs(const char *desc, LSA_Q_REMOVEPRIVS *r_c, prs_struct *
|
||||
return False;
|
||||
|
||||
if (UNMARSHALLING(ps) && r_c->count!=0) {
|
||||
if (!(r_c->set.set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count)))
|
||||
if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
|
||||
return False;
|
||||
|
||||
if (!(r_c->set->set = (LUID_ATTR *)prs_alloc_mem(ps, sizeof(LUID_ATTR) * r_c->count)))
|
||||
return False;
|
||||
}
|
||||
|
||||
if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
|
||||
if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
|
||||
return False;
|
||||
}
|
||||
|
||||
|
@ -27,15 +27,6 @@
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_RPC_PARSE
|
||||
|
||||
/*******************************************************************
|
||||
Sets up a SEC_ACCESS structure.
|
||||
********************************************************************/
|
||||
|
||||
void init_sec_access(SEC_ACCESS *t, uint32 mask)
|
||||
{
|
||||
t->mask = mask;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes a SEC_ACCESS structure.
|
||||
********************************************************************/
|
||||
@ -54,51 +45,6 @@ BOOL sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Check if ACE has OBJECT type.
|
||||
********************************************************************/
|
||||
|
||||
BOOL sec_ace_object(uint8 type)
|
||||
{
|
||||
if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
|
||||
type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
|
||||
type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
|
||||
type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
copy a SEC_ACE structure.
|
||||
********************************************************************/
|
||||
void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
|
||||
{
|
||||
ace_dest->type = ace_src->type;
|
||||
ace_dest->flags = ace_src->flags;
|
||||
ace_dest->size = ace_src->size;
|
||||
ace_dest->info.mask = ace_src->info.mask;
|
||||
ace_dest->obj_flags = ace_src->obj_flags;
|
||||
memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, GUID_SIZE);
|
||||
memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, GUID_SIZE);
|
||||
sid_copy(&ace_dest->trustee, &ace_src->trustee);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Sets up a SEC_ACE structure.
|
||||
********************************************************************/
|
||||
|
||||
void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
|
||||
{
|
||||
t->type = type;
|
||||
t->flags = flag;
|
||||
t->size = sid_size(sid) + 8;
|
||||
t->info = mask;
|
||||
|
||||
ZERO_STRUCTP(&t->trustee);
|
||||
sid_copy(&t->trustee, sid);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes a SEC_ACE structure.
|
||||
********************************************************************/
|
||||
@ -153,127 +99,6 @@ BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
adds new SID with its permissions to ACE list
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
*num += 1;
|
||||
|
||||
if((new[0] = (SEC_ACE *) talloc_zero(ctx, (*num) * sizeof(SEC_ACE))) == 0)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < *num - 1; i ++)
|
||||
sec_ace_copy(&(*new)[i], &old[i]);
|
||||
|
||||
(*new)[i].type = 0;
|
||||
(*new)[i].flags = 0;
|
||||
(*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid);
|
||||
(*new)[i].info.mask = mask;
|
||||
sid_copy(&(*new)[i].trustee, sid);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
modify SID's permissions at ACL
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
for (i = 0; i < num; i ++) {
|
||||
if (sid_compare(&ace[i].trustee, sid) == 0) {
|
||||
ace[i].info.mask = mask;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
return NT_STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
delete SID from ACL
|
||||
********************************************************************/
|
||||
|
||||
static NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, uint32 *num, DOM_SID *sid)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int n_del = 0;
|
||||
|
||||
if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
if((new[0] = (SEC_ACE *) talloc_zero(ctx, (*num) * sizeof(SEC_ACE))) == 0)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < *num; i ++) {
|
||||
if (sid_compare(&old[i].trustee, sid) != 0)
|
||||
sec_ace_copy(&(*new)[i], &old[i]);
|
||||
else
|
||||
n_del ++;
|
||||
}
|
||||
if (n_del == 0)
|
||||
return NT_STATUS_NOT_FOUND;
|
||||
else {
|
||||
*num -= n_del;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Create a SEC_ACL structure.
|
||||
********************************************************************/
|
||||
|
||||
SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list)
|
||||
{
|
||||
SEC_ACL *dst;
|
||||
int i;
|
||||
|
||||
if((dst = (SEC_ACL *)talloc_zero(ctx,sizeof(SEC_ACL))) == NULL)
|
||||
return NULL;
|
||||
|
||||
dst->revision = revision;
|
||||
dst->num_aces = num_aces;
|
||||
dst->size = SEC_ACL_HEADER_SIZE;
|
||||
|
||||
/* Now we need to return a non-NULL address for the ace list even
|
||||
if the number of aces required is zero. This is because there
|
||||
is a distinct difference between a NULL ace and an ace with zero
|
||||
entries in it. This is achieved by checking that num_aces is a
|
||||
positive number. */
|
||||
|
||||
if ((num_aces) &&
|
||||
((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
|
||||
== NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_aces; i++) {
|
||||
dst->ace[i] = ace_list[i]; /* Structure copy. */
|
||||
dst->size += ace_list[i].size;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Duplicate a SEC_ACL structure.
|
||||
********************************************************************/
|
||||
|
||||
SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
|
||||
{
|
||||
if(src == NULL)
|
||||
return NULL;
|
||||
|
||||
return make_sec_acl(ctx, src->revision, src->num_aces, src->ace);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes a SEC_ACL structure.
|
||||
|
||||
@ -346,332 +171,6 @@ BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Works out the linearization size of a SEC_DESC.
|
||||
********************************************************************/
|
||||
|
||||
size_t sec_desc_size(SEC_DESC *psd)
|
||||
{
|
||||
size_t offset;
|
||||
|
||||
if (!psd) return 0;
|
||||
|
||||
offset = SEC_DESC_HEADER_SIZE;
|
||||
|
||||
/* don't align */
|
||||
|
||||
if (psd->owner_sid != NULL)
|
||||
offset += sid_size(psd->owner_sid);
|
||||
|
||||
if (psd->grp_sid != NULL)
|
||||
offset += sid_size(psd->grp_sid);
|
||||
|
||||
if (psd->sacl != NULL)
|
||||
offset += psd->sacl->size;
|
||||
|
||||
if (psd->dacl != NULL)
|
||||
offset += psd->dacl->size;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Compares two SEC_ACE structures
|
||||
********************************************************************/
|
||||
|
||||
BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
|
||||
{
|
||||
/* Trivial case */
|
||||
|
||||
if (!s1 && !s2) return True;
|
||||
|
||||
/* Check top level stuff */
|
||||
|
||||
if (s1->type != s2->type || s1->flags != s2->flags ||
|
||||
s1->info.mask != s2->info.mask) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Check SID */
|
||||
|
||||
if (!sid_equal(&s1->trustee, &s2->trustee)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Compares two SEC_ACL structures
|
||||
********************************************************************/
|
||||
|
||||
BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
/* Trivial cases */
|
||||
|
||||
if (!s1 && !s2) return True;
|
||||
if (!s1 || !s2) return False;
|
||||
|
||||
/* Check top level stuff */
|
||||
|
||||
if (s1->revision != s2->revision) {
|
||||
DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
|
||||
s1->revision, s2->revision));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (s1->num_aces != s2->num_aces) {
|
||||
DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
|
||||
s1->revision, s2->revision));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* The ACEs could be in any order so check each ACE in s1 against
|
||||
each ACE in s2. */
|
||||
|
||||
for (i = 0; i < s1->num_aces; i++) {
|
||||
BOOL found = False;
|
||||
|
||||
for (j = 0; j < s2->num_aces; j++) {
|
||||
if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
|
||||
found = True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Compares two SEC_DESC structures
|
||||
********************************************************************/
|
||||
|
||||
BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
|
||||
{
|
||||
/* Trivial case */
|
||||
|
||||
if (!s1 && !s2) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check top level stuff */
|
||||
|
||||
if (s1->revision != s2->revision) {
|
||||
DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
|
||||
s1->revision, s2->revision));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (s1->type!= s2->type) {
|
||||
DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
|
||||
s1->type, s2->type));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Check owner and group */
|
||||
|
||||
if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
|
||||
fstring str1, str2;
|
||||
|
||||
sid_to_string(str1, s1->owner_sid);
|
||||
sid_to_string(str2, s2->owner_sid);
|
||||
|
||||
DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
|
||||
str1, str2));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
|
||||
fstring str1, str2;
|
||||
|
||||
sid_to_string(str1, s1->grp_sid);
|
||||
sid_to_string(str2, s2->grp_sid);
|
||||
|
||||
DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
|
||||
str1, str2));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Check ACLs present in one but not the other */
|
||||
|
||||
if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
|
||||
(s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
|
||||
DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Sigh - we have to do it the hard way by iterating over all
|
||||
the ACEs in the ACLs */
|
||||
|
||||
if (!sec_acl_equal(s1->dacl, s2->dacl) ||
|
||||
!sec_acl_equal(s1->sacl, s2->sacl)) {
|
||||
DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
done:
|
||||
DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Merge part of security descriptor old_sec in to the empty sections of
|
||||
security descriptor new_sec.
|
||||
********************************************************************/
|
||||
|
||||
SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
|
||||
{
|
||||
DOM_SID *owner_sid, *group_sid;
|
||||
SEC_DESC_BUF *return_sdb;
|
||||
SEC_ACL *dacl, *sacl;
|
||||
SEC_DESC *psd = NULL;
|
||||
uint16 secdesc_type;
|
||||
size_t secdesc_size;
|
||||
|
||||
/* Copy over owner and group sids. There seems to be no flag for
|
||||
this so just check the pointer values. */
|
||||
|
||||
owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid :
|
||||
old_sdb->sec->owner_sid;
|
||||
|
||||
group_sid = new_sdb->sec->grp_sid ? new_sdb->sec->grp_sid :
|
||||
old_sdb->sec->grp_sid;
|
||||
|
||||
secdesc_type = new_sdb->sec->type;
|
||||
|
||||
/* Ignore changes to the system ACL. This has the effect of making
|
||||
changes through the security tab audit button not sticking.
|
||||
Perhaps in future Samba could implement these settings somehow. */
|
||||
|
||||
sacl = NULL;
|
||||
secdesc_type &= ~SEC_DESC_SACL_PRESENT;
|
||||
|
||||
/* Copy across discretionary ACL */
|
||||
|
||||
if (secdesc_type & SEC_DESC_DACL_PRESENT) {
|
||||
dacl = new_sdb->sec->dacl;
|
||||
} else {
|
||||
dacl = old_sdb->sec->dacl;
|
||||
}
|
||||
|
||||
/* Create new security descriptor from bits */
|
||||
|
||||
psd = make_sec_desc(ctx, new_sdb->sec->revision, secdesc_type,
|
||||
owner_sid, group_sid, sacl, dacl, &secdesc_size);
|
||||
|
||||
return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
|
||||
|
||||
return(return_sdb);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Creates a SEC_DESC structure
|
||||
********************************************************************/
|
||||
|
||||
SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type,
|
||||
DOM_SID *owner_sid, DOM_SID *grp_sid,
|
||||
SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
|
||||
{
|
||||
SEC_DESC *dst;
|
||||
uint32 offset = 0;
|
||||
|
||||
*sd_size = 0;
|
||||
|
||||
if(( dst = (SEC_DESC *)talloc_zero(ctx, sizeof(SEC_DESC))) == NULL)
|
||||
return NULL;
|
||||
|
||||
dst->revision = revision;
|
||||
dst->type = type;
|
||||
|
||||
if (sacl)
|
||||
dst->type |= SEC_DESC_SACL_PRESENT;
|
||||
if (dacl)
|
||||
dst->type |= SEC_DESC_DACL_PRESENT;
|
||||
|
||||
dst->off_owner_sid = 0;
|
||||
dst->off_grp_sid = 0;
|
||||
dst->off_sacl = 0;
|
||||
dst->off_dacl = 0;
|
||||
|
||||
if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL))
|
||||
goto error_exit;
|
||||
|
||||
if(grp_sid && ((dst->grp_sid = sid_dup_talloc(ctx,grp_sid)) == NULL))
|
||||
goto error_exit;
|
||||
|
||||
if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL))
|
||||
goto error_exit;
|
||||
|
||||
if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
|
||||
goto error_exit;
|
||||
|
||||
offset = SEC_DESC_HEADER_SIZE;
|
||||
|
||||
/*
|
||||
* Work out the linearization sizes.
|
||||
*/
|
||||
|
||||
if (dst->sacl != NULL) {
|
||||
dst->off_sacl = offset;
|
||||
offset += dst->sacl->size;
|
||||
}
|
||||
|
||||
if (dst->dacl != NULL) {
|
||||
dst->off_dacl = offset;
|
||||
offset += dst->dacl->size;
|
||||
}
|
||||
|
||||
if (dst->owner_sid != NULL) {
|
||||
dst->off_owner_sid = offset;
|
||||
offset += sid_size(dst->owner_sid);
|
||||
}
|
||||
|
||||
if (dst->grp_sid != NULL) {
|
||||
dst->off_grp_sid = offset;
|
||||
offset += sid_size(dst->grp_sid);
|
||||
}
|
||||
|
||||
*sd_size = (size_t)offset;
|
||||
return dst;
|
||||
|
||||
error_exit:
|
||||
|
||||
*sd_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Duplicate a SEC_DESC structure.
|
||||
********************************************************************/
|
||||
|
||||
SEC_DESC *dup_sec_desc( TALLOC_CTX *ctx, SEC_DESC *src)
|
||||
{
|
||||
size_t dummy;
|
||||
|
||||
if(src == NULL)
|
||||
return NULL;
|
||||
|
||||
return make_sec_desc( ctx, src->revision, src->type,
|
||||
src->owner_sid, src->grp_sid, src->sacl,
|
||||
src->dacl, &dummy);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Creates a SEC_DESC structure with typical defaults.
|
||||
********************************************************************/
|
||||
|
||||
SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
|
||||
SEC_ACL *dacl, size_t *sd_size)
|
||||
{
|
||||
return make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
|
||||
owner_sid, grp_sid, NULL, dacl, sd_size);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes a SEC_DESC structure.
|
||||
If reading and the *ppsd = NULL, allocates the structure.
|
||||
@ -807,42 +306,6 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Creates a SEC_DESC_BUF structure.
|
||||
********************************************************************/
|
||||
|
||||
SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
|
||||
{
|
||||
SEC_DESC_BUF *dst;
|
||||
|
||||
if((dst = (SEC_DESC_BUF *)talloc_zero(ctx, sizeof(SEC_DESC_BUF))) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* max buffer size (allocated size) */
|
||||
dst->max_len = (uint32)len;
|
||||
dst->len = (uint32)len;
|
||||
|
||||
if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dst->ptr = 0x1;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Duplicates a SEC_DESC_BUF structure.
|
||||
********************************************************************/
|
||||
|
||||
SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
|
||||
{
|
||||
if(src == NULL)
|
||||
return NULL;
|
||||
|
||||
return make_sec_desc_buf( ctx, src->len, src->sec);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes a SEC_DESC_BUF structure.
|
||||
********************************************************************/
|
||||
@ -901,193 +364,3 @@ BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Add a new SID with its permissions to SEC_DESC.
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
|
||||
{
|
||||
SEC_DESC *sd = 0;
|
||||
SEC_ACL *dacl = 0;
|
||||
SEC_ACE *ace = 0;
|
||||
NTSTATUS status;
|
||||
|
||||
*sd_size = 0;
|
||||
|
||||
if (!ctx || !psd || !sid || !sd_size)
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status))
|
||||
return status;
|
||||
|
||||
if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid,
|
||||
psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
*psd = sd;
|
||||
sd = 0;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Modify a SID's permissions in a SEC_DESC.
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (!sd || !sid)
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status))
|
||||
return status;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Delete a SID from a SEC_DESC.
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
|
||||
{
|
||||
SEC_DESC *sd = 0;
|
||||
SEC_ACL *dacl = 0;
|
||||
SEC_ACE *ace = 0;
|
||||
NTSTATUS status;
|
||||
|
||||
*sd_size = 0;
|
||||
|
||||
if (!ctx || !psd[0] || !sid || !sd_size)
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status))
|
||||
return status;
|
||||
|
||||
if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid,
|
||||
psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
*psd = sd;
|
||||
sd = 0;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Comparison function to sort non-inherited first.
|
||||
*******************************************************************/
|
||||
|
||||
static int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2)
|
||||
{
|
||||
int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
|
||||
int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
|
||||
|
||||
if (a1_inh == a2_inh)
|
||||
return 0;
|
||||
|
||||
if (!a1_inh && a2_inh)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Comparison function to apply the order explained below in a group.
|
||||
*******************************************************************/
|
||||
|
||||
static int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2)
|
||||
{
|
||||
if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
|
||||
(a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
|
||||
return -1;
|
||||
|
||||
if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
|
||||
(a1->type != SEC_ACE_TYPE_ACCESS_DENIED))
|
||||
return 1;
|
||||
|
||||
/* Both access denied or access allowed. */
|
||||
|
||||
/* 1. ACEs that apply to the object itself */
|
||||
|
||||
if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
|
||||
(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
|
||||
return -1;
|
||||
else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
|
||||
(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
|
||||
return 1;
|
||||
|
||||
/* 2. ACEs that apply to a subobject of the object, such as
|
||||
* a property set or property. */
|
||||
|
||||
if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
|
||||
!(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
|
||||
return -1;
|
||||
else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
|
||||
!(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Functions to convert a SEC_DESC ACE DACL list into canonical order.
|
||||
JRA.
|
||||
|
||||
--- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
|
||||
|
||||
The following describes the preferred order:
|
||||
|
||||
To ensure that noninherited ACEs have precedence over inherited ACEs,
|
||||
place all noninherited ACEs in a group before any inherited ACEs.
|
||||
This ordering ensures, for example, that a noninherited access-denied ACE
|
||||
is enforced regardless of any inherited ACE that allows access.
|
||||
|
||||
Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
|
||||
1. Access-denied ACEs that apply to the object itself
|
||||
2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
|
||||
3. Access-allowed ACEs that apply to the object itself
|
||||
4. Access-allowed ACEs that apply to a subobject of the object"
|
||||
|
||||
********************************************************************/
|
||||
|
||||
void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!srclist || num_aces == 0)
|
||||
return;
|
||||
|
||||
/* Sort so that non-inherited ACE's come first. */
|
||||
qsort( srclist, num_aces, sizeof(srclist[0]), QSORT_CAST nt_ace_inherit_comp);
|
||||
|
||||
/* Find the boundary between non-inherited ACEs. */
|
||||
for (i = 0; i < num_aces; i++ ) {
|
||||
SEC_ACE *curr_ace = &srclist[i];
|
||||
|
||||
if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
|
||||
break;
|
||||
}
|
||||
|
||||
/* i now points at entry number of the first inherited ACE. */
|
||||
|
||||
/* Sort the non-inherited ACEs. */
|
||||
if (i)
|
||||
qsort( srclist, i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
|
||||
|
||||
/* Now sort the inherited ACEs. */
|
||||
if (num_aces - i)
|
||||
qsort( &srclist[i], num_aces - i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
|
||||
}
|
||||
|
@ -443,7 +443,7 @@ static BOOL api_lsa_enum_privsaccount(pipes_struct *p)
|
||||
return False;
|
||||
}
|
||||
|
||||
r_u.status = _lsa_enum_privsaccount(p, &q_u, &r_u);
|
||||
r_u.status = _lsa_enum_privsaccount(p, rdata, &q_u, &r_u);
|
||||
|
||||
/* store the response in the SMB stream */
|
||||
if(!lsa_io_r_enum_privsaccount("", &r_u, rdata, 0)) {
|
||||
|
@ -955,7 +955,7 @@ NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENAC
|
||||
For a given SID, enumerate all the privilege this account has.
|
||||
***************************************************************************/
|
||||
|
||||
NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
|
||||
NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
|
||||
{
|
||||
struct lsa_info *info=NULL;
|
||||
GROUP_MAP map;
|
||||
@ -971,29 +971,29 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LS
|
||||
return NT_STATUS_NO_SUCH_GROUP;
|
||||
|
||||
#if 0 /* privileges currently not implemented! */
|
||||
DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", map.priv_set.count));
|
||||
if (map.priv_set.count!=0) {
|
||||
DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", map.priv_set->count));
|
||||
if (map.priv_set->count!=0) {
|
||||
|
||||
set=(LUID_ATTR *)talloc(p->mem_ctx, map.priv_set.count*sizeof(LUID_ATTR));
|
||||
set=(LUID_ATTR *)talloc(map.priv_set->mem_ctx, map.priv_set.count*sizeof(LUID_ATTR));
|
||||
if (set == NULL) {
|
||||
free_privilege(&map.priv_set);
|
||||
destroy_privilege(&map.priv_set);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (i=0; i<map.priv_set.count; i++) {
|
||||
set[i].luid.low=map.priv_set.set[i].luid.low;
|
||||
set[i].luid.high=map.priv_set.set[i].luid.high;
|
||||
set[i].attr=map.priv_set.set[i].attr;
|
||||
for (i = 0; i < map.priv_set.count; i++) {
|
||||
set[i].luid.low = map.priv_set->set[i].luid.low;
|
||||
set[i].luid.high = map.priv_set->set[i].luid.high;
|
||||
set[i].attr = map.priv_set->set[i].attr;
|
||||
DEBUG(10,("_lsa_enum_privsaccount: priv %d: %d:%d:%d\n", i,
|
||||
set[i].luid.high, set[i].luid.low, set[i].attr));
|
||||
}
|
||||
}
|
||||
|
||||
init_lsa_r_enum_privsaccount(r_u, set, map.priv_set.count, 0);
|
||||
free_privilege(&map.priv_set);
|
||||
init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, set, map.priv_set->count, 0);
|
||||
destroy_privilege(&map.priv_set);
|
||||
#endif
|
||||
|
||||
init_lsa_r_enum_privsaccount(r_u, set, 0, 0);
|
||||
init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, set, 0, 0);
|
||||
|
||||
return r_u->status;
|
||||
}
|
||||
@ -1059,11 +1059,11 @@ NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA
|
||||
NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
|
||||
{
|
||||
#if 0
|
||||
struct lsa_info *info=NULL;
|
||||
struct lsa_info *info = NULL;
|
||||
GROUP_MAP map;
|
||||
int i=0;
|
||||
LUID_ATTR *luid_attr=NULL;
|
||||
PRIVILEGE_SET *set=NULL;
|
||||
int i = 0;
|
||||
LUID_ATTR *luid_attr = NULL;
|
||||
PRIVILEGE_SET *set = NULL;
|
||||
#endif
|
||||
|
||||
r_u->status = NT_STATUS_OK;
|
||||
@ -1076,24 +1076,24 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
|
||||
if (!pdb_getgrsid(&map, info->sid))
|
||||
return NT_STATUS_NO_SUCH_GROUP;
|
||||
|
||||
set=&q_u->set;
|
||||
set = &q_u->set;
|
||||
|
||||
for (i=0; i<set->count; i++) {
|
||||
luid_attr=&set->set[i];
|
||||
for (i = 0; i < set->count; i++) {
|
||||
luid_attr = &set->set[i];
|
||||
|
||||
/* check if the privilege is already there */
|
||||
if (check_priv_in_privilege(&map.priv_set, *luid_attr)){
|
||||
free_privilege(&map.priv_set);
|
||||
if (check_priv_in_privilege(map.priv_set, *luid_attr)){
|
||||
destroy_privilege(&map.priv_set);
|
||||
return NT_STATUS_NO_SUCH_PRIVILEGE;
|
||||
}
|
||||
|
||||
add_privilege(&map.priv_set, *luid_attr);
|
||||
add_privilege(map.priv_set, *luid_attr);
|
||||
}
|
||||
|
||||
if(!pdb_update_group_mapping_entry(&map))
|
||||
return NT_STATUS_NO_SUCH_GROUP;
|
||||
|
||||
free_privilege(&map.priv_set);
|
||||
destroy_privilege(&map.priv_set);
|
||||
|
||||
#endif
|
||||
return r_u->status;
|
||||
@ -1106,11 +1106,11 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
|
||||
NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
|
||||
{
|
||||
#if 0
|
||||
struct lsa_info *info=NULL;
|
||||
struct lsa_info *info = NULL;
|
||||
GROUP_MAP map;
|
||||
int i=0;
|
||||
LUID_ATTR *luid_attr=NULL;
|
||||
PRIVILEGE_SET *set=NULL;
|
||||
LUID_ATTR *luid_attr = NULL;
|
||||
PRIVILEGE_SET *set = NULL;
|
||||
#endif
|
||||
|
||||
r_u->status = NT_STATUS_OK;
|
||||
@ -1123,37 +1123,37 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP
|
||||
if (!pdb_getgrsid(&map, info->sid))
|
||||
return NT_STATUS_NO_SUCH_GROUP;
|
||||
|
||||
if (q_u->allrights!=0) {
|
||||
if (q_u->allrights != 0) {
|
||||
/* log it and return, until I see one myself don't do anything */
|
||||
DEBUG(5,("_lsa_removeprivs: trying to remove all privileges ?\n"));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
if (q_u->ptr==0) {
|
||||
if (q_u->ptr == 0) {
|
||||
/* log it and return, until I see one myself don't do anything */
|
||||
DEBUG(5,("_lsa_removeprivs: no privileges to remove ?\n"));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
set=&q_u->set;
|
||||
set = &q_u->set;
|
||||
|
||||
for (i=0; i<set->count; i++) {
|
||||
luid_attr=&set->set[i];
|
||||
for (i = 0; i < set->count; i++) {
|
||||
luid_attr = &set->set[i];
|
||||
|
||||
/* if we don't have the privilege, we're trying to remove, give up */
|
||||
/* what else can we do ??? JFM. */
|
||||
if (!check_priv_in_privilege(&map.priv_set, *luid_attr)){
|
||||
free_privilege(&map.priv_set);
|
||||
if (!check_priv_in_privilege(map.priv_set, *luid_attr)){
|
||||
destroy_privilege(&map.priv_set);
|
||||
return NT_STATUS_NO_SUCH_PRIVILEGE;
|
||||
}
|
||||
|
||||
remove_privilege(&map.priv_set, *luid_attr);
|
||||
remove_privilege(map.priv_set, *luid_attr);
|
||||
}
|
||||
|
||||
if(!pdb_update_group_mapping_entry(&map))
|
||||
return NT_STATUS_NO_SUCH_GROUP;
|
||||
|
||||
free_privilege(&map.priv_set);
|
||||
destroy_privilege(&map.priv_set);
|
||||
#endif
|
||||
return r_u->status;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ END {
|
||||
gotstart = 1;
|
||||
}
|
||||
|
||||
if( $0 ~ /^ADS_STRUCT|^ADS_STATUS|^DATA_BLOB|^ASN1_DATA|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) {
|
||||
if( $0 ~ /^ADS_STRUCT|^ADS_STATUS|^DATA_BLOB|^ASN1_DATA|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT|^NTTIME/ ) {
|
||||
gotstart = 1;
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,7 @@ char *add_suffix(const char *name, const char *suffix)
|
||||
fprintf(stderr,"Out of memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
strncpy(ret, name, len);
|
||||
strncat(ret, suffix, len);
|
||||
snprintf(ret, len, "%s%s", name, suffix);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user