summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/idl/lsa.idl31
-rw-r--r--source4/librpc/ndr/ndr_lsa.c88
-rw-r--r--source4/librpc/ndr/ndr_lsa.h22
-rw-r--r--source4/librpc/rpc/rpc_lsa.c8
-rw-r--r--source4/torture/rpc/lsa.c46
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,