1
0
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:
Andrew Tridgell 0001-01-01 00:00:00 +00:00
parent f0a8f063a6
commit 1f93cbc1d5
9 changed files with 210 additions and 23 deletions

View File

@ -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
);
/******************/

View File

@ -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; \

View File

@ -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

View File

@ -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
*/

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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;
}