mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
added lsa_QuerySecObj() and the necessary sec_desc_buf supporting code
also adding printing of security descriptors
This commit is contained in:
parent
f0a8f063a6
commit
1f93cbc1d5
@ -51,7 +51,11 @@
|
||||
|
||||
/******************/
|
||||
/* Function: 0x03 */
|
||||
NTSTATUS lsa_QuerySecObj ();
|
||||
NTSTATUS lsa_QuerySecObj (
|
||||
[in,ref] policy_handle *handle,
|
||||
[in] uint32 sec_info,
|
||||
[out] sec_desc_buf *sd
|
||||
);
|
||||
|
||||
|
||||
/******************/
|
||||
|
@ -88,6 +88,27 @@ enum ndr_err_code {
|
||||
#define NDR_SCALARS 1
|
||||
#define NDR_BUFFERS 2
|
||||
|
||||
#define NDR_PULL_NEED_BYTES(ndr, n) do { \
|
||||
if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \
|
||||
return NT_STATUS_BUFFER_TOO_SMALL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NDR_PULL_ALIGN(ndr, n) do { \
|
||||
ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
|
||||
if (ndr->offset >= ndr->data_size) { \
|
||||
return NT_STATUS_BUFFER_TOO_SMALL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n)))
|
||||
|
||||
#define NDR_PUSH_ALIGN(ndr, n) do { \
|
||||
uint32 _pad = (ndr->offset & (n-1)); \
|
||||
while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* these are used to make the error checking on each element in libndr
|
||||
less tedious, hopefully making the code more readable */
|
||||
#define NDR_CHECK(call) do { NTSTATUS _status; \
|
||||
|
@ -50,6 +50,20 @@ struct ndr_pull *ndr_pull_init_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
|
||||
return ndr;
|
||||
}
|
||||
|
||||
/*
|
||||
create an ndr sub-context based on an existing context. The new context starts
|
||||
at the current offset, with the given size limit
|
||||
*/
|
||||
NTSTATUS ndr_pull_subcontext(struct ndr_pull *ndr, struct ndr_pull *ndr2, uint32 size)
|
||||
{
|
||||
NDR_PULL_NEED_BYTES(ndr, size);
|
||||
*ndr2 = *ndr;
|
||||
ndr2->data += ndr2->offset;
|
||||
ndr2->offset = 0;
|
||||
ndr2->data_size = size;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* limit the remaining size of the current ndr parse structure to the
|
||||
given size, starting at the given offset
|
||||
|
@ -22,19 +22,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#define NDR_PULL_NEED_BYTES(ndr, n) do { \
|
||||
if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \
|
||||
return NT_STATUS_BUFFER_TOO_SMALL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NDR_PULL_ALIGN(ndr, n) do { \
|
||||
ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
|
||||
if (ndr->offset >= ndr->data_size) { \
|
||||
return NT_STATUS_BUFFER_TOO_SMALL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
parse a uint8
|
||||
*/
|
||||
@ -152,13 +139,6 @@ NTSTATUS ndr_pull_GUID(struct ndr_pull *ndr, int ndr_flags, GUID *guid)
|
||||
}
|
||||
|
||||
|
||||
#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n)))
|
||||
|
||||
#define NDR_PUSH_ALIGN(ndr, n) do { \
|
||||
uint32 _pad = (ndr->offset & (n-1)); \
|
||||
while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
push a uint8
|
||||
*/
|
||||
|
@ -43,6 +43,8 @@ NTSTATUS ndr_push_lsa_EnumPrivs(struct ndr_push *ndr, struct lsa_EnumPrivs *r)
|
||||
|
||||
NTSTATUS ndr_push_lsa_QuerySecObj(struct ndr_push *ndr, struct lsa_QuerySecObj *r)
|
||||
{
|
||||
NDR_CHECK(ndr_push_policy_handle(ndr, r->in.handle));
|
||||
NDR_CHECK(ndr_push_uint32(ndr, r->in.sec_info));
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -582,6 +584,16 @@ NTSTATUS ndr_pull_lsa_EnumPrivs(struct ndr_pull *ndr, struct lsa_EnumPrivs *r)
|
||||
|
||||
NTSTATUS ndr_pull_lsa_QuerySecObj(struct ndr_pull *ndr, struct lsa_QuerySecObj *r)
|
||||
{
|
||||
uint32 _ptr_sd;
|
||||
NDR_CHECK(ndr_pull_uint32(ndr, &_ptr_sd));
|
||||
if (_ptr_sd) {
|
||||
NDR_ALLOC(ndr, r->out.sd);
|
||||
} else {
|
||||
r->out.sd = NULL;
|
||||
}
|
||||
if (r->out.sd) {
|
||||
NDR_CHECK(ndr_pull_sec_desc_buf(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sd));
|
||||
}
|
||||
NDR_CHECK(ndr_pull_NTSTATUS(ndr, &r->out.result));
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
@ -57,9 +57,12 @@ struct lsa_EnumPrivs {
|
||||
|
||||
struct lsa_QuerySecObj {
|
||||
struct {
|
||||
struct policy_handle *handle;
|
||||
uint32 sec_info;
|
||||
} in;
|
||||
|
||||
struct {
|
||||
struct sec_desc_buf *sd;
|
||||
NTSTATUS result;
|
||||
} out;
|
||||
|
||||
|
@ -50,6 +50,8 @@ NTSTATUS ndr_pull_security_ace(struct ndr_pull *ndr, struct security_ace *ace)
|
||||
if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
|
||||
NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &ace->obj->inherit_guid));
|
||||
}
|
||||
} else {
|
||||
ace->obj = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -354,6 +356,44 @@ void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, struct dom_sid2
|
||||
ndr_print_dom_sid(ndr, name, sid);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
print a security_ace
|
||||
*/
|
||||
void ndr_print_security_ace(struct ndr_print *ndr, const char *name, struct security_ace *ace)
|
||||
{
|
||||
ndr_print_struct(ndr, name, "security_ace");
|
||||
ndr->depth++;
|
||||
ndr_print_uint8(ndr, "type", ace->type);
|
||||
ndr_print_uint8(ndr, "flags", ace->flags);
|
||||
ndr_print_uint32(ndr, "access_mask", ace->access_mask);
|
||||
if (ace->obj) {
|
||||
ndr_print_struct(ndr, name, "security_ace_obj");
|
||||
ndr->depth++;
|
||||
ndr_print_uint32(ndr, "flags", ace->obj->flags);
|
||||
ndr_print_GUID(ndr, "object_guid", &ace->obj->object_guid);
|
||||
ndr_print_GUID(ndr, "inherit_guid", &ace->obj->inherit_guid);
|
||||
ndr->depth--;
|
||||
}
|
||||
ndr_print_dom_sid(ndr, "trustee", &ace->trustee);
|
||||
ndr->depth--;
|
||||
}
|
||||
|
||||
/*
|
||||
print a security_acl
|
||||
*/
|
||||
void ndr_print_security_acl(struct ndr_print *ndr, const char *name, struct security_acl *acl)
|
||||
{
|
||||
ndr_print_struct(ndr, name, "security_acl");
|
||||
ndr->depth++;
|
||||
ndr_print_uint16(ndr, "revision", acl->revision);
|
||||
ndr_print_uint32(ndr, "num_aces", acl->num_aces);
|
||||
ndr_print_array(ndr, "aces", acl->aces,
|
||||
sizeof(acl->aces[0]), acl->num_aces,
|
||||
(ndr_print_fn_t) ndr_print_security_ace);
|
||||
ndr->depth--;
|
||||
}
|
||||
|
||||
/*
|
||||
print a security descriptor
|
||||
*/
|
||||
@ -361,8 +401,75 @@ void ndr_print_security_descriptor(struct ndr_print *ndr,
|
||||
const char *name,
|
||||
struct security_descriptor *sd)
|
||||
{
|
||||
ndr->print(ndr, "%-25s: ndr_print_security_descriptor not implemented",
|
||||
name);
|
||||
ndr_print_struct(ndr, name, "security_descriptor");
|
||||
ndr->depth++;
|
||||
ndr_print_uint8(ndr, "revision", sd->revision);
|
||||
ndr_print_uint16(ndr, "type", sd->type);
|
||||
ndr_print_ptr(ndr, "owner_sid", sd->owner_sid);
|
||||
if (sd->owner_sid) {
|
||||
ndr_print_dom_sid(ndr, "owner_sid", sd->owner_sid);
|
||||
}
|
||||
ndr_print_ptr(ndr, "group_sid", sd->group_sid);
|
||||
if (sd->group_sid) {
|
||||
ndr_print_dom_sid(ndr, "group_sid", sd->group_sid);
|
||||
}
|
||||
ndr_print_ptr(ndr, "sacl", sd->sacl);
|
||||
if (sd->sacl) {
|
||||
ndr_print_security_acl(ndr, "sacl", sd->sacl);
|
||||
}
|
||||
ndr_print_ptr(ndr, "dacl", sd->dacl);
|
||||
if (sd->dacl) {
|
||||
ndr_print_security_acl(ndr, "dacl", sd->dacl);
|
||||
}
|
||||
ndr->depth--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
implementation of sec_desc_buf - an encapsulated security descriptor
|
||||
*/
|
||||
NTSTATUS ndr_pull_sec_desc_buf(struct ndr_pull *ndr, int ndr_flags,
|
||||
struct sec_desc_buf *sdbuf)
|
||||
{
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
uint32 _ptr;
|
||||
NDR_CHECK(ndr_pull_uint32(ndr, &sdbuf->size));
|
||||
NDR_CHECK(ndr_pull_uint32(ndr, &_ptr));
|
||||
if (_ptr) {
|
||||
NDR_ALLOC(ndr, sdbuf->sd);
|
||||
} else {
|
||||
sdbuf->sd = NULL;
|
||||
}
|
||||
}
|
||||
if (ndr_flags & NDR_BUFFERS) {
|
||||
if (sdbuf->sd) {
|
||||
struct ndr_pull ndr2;
|
||||
uint32 size;
|
||||
NDR_CHECK(ndr_pull_uint32(ndr, &size));
|
||||
if (size != sdbuf->size) {
|
||||
return NT_STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, sdbuf->size));
|
||||
NDR_CHECK(ndr_pull_security_descriptor(&ndr2, sdbuf->sd));
|
||||
NDR_CHECK(ndr_pull_advance(ndr, sdbuf->size));
|
||||
}
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
print a sec_desc_buf
|
||||
*/
|
||||
void ndr_print_sec_desc_buf(struct ndr_print *ndr, const char *name,
|
||||
struct sec_desc_buf *sdbuf)
|
||||
{
|
||||
ndr_print_struct(ndr, name, "sec_desc_buf");
|
||||
ndr->depth++;
|
||||
ndr_print_uint32(ndr, "size", sdbuf->size);
|
||||
ndr_print_ptr(ndr, "sd", sdbuf->sd);
|
||||
if (sdbuf->sd) {
|
||||
ndr_print_security_descriptor(ndr, "sd", sdbuf->sd);
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,23 @@ struct security_descriptor {
|
||||
struct security_acl *dacl; /* user (discretionary) ACL */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
a security descriptor encapsulated in a buffer.
|
||||
It is like this IDL:
|
||||
typedef struct {
|
||||
uint32 size;
|
||||
[size_is(size)] uint8 *buf;
|
||||
} sec_desc_buf;
|
||||
*/
|
||||
struct sec_desc_buf {
|
||||
uint32 size; /* the sd wire size - auto-generated */
|
||||
struct security_descriptor *sd;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* query security descriptor */
|
||||
struct smb_query_secdesc {
|
||||
struct {
|
||||
|
@ -332,6 +332,31 @@ static BOOL test_EnumAccountRights(struct dcerpc_pipe *p,
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_QuerySecObj(struct dcerpc_pipe *p,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *acct_handle,
|
||||
struct dom_sid *sid)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct lsa_QuerySecObj r;
|
||||
|
||||
printf("Testing QuerySecObj\n");
|
||||
|
||||
r.in.handle = acct_handle;
|
||||
r.in.sec_info = 7;
|
||||
|
||||
status = dcerpc_lsa_QuerySecObj(p, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("QuerySecObj failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
NDR_PRINT_DEBUG(sec_desc_buf, r.out.sd);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL test_OpenAccount(struct dcerpc_pipe *p,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle,
|
||||
@ -358,6 +383,10 @@ static BOOL test_OpenAccount(struct dcerpc_pipe *p,
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!test_QuerySecObj(p, mem_ctx, handle, &acct_handle)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user