diff options
-rw-r--r-- | source4/librpc/idl/lsa.idl | 31 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_lsa.c | 88 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_lsa.h | 22 | ||||
-rw-r--r-- | source4/librpc/rpc/rpc_lsa.c | 8 | ||||
-rw-r--r-- | source4/torture/rpc/lsa.c | 46 |
5 files changed, 178 insertions, 17 deletions
diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl index f604534a78..6766775c9c 100644 --- a/source4/librpc/idl/lsa.idl +++ b/source4/librpc/idl/lsa.idl @@ -20,6 +20,7 @@ [in,ref] policy_handle *handle ); + /******************/ /* Function: 0x02 */ @@ -47,14 +48,17 @@ [out,ref] lsa_PrivArray *privs ); + /******************/ /* Function: 0x03 */ NTSTATUS lsa_QuerySecObj (); + /******************/ /* Function: 0x04 */ NTSTATUS lsa_SetSecObj (); + /******************/ /* Function: 0x05 */ NTSTATUS lsa_ChangePassword (); @@ -225,8 +229,31 @@ ); - /* Function: 0x12 */ - NTSTATUS ENUMPRIVSACCOUNT (); + /****************************************/ + /* Function: 0x12 */ + + typedef struct { + uint32 low; + uint32 high; + } lsa_LUID; + + typedef struct { + lsa_LUID luid; + uint32 attribute; + } lsa_LUIDAttribute; + + typedef struct { + uint32 count; + [size_is(count)] lsa_LUIDAttribute set[*]; + } lsa_PrivilegeSet; + + NTSTATUS lsa_EnumPrivsAccount ( + [in,ref] policy_handle *handle, + [out] lsa_PrivilegeSet *privs, + [out] uint32 unknown + ); + + /* Function: 0x13 */ NTSTATUS ADDPRIVS (); /* Function: 0x14 */ diff --git a/source4/librpc/ndr/ndr_lsa.c b/source4/librpc/ndr/ndr_lsa.c index 37850fbf19..59d3fc9b7b 100644 --- a/source4/librpc/ndr/ndr_lsa.c +++ b/source4/librpc/ndr/ndr_lsa.c @@ -726,7 +726,6 @@ NTSTATUS ndr_push_lsa_LookupNames(struct ndr_push *ndr, struct lsa_LookupNames * NTSTATUS ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, struct lsa_LookupNames *r) { uint32 _ptr_domains; - NDR_ALLOC(ndr, r->out.domains); NDR_CHECK(ndr_pull_uint32(ndr, &_ptr_domains)); if (_ptr_domains) { NDR_ALLOC(ndr, r->out.domains); @@ -818,7 +817,6 @@ NTSTATUS ndr_push_lsa_LookupSids(struct ndr_push *ndr, struct lsa_LookupSids *r) NTSTATUS ndr_pull_lsa_LookupSids(struct ndr_pull *ndr, struct lsa_LookupSids *r) { uint32 _ptr_domains; - NDR_ALLOC(ndr, r->out.domains); NDR_CHECK(ndr_pull_uint32(ndr, &_ptr_domains)); if (_ptr_domains) { NDR_ALLOC(ndr, r->out.domains); @@ -865,14 +863,96 @@ NTSTATUS ndr_pull_lsa_OpenAccount(struct ndr_pull *ndr, struct lsa_OpenAccount * return NT_STATUS_OK; } -NTSTATUS ndr_push_ENUMPRIVSACCOUNT(struct ndr_push *ndr, struct ENUMPRIVSACCOUNT *r) +static NTSTATUS ndr_push_lsa_LUID(struct ndr_push *ndr, int ndr_flags, struct lsa_LUID *r) { + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_push_uint32(ndr, r->low)); + NDR_CHECK(ndr_push_uint32(ndr, r->high)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; +done: + return NT_STATUS_OK; +} +static NTSTATUS ndr_pull_lsa_LUID(struct ndr_pull *ndr, int ndr_flags, struct lsa_LUID *r) +{ + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_uint32(ndr, &r->low)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->high)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; +done: return NT_STATUS_OK; } -NTSTATUS ndr_pull_ENUMPRIVSACCOUNT(struct ndr_pull *ndr, struct ENUMPRIVSACCOUNT *r) +static NTSTATUS ndr_push_lsa_LUIDAttribute(struct ndr_push *ndr, int ndr_flags, struct lsa_LUIDAttribute *r) { + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_push_lsa_LUID(ndr, NDR_SCALARS, &r->luid)); + NDR_CHECK(ndr_push_uint32(ndr, r->attribute)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_push_lsa_LUID(ndr, ndr_flags, &r->luid)); +done: + return NT_STATUS_OK; +} + +static NTSTATUS ndr_pull_lsa_LUIDAttribute(struct ndr_pull *ndr, int ndr_flags, struct lsa_LUIDAttribute *r) +{ + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_lsa_LUID(ndr, NDR_SCALARS, &r->luid)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->attribute)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_pull_lsa_LUID(ndr, ndr_flags, &r->luid)); +done: + return NT_STATUS_OK; +} + +static NTSTATUS ndr_push_lsa_PrivilegeSet(struct ndr_push *ndr, int ndr_flags, struct lsa_PrivilegeSet *r) +{ + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_push_uint32(ndr, r->count)); + NDR_CHECK(ndr_push_lsa_LUIDAttribute(ndr, NDR_SCALARS, r->set)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_push_array(ndr, ndr_flags, r->set, sizeof(r->set[0]), r->count, (ndr_push_flags_fn_t)ndr_push_lsa_LUIDAttribute)); +done: + return NT_STATUS_OK; +} + +static NTSTATUS ndr_pull_lsa_PrivilegeSet(struct ndr_pull *ndr, int ndr_flags, struct lsa_PrivilegeSet *r) +{ + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_uint32(ndr, &r->count)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_ALLOC_N_SIZE(ndr, r->set, r->count, sizeof(r->set[0])); + NDR_CHECK(ndr_pull_array(ndr, ndr_flags, (void **)r->set, sizeof(r->set[0]), r->count, (ndr_pull_flags_fn_t)ndr_pull_lsa_LUIDAttribute)); +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_push_lsa_EnumPrivsAccount(struct ndr_push *ndr, struct lsa_EnumPrivsAccount *r) +{ + NDR_CHECK(ndr_push_policy_handle(ndr, r->in.handle)); + + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_lsa_EnumPrivsAccount(struct ndr_pull *ndr, struct lsa_EnumPrivsAccount *r) +{ + uint32 _ptr_privs; + NDR_CHECK(ndr_pull_uint32(ndr, &_ptr_privs)); + if (_ptr_privs) { + NDR_ALLOC(ndr, r->out.privs); + } else { + r->out.privs = NULL; + } + if (r->out.privs) { + NDR_CHECK(ndr_pull_lsa_PrivilegeSet(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.privs)); + } + NDR_CHECK(ndr_pull_uint32(ndr, &r->out.unknown)); NDR_CHECK(ndr_pull_NTSTATUS(ndr, &r->out.result)); return NT_STATUS_OK; diff --git a/source4/librpc/ndr/ndr_lsa.h b/source4/librpc/ndr/ndr_lsa.h index 473cf370c6..f8c4ab5f6a 100644 --- a/source4/librpc/ndr/ndr_lsa.h +++ b/source4/librpc/ndr/ndr_lsa.h @@ -306,11 +306,29 @@ struct lsa_OpenAccount { }; -struct ENUMPRIVSACCOUNT { +struct lsa_LUID { + uint32 low; + uint32 high; +}; + +struct lsa_LUIDAttribute { + struct lsa_LUID luid; + uint32 attribute; +}; + +struct lsa_PrivilegeSet { + uint32 count; + struct lsa_LUIDAttribute *set; +}; + +struct lsa_EnumPrivsAccount { struct { + struct policy_handle *handle; } in; struct { + struct lsa_PrivilegeSet *privs; + uint32 unknown; NTSTATUS result; } out; @@ -618,7 +636,7 @@ struct QUERYINFO2 { #define DCERPC_LSA_LOOKUPSIDS 15 #define DCERPC_CREATESECRET 16 #define DCERPC_LSA_OPENACCOUNT 17 -#define DCERPC_ENUMPRIVSACCOUNT 18 +#define DCERPC_LSA_ENUMPRIVSACCOUNT 18 #define DCERPC_ADDPRIVS 19 #define DCERPC_REMOVEPRIVS 20 #define DCERPC_GETQUOTAS 21 diff --git a/source4/librpc/rpc/rpc_lsa.c b/source4/librpc/rpc/rpc_lsa.c index c5c18fe7ea..c514cdbb78 100644 --- a/source4/librpc/rpc/rpc_lsa.c +++ b/source4/librpc/rpc/rpc_lsa.c @@ -255,12 +255,12 @@ NTSTATUS dcerpc_lsa_OpenAccount(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, stru return r->out.result; } -NTSTATUS dcerpc_ENUMPRIVSACCOUNT(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct ENUMPRIVSACCOUNT *r) +NTSTATUS dcerpc_lsa_EnumPrivsAccount(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct lsa_EnumPrivsAccount *r) { NTSTATUS status; - status = dcerpc_ndr_request(p, DCERPC_ENUMPRIVSACCOUNT, mem_ctx, - (ndr_push_fn_t) ndr_push_ENUMPRIVSACCOUNT, - (ndr_pull_fn_t) ndr_pull_ENUMPRIVSACCOUNT, + status = dcerpc_ndr_request(p, DCERPC_LSA_ENUMPRIVSACCOUNT, mem_ctx, + (ndr_push_fn_t) ndr_push_lsa_EnumPrivsAccount, + (ndr_pull_fn_t) ndr_pull_lsa_EnumPrivsAccount, r); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index df095aca6e..f4c4858c8e 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -271,6 +271,40 @@ static BOOL test_LookupSids(struct dcerpc_pipe *p, return True; } +static BOOL test_EnumPrivsAccount(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + struct policy_handle *acct_handle) +{ + NTSTATUS status; + struct lsa_EnumPrivsAccount r; + + printf("Testing EnumPrivsAccount\n"); + + r.in.handle = acct_handle; + + status = dcerpc_lsa_EnumPrivsAccount(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("EnumPrivsAccount failed - %s\n", nt_errstr(status)); + return False; + } + + printf("received %d privileges with unknown=0x%x\n", + r.out.privs?r.out.privs->count:0, r.out.unknown); + + if (r.out.privs) { + struct lsa_PrivilegeSet *privs = r.out.privs; + int i; + for (i=0;i<privs->count;i++) { + printf("luid=%08x-%08x attribute=0x%08x\n", + privs->set[i].luid.low, + privs->set[i].luid.high, + privs->set[i].attribute); + } + } + + return True; +} + static BOOL test_OpenAccount(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, @@ -280,7 +314,7 @@ static BOOL test_OpenAccount(struct dcerpc_pipe *p, struct lsa_OpenAccount r; struct policy_handle acct_handle; - printf("Testing account %s\n", lsa_sid_string_talloc(mem_ctx, sid)); + printf("Testing OpenAccount(%s)\n", lsa_sid_string_talloc(mem_ctx, sid)); r.in.handle = handle; r.in.sid = sid; @@ -293,6 +327,10 @@ static BOOL test_OpenAccount(struct dcerpc_pipe *p, return False; } + if (!test_EnumPrivsAccount(p, mem_ctx, &acct_handle)) { + return False; + } + return True; } @@ -407,7 +445,7 @@ static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, NTSTATUS status; int i; uint32 resume_handle = 0; - struct lsa_RefDomainList domains; + struct lsa_DomainList domains; printf("\nTesting EnumTrustDom\n"); @@ -423,9 +461,7 @@ static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, return False; } - printf("lookup gave %d domains (max_count=%d)\n", - domains.count, - domains.max_count); + printf("lookup gave %d domains\n", domains.count); for (i=0;i<r.out.domains->count;i++) { printf("name='%s' sid=%s\n", domains.domains[i].name.name, |