summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/dsdb/common/util.c33
-rw-r--r--source4/libcli/util/nterr.c1
-rw-r--r--source4/libnet/groupinfo.c18
-rw-r--r--source4/libnet/groupman.c10
-rw-r--r--source4/libnet/libnet_domain.c21
-rw-r--r--source4/libnet/libnet_group.c16
-rw-r--r--source4/libnet/libnet_join.c25
-rw-r--r--source4/libnet/libnet_passwd.c17
-rw-r--r--source4/libnet/libnet_samsync_ldb.c6
-rw-r--r--source4/libnet/libnet_user.c16
-rw-r--r--source4/libnet/userinfo.c16
-rw-r--r--source4/libnet/userman.c33
-rw-r--r--source4/librpc/idl/samr.idl1424
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c361
-rw-r--r--source4/rpc_server/samr/samr_password.c11
-rw-r--r--source4/torture/libnet/libnet_domain.c6
-rw-r--r--source4/torture/libnet/libnet_group.c9
-rw-r--r--source4/torture/libnet/libnet_user.c9
-rw-r--r--source4/torture/libnet/utils.c18
-rw-r--r--source4/torture/rpc/samba3rpc.c53
-rw-r--r--source4/torture/rpc/samr.c527
-rw-r--r--source4/torture/rpc/samr_accessmask.c29
-rw-r--r--source4/torture/rpc/samsync.c149
-rw-r--r--source4/torture/rpc/schannel.c2
-rw-r--r--source4/torture/rpc/testjoin.c17
-rw-r--r--source4/winbind/wb_async_helpers.c7
26 files changed, 912 insertions, 1922 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 69e456274c..2161286e08 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -657,6 +657,28 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
return acct_flags;
}
+struct lsa_BinaryString samdb_result_parameters(TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg,
+ const char *attr)
+{
+ struct lsa_BinaryString s;
+ const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
+
+ ZERO_STRUCT(s);
+
+ if (!val) {
+ return s;
+ }
+
+ s.array = talloc_array(mem_ctx, uint16_t, val->length/2);
+ if (!s.array) {
+ return s;
+ }
+ s.length = s.size = val->length/2;
+ memcpy(s.array, val->data, val->length);
+
+ return s;
+}
/* Find an attribute, with a particular value */
@@ -897,6 +919,17 @@ int samdb_msg_add_logon_hours(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
}
/*
+ add a parameters element to a message
+*/
+int samdb_msg_add_parameters(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+ const char *attr_name, struct lsa_BinaryString *parameters)
+{
+ struct ldb_val val;
+ val.length = parameters->length * 2;
+ val.data = (uint8_t *)parameters->array;
+ return ldb_msg_add_value(msg, attr_name, &val, NULL);
+}
+/*
add a general value element to a message
*/
int samdb_msg_add_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c
index e95f0228c1..e94ed36d39 100644
--- a/source4/libcli/util/nterr.c
+++ b/source4/libcli/util/nterr.c
@@ -548,6 +548,7 @@ static const nt_err_code_struct nt_errs[] =
{ "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED },
{ "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND },
{ "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED },
+ { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY },
{ "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
{ "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
{ "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP },
diff --git a/source4/libnet/groupinfo.c b/source4/libnet/groupinfo.c
index 1da6646702..5c94c34b1d 100644
--- a/source4/libnet/groupinfo.c
+++ b/source4/libnet/groupinfo.c
@@ -83,8 +83,8 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
if (s->monitor_fn) {
msg.type = mon_SamrLookupName;
msg_lookup = talloc(s, struct msg_rpc_lookup_name);
- msg_lookup->rid = s->lookup.out.rids.ids;
- msg_lookup->count = s->lookup.out.rids.count;
+ msg_lookup->rid = s->lookup.out.rids->ids;
+ msg_lookup->count = s->lookup.out.rids->count;
msg.data = (void*)msg_lookup;
msg.data_size = sizeof(*msg_lookup);
@@ -94,7 +94,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
/* have we actually got name resolved
- we're looking for only one at the moment */
- if (s->lookup.out.rids.count == 0) {
+ if (s->lookup.out.rids->count == 0) {
composite_error(c, NT_STATUS_NO_SUCH_USER);
}
@@ -103,7 +103,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
/* prepare parameters for LookupNames */
s->opengroup.in.domain_handle = &s->domain_handle;
s->opengroup.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- s->opengroup.in.rid = s->lookup.out.rids.ids[0];
+ s->opengroup.in.rid = s->lookup.out.rids->ids[0];
s->opengroup.out.group_handle = &s->group_handle;
/* send request */
@@ -152,6 +152,8 @@ static void continue_groupinfo_opengroup(struct rpc_request *req)
/* prepare parameters for QueryGroupInfo call */
s->querygroupinfo.in.group_handle = &s->group_handle;
s->querygroupinfo.in.level = s->level;
+ s->querygroupinfo.out.info = talloc(s, union samr_GroupInfo *);
+ if (composite_nomem(s->querygroupinfo.out.info, c)) return;
/* queue rpc call, set event handling and new state */
querygroup_req = dcerpc_samr_QueryGroupInfo_send(s->pipe, c, &s->querygroupinfo);
@@ -185,7 +187,7 @@ static void continue_groupinfo_getgroup(struct rpc_request *req)
return;
}
- s->info = talloc_steal(s, s->querygroupinfo.out.info);
+ s->info = talloc_steal(s, *s->querygroupinfo.out.info);
/* issue a monitor message */
if (s->monitor_fn) {
@@ -301,7 +303,11 @@ struct composite_context *libnet_rpc_groupinfo_send(struct dcerpc_pipe *p,
s->lookup.in.names[0].string = talloc_strdup(s, io->in.groupname);
if (composite_nomem(s->lookup.in.names[0].string, c)) return c;
-
+ s->lookup.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookup.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookup.out.rids, c)) return c;
+ if (composite_nomem(s->lookup.out.types, c)) return c;
+
/* send request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookup);
if (composite_nomem(lookup_req, c)) return c;
diff --git a/source4/libnet/groupman.c b/source4/libnet/groupman.c
index 58d5742336..4dfb2d8aab 100644
--- a/source4/libnet/groupman.c
+++ b/source4/libnet/groupman.c
@@ -174,6 +174,10 @@ struct composite_context* libnet_rpc_groupdel_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.groupname;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
@@ -205,12 +209,12 @@ static void continue_groupdel_name_found(struct rpc_request *req)
/* what to do when there's no group account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_GROUP;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -218,7 +222,7 @@ static void continue_groupdel_name_found(struct rpc_request *req)
/* prepare the arguments for rpc call */
s->opengroup.in.domain_handle = &s->domain_handle;
- s->opengroup.in.rid = s->lookupname.out.rids.ids[0];
+ s->opengroup.in.rid = s->lookupname.out.rids->ids[0];
s->opengroup.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->opengroup.out.group_handle = &s->group_handle;
diff --git a/source4/libnet/libnet_domain.c b/source4/libnet/libnet_domain.c
index ccdfdaf134..eb6920d88e 100644
--- a/source4/libnet/libnet_domain.c
+++ b/source4/libnet/libnet_domain.c
@@ -40,6 +40,7 @@ struct domain_open_samr_state {
uint32_t access_mask;
struct policy_handle connect_handle;
struct policy_handle domain_handle;
+ struct dom_sid2 *domain_sid;
/* information about the progress */
void (*monitor_fn)(struct monitor_msg*);
@@ -159,6 +160,8 @@ static void continue_domain_open_connect(struct rpc_request *req)
/* prepare for samr_LookupDomain call */
r->in.connect_handle = &s->connect_handle;
r->in.domain_name = &s->domain_name;
+ r->out.sid = talloc(s, struct dom_sid2 *);
+ if (composite_nomem(r->out.sid, c)) return;
lookup_req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
if (composite_nomem(lookup_req, c)) return;
@@ -209,7 +212,7 @@ static void continue_domain_open_lookup(struct rpc_request *req)
/* prepare for samr_OpenDomain call */
r->in.connect_handle = &s->connect_handle;
r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r->in.sid = s->lookup.out.sid;
+ r->in.sid = *s->lookup.out.sid;
r->out.domain_handle = &s->domain_handle;
opendom_req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
@@ -361,7 +364,7 @@ NTSTATUS libnet_DomainOpenSamr_recv(struct composite_context *c, struct libnet_c
libnet functions */
ctx->samr.connect_handle = s->connect_handle;
ctx->samr.handle = s->domain_handle;
- ctx->samr.sid = talloc_steal(ctx, s->lookup.out.sid);
+ ctx->samr.sid = talloc_steal(ctx, *s->lookup.out.sid);
ctx->samr.name = talloc_steal(ctx, s->domain_name.string);
ctx->samr.access_mask = s->access_mask;
}
@@ -998,6 +1001,10 @@ static void continue_samr_connect(struct rpc_request *req)
s->enumdom.in.resume_handle = &s->resume_handle;
s->enumdom.in.buf_size = s->buf_size;
s->enumdom.out.resume_handle = &s->resume_handle;
+ s->enumdom.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->enumdom.out.num_entries, c)) return;
+ s->enumdom.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->enumdom.out.sam, c)) return;
enumdom_req = dcerpc_samr_EnumDomains_send(s->ctx->samr.pipe, c, &s->enumdom);
if (composite_nomem(enumdom_req, c)) return;
@@ -1113,16 +1120,16 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis
/* prepare domains array */
if (s->domains == NULL) {
s->domains = talloc_array(mem_ctx, struct domainlist,
- s->enumdom.out.num_entries);
+ *s->enumdom.out.num_entries);
} else {
s->domains = talloc_realloc(mem_ctx, s->domains, struct domainlist,
- s->count + s->enumdom.out.num_entries);
+ s->count + *s->enumdom.out.num_entries);
}
/* copy domain names returned from samr_EnumDomains call */
- for (i = s->count; i < s->count + s->enumdom.out.num_entries; i++)
+ for (i = s->count; i < s->count + *s->enumdom.out.num_entries; i++)
{
- struct lsa_String *domain_name = &s->enumdom.out.sam->entries[i - s->count].name;
+ struct lsa_String *domain_name = &(*s->enumdom.out.sam)->entries[i - s->count].name;
/* strdup name as a child of allocated array to make it follow the array
in case of talloc_steal or talloc_free */
@@ -1131,7 +1138,7 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis
}
/* number of entries returned (domains enumerated) */
- s->count += s->enumdom.out.num_entries;
+ s->count += *s->enumdom.out.num_entries;
return s->domains;
}
diff --git a/source4/libnet/libnet_group.c b/source4/libnet/libnet_group.c
index eded378511..af5fe4d5d3 100644
--- a/source4/libnet/libnet_group.c
+++ b/source4/libnet/libnet_group.c
@@ -518,6 +518,10 @@ static void continue_domain_queried(struct rpc_request *req)
s->group_list.in.max_size = s->page_size;
s->group_list.in.resume_handle = &s->resume_index;
s->group_list.out.resume_handle = &s->resume_index;
+ s->group_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->group_list.out.num_entries, c)) return;
+ s->group_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->group_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list);
@@ -549,6 +553,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx)
s->group_list.in.max_size = s->page_size;
s->group_list.in.resume_handle = &s->resume_index;
s->group_list.out.resume_handle = &s->resume_index;
+ s->group_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->group_list.out.num_entries, c)) return;
+ s->group_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->group_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list);
@@ -587,15 +595,15 @@ static void continue_groups_enumerated(struct rpc_request *req)
/* get enumerated accounts counter and resume handle (the latter allows
making subsequent call to continue enumeration) */
s->resume_index = *s->group_list.out.resume_handle;
- s->count = s->group_list.out.num_entries;
+ s->count = *s->group_list.out.num_entries;
/* prepare returned group accounts array */
- s->groups = talloc_array(c, struct grouplist, s->group_list.out.sam->count);
+ s->groups = talloc_array(c, struct grouplist, (*s->group_list.out.sam)->count);
if (composite_nomem(s->groups, c)) return;
- for (i = 0; i < s->group_list.out.sam->count; i++) {
+ for (i = 0; i < (*s->group_list.out.sam)->count; i++) {
struct dom_sid *group_sid;
- struct samr_SamEntry *entry = &s->group_list.out.sam->entries[i];
+ struct samr_SamEntry *entry = &(*s->group_list.out.sam)->entries[i];
struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid;
/* construct group sid from returned rid and queried domain sid */
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 0ed5e8ae26..70fcb4a894 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -444,13 +444,16 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
struct samr_OpenDomain od;
struct policy_handle d_handle;
struct samr_LookupNames ln;
+ struct samr_Ids rids, types;
struct samr_OpenUser ou;
struct samr_CreateUser2 cu;
struct policy_handle *u_handle = NULL;
struct samr_QueryUserInfo qui;
+ union samr_UserInfo *uinfo;
struct samr_UserInfo21 u_info21;
union libnet_SetPassword r2;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
struct lsa_String samr_account_name;
uint32_t acct_flags, old_acct_flags;
@@ -559,9 +562,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
if (!connect_with_info->out.domain_sid) {
struct lsa_String name;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
name.string = connect_with_info->out.domain_name;
l.in.connect_handle = &p_handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(samr_pipe, tmp_ctx, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -571,7 +576,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
talloc_free(tmp_ctx);
return status;
}
- connect_with_info->out.domain_sid = l.out.sid;
+ connect_with_info->out.domain_sid = *l.out.sid;
}
/* prepare samr_OpenDomain */
@@ -611,6 +616,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
ln.in.domain_handle = &d_handle;
ln.in.num_names = 1;
ln.in.names = talloc_array(tmp_ctx, struct lsa_String, 1);
+ ln.out.rids = &rids;
+ ln.out.types = &types;
if (!ln.in.names) {
r->out.error_string = NULL;
talloc_free(tmp_ctx);
@@ -630,10 +637,10 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
}
/* check if we got one RID for the user */
- if (ln.out.rids.count != 1) {
+ if (ln.out.rids->count != 1) {
r->out.error_string = talloc_asprintf(mem_ctx,
"samr_LookupNames for [%s] returns %d RIDs",
- r->in.account_name, ln.out.rids.count);
+ r->in.account_name, ln.out.rids->count);
talloc_free(tmp_ctx);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -642,7 +649,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
ZERO_STRUCTP(u_handle);
ou.in.domain_handle = &d_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- ou.in.rid = ln.out.rids.ids[0];
+ ou.in.rid = ln.out.rids->ids[0];
rid = ou.in.rid;
ou.out.user_handle = u_handle;
@@ -694,6 +701,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
/* prepare samr_QueryUserInfo (get flags) */
qui.in.user_handle = u_handle;
qui.in.level = 16;
+ qui.out.info = &uinfo;
status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
if (!NT_STATUS_IS_OK(status)) {
@@ -705,7 +713,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
- if (!qui.out.info) {
+ if (!uinfo) {
status = NT_STATUS_INVALID_PARAMETER;
r->out.error_string
= talloc_asprintf(mem_ctx,
@@ -715,7 +723,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
- old_acct_flags = (qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
+ old_acct_flags = (uinfo->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
/* Possibly bail if the account is of the wrong type */
if (old_acct_flags
!= r->in.acct_type) {
@@ -771,17 +779,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return NT_STATUS_USER_EXISTS;
}
} else {
- acct_flags = qui.out.info->info16.acct_flags;
+ acct_flags = uinfo->info16.acct_flags;
}
acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ));
/* Find out what password policy this user has */
pwp.in.user_handle = u_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
/* Grab a password of that minimum length */
diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c
index de2ed01abd..976606e72c 100644
--- a/source4/libnet/libnet_passwd.c
+++ b/source4/libnet/libnet_passwd.c
@@ -50,6 +50,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
struct samr_Password nt_verifier, lm_verifier;
uint8_t old_nt_hash[16], new_nt_hash[16];
uint8_t old_lm_hash[16], new_lm_hash[16];
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
/* prepare connect to the SAMR pipe of the users domain PDC */
c.level = LIBNET_RPC_CONNECT_PDC;
@@ -92,6 +94,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
pw3.in.lm_password = &lm_pass;
pw3.in.lm_verifier = &lm_verifier;
pw3.in.password3 = NULL;
+ pw3.out.dominfo = &dominfo;
+ pw3.out.reject = &reject;
/* 2. try samr_ChangePasswordUser3 */
status = dcerpc_samr_ChangePasswordUser3(c.out.dcerpc_pipe, mem_ctx, &pw3);
@@ -527,10 +531,12 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
struct samr_Connect sc;
struct policy_handle p_handle;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct lsa_String d_name;
struct samr_OpenDomain od;
struct policy_handle d_handle;
struct samr_LookupNames ln;
+ struct samr_Ids rids, types;
struct samr_OpenUser ou;
struct policy_handle u_handle;
union libnet_SetPassword r2;
@@ -568,6 +574,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
d_name.string = r->samr.in.domain_name;
ld.in.connect_handle = &p_handle;
ld.in.domain_name = &d_name;
+ ld.out.sid = &sid;
/* 3. do a samr_LookupDomain to get the domain sid */
status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld);
@@ -582,7 +589,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ZERO_STRUCT(d_handle);
od.in.connect_handle = &p_handle;
od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- od.in.sid = ld.out.sid;
+ od.in.sid = *ld.out.sid;
od.out.domain_handle = &d_handle;
/* 4. do a samr_OpenDomain to get a domain handle */
@@ -598,6 +605,8 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ln.in.domain_handle = &d_handle;
ln.in.num_names = 1;
ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
+ ln.out.rids = &rids;
+ ln.out.types = &types;
if (!ln.in.names) {
r->samr.out.error_string = "Out of Memory";
return NT_STATUS_NO_MEMORY;
@@ -614,10 +623,10 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
}
/* check if we got one RID for the user */
- if (ln.out.rids.count != 1) {
+ if (ln.out.rids->count != 1) {
r->samr.out.error_string = talloc_asprintf(mem_ctx,
"samr_LookupNames for [%s] returns %d RIDs",
- r->samr.in.account_name, ln.out.rids.count);
+ r->samr.in.account_name, ln.out.rids->count);
status = NT_STATUS_INVALID_PARAMETER;
goto disconnect;
}
@@ -626,7 +635,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ZERO_STRUCT(u_handle);
ou.in.domain_handle = &d_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- ou.in.rid = ln.out.rids.ids[0];
+ ou.in.rid = ln.out.rids->ids[0];
ou.out.user_handle = &u_handle;
/* 6. do a samr_OpenUser to get a user handle */
diff --git a/source4/libnet/libnet_samsync_ldb.c b/source4/libnet/libnet_samsync_ldb.c
index 8b7dd1f598..160b4b3e19 100644
--- a/source4/libnet/libnet_samsync_ldb.c
+++ b/source4/libnet/libnet_samsync_ldb.c
@@ -384,7 +384,11 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
}
ADD_OR_DEL(string, "comment", comment.string);
- ADD_OR_DEL(string, "userParameters", parameters.string);
+
+ if (samdb_msg_add_parameters(state->sam_ldb, mem_ctx, msg, "userParameters", &user->parameters) != 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
ADD_OR_DEL(uint, "countryCode", country_code);
ADD_OR_DEL(uint, "codePage", code_page);
diff --git a/source4/libnet/libnet_user.c b/source4/libnet/libnet_user.c
index c768319452..8606d0856e 100644
--- a/source4/libnet/libnet_user.c
+++ b/source4/libnet/libnet_user.c
@@ -1032,6 +1032,10 @@ static void continue_domain_queried(struct rpc_request *req)
s->user_list.in.resume_handle = &s->resume_index;
s->user_list.in.acct_flags = ACB_NORMAL;
s->user_list.out.resume_handle = &s->resume_index;
+ s->user_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->user_list.out.num_entries, c)) return;
+ s->user_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->user_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);
@@ -1064,6 +1068,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx)
s->user_list.in.resume_handle = &s->resume_index;
s->user_list.in.acct_flags = ACB_NORMAL;
s->user_list.out.resume_handle = &s->resume_index;
+ s->user_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->user_list.out.sam, c)) return;
+ s->user_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->user_list.out.num_entries, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);
@@ -1102,15 +1110,15 @@ static void continue_users_enumerated(struct rpc_request *req)
/* get enumerated accounts counter and resume handle (the latter allows
making subsequent call to continue enumeration) */
s->resume_index = *s->user_list.out.resume_handle;
- s->count = s->user_list.out.num_entries;
+ s->count = *s->user_list.out.num_entries;
/* prepare returned user accounts array */
- s->users = talloc_array(c, struct userlist, s->user_list.out.sam->count);
+ s->users = talloc_array(c, struct userlist, (*s->user_list.out.sam)->count);
if (composite_nomem(s->users, c)) return;
- for (i = 0; i < s->user_list.out.sam->count; i++) {
+ for (i = 0; i < (*s->user_list.out.sam)->count; i++) {
struct dom_sid *user_sid;
- struct samr_SamEntry *entry = &s->user_list.out.sam->entries[i];
+ struct samr_SamEntry *entry = &(*s->user_list.out.sam)->entries[i];
struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid;
/* construct user sid from returned rid and queried domain sid */
diff --git a/source4/libnet/userinfo.c b/source4/libnet/userinfo.c
index e8b6b090c7..710154d41e 100644
--- a/source4/libnet/userinfo.c
+++ b/source4/libnet/userinfo.c
@@ -82,8 +82,8 @@ static void continue_userinfo_lookup(struct rpc_request *req)
if (s->monitor_fn) {
msg.type = mon_SamrLookupName;
msg_lookup = talloc(s, struct msg_rpc_lookup_name);
- msg_lookup->rid = s->lookup.out.rids.ids;
- msg_lookup->count = s->lookup.out.rids.count;
+ msg_lookup->rid = s->lookup.out.rids->ids;
+ msg_lookup->count = s->lookup.out.rids->count;
msg.data = (void*)msg_lookup;
msg.data_size = sizeof(*msg_lookup);
@@ -93,7 +93,7 @@ static void continue_userinfo_lookup(struct rpc_request *req)
/* have we actually got name resolved
- we're looking for only one at the moment */
- if (s->lookup.out.rids.count == 0) {
+ if (s->lookup.out.rids->count == 0) {
composite_error(c, NT_STATUS_NO_SUCH_USER);
}
@@ -102,7 +102,7 @@ static void continue_userinfo_lookup(struct rpc_request *req)
/* prepare parameters for LookupNames */
s->openuser.in.domain_handle = &s->domain_handle;
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- s->openuser.in.rid = s->lookup.out.rids.ids[0];
+ s->openuser.in.rid = s->lookup.out.rids->ids[0];
s->openuser.out.user_handle = &s->user_handle;
/* send request */
@@ -151,6 +151,8 @@ static void continue_userinfo_openuser(struct rpc_request *req)
/* prepare parameters for QueryUserInfo call */
s->queryuserinfo.in.user_handle = &s->user_handle;
s->queryuserinfo.in.level = s->level;
+ s->queryuserinfo.out.info = talloc(s, union samr_UserInfo *);
+ if (composite_nomem(s->queryuserinfo.out.info, c)) return;
/* queue rpc call, set event handling and new state */
queryuser_req = dcerpc_samr_QueryUserInfo_send(s->pipe, c, &s->queryuserinfo);
@@ -184,7 +186,7 @@ static void continue_userinfo_getuser(struct rpc_request *req)
return;
}
- s->info = talloc_steal(s, s->queryuserinfo.out.info);
+ s->info = talloc_steal(s, *(s->queryuserinfo.out.info));
/* issue a monitor message */
if (s->monitor_fn) {
@@ -297,6 +299,10 @@ struct composite_context *libnet_rpc_userinfo_send(struct dcerpc_pipe *p,
s->lookup.in.num_names = 1;
s->lookup.in.names = talloc_array(s, struct lsa_String, 1);
if (composite_nomem(s->lookup.in.names, c)) return c;
+ s->lookup.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookup.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookup.out.rids, c)) return c;
+ if (composite_nomem(s->lookup.out.types, c)) return c;
s->lookup.in.names[0].string = talloc_strdup(s, io->in.username);
if (composite_nomem(s->lookup.in.names[0].string, c)) return c;
diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c
index 398d9f2cb0..c638d8af32 100644
--- a/source4/libnet/userman.c
+++ b/source4/libnet/userman.c
@@ -236,12 +236,12 @@ static void continue_userdel_name_found(struct rpc_request *req)
/* what to do when there's no user account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_USER;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -251,8 +251,8 @@ static void continue_userdel_name_found(struct rpc_request *req)
if (s->monitor_fn) {
struct msg_rpc_lookup_name msg_lookup;
- msg_lookup.rid = s->lookupname.out.rids.ids;
- msg_lookup.count = s->lookupname.out.rids.count;
+ msg_lookup.rid = s->lookupname.out.rids->ids;
+ msg_lookup.count = s->lookupname.out.rids->count;
msg.type = mon_SamrLookupName;
msg.data = (void*)&msg_lookup;
@@ -262,7 +262,7 @@ static void continue_userdel_name_found(struct rpc_request *req)
/* prepare the arguments for rpc call */
s->openuser.in.domain_handle = &s->domain_handle;
- s->openuser.in.rid = s->lookupname.out.rids.ids[0];
+ s->openuser.in.rid = s->lookupname.out.rids->ids[0];
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->openuser.out.user_handle = &s->user_handle;
@@ -393,6 +393,10 @@ struct composite_context *libnet_rpc_userdel_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.username;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
@@ -500,12 +504,12 @@ static void continue_usermod_name_found(struct rpc_request *req)
/* what to do when there's no user account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_USER;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -515,8 +519,8 @@ static void continue_usermod_name_found(struct rpc_request *req)
if (s->monitor_fn) {
struct msg_rpc_lookup_name msg_lookup;
- msg_lookup.rid = s->lookupname.out.rids.ids;
- msg_lookup.count = s->lookupname.out.rids.count;
+ msg_lookup.rid = s->lookupname.out.rids->ids;
+ msg_lookup.count = s->lookupname.out.rids->count;
msg.type = mon_SamrLookupName;
msg.data = (void*)&msg_lookup;
@@ -526,7 +530,7 @@ static void continue_usermod_name_found(struct rpc_request *req)
/* prepare the next rpc call */
s->openuser.in.domain_handle = &s->domain_handle;
- s->openuser.in.rid = s->lookupname.out.rids.ids[0];
+ s->openuser.in.rid = s->lookupname.out.rids->ids[0];
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->openuser.out.user_handle = &s->user_handle;
@@ -679,6 +683,9 @@ static NTSTATUS usermod_change(struct composite_context *c,
if (!do_set) {
s->queryuser.in.user_handle = &s->user_handle;
s->queryuser.in.level = level;
+ s->queryuser.out.info = talloc(s, union samr_UserInfo *);
+ if (composite_nomem(s->queryuser.out.info, c)) return;
+
/* send query user info request to retrieve complete data of
a particular info level */
@@ -751,7 +758,7 @@ static void continue_usermod_user_queried(struct rpc_request *req)
/* get returned user data and make a change (potentially one
of many) */
- s->info = *s->queryuser.out.info;
+ s->info = *(*s->queryuser.out.info);
usermod_setfields(s, &level, i, true);
@@ -834,6 +841,10 @@ struct composite_context *libnet_rpc_usermod_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.username;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the rpc request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl
deleted file mode 100644
index 47882dfb84..0000000000
--- a/source4/librpc/idl/samr.idl
+++ /dev/null
@@ -1,1424 +0,0 @@
-#include "idl_types.h"
-
-/*
- samr interface definition
-*/
-import "misc.idl", "lsa.idl", "security.idl";
-
-/*
- Thanks to Todd Sabin for some information from his samr.idl in acltools
-*/
-
-[ uuid("12345778-1234-abcd-ef00-0123456789ac"),
- version(1.0),
- endpoint("ncacn_np:[\\pipe\\samr]","ncacn_ip_tcp:", "ncalrpc:"),
- pointer_default(unique)
-] interface samr
-{
- typedef bitmap security_secinfo security_secinfo;
-
- /* account control (acct_flags) bits */
- typedef [public,bitmap32bit] bitmap {
- ACB_DISABLED = 0x00000001, /* 1 = User account disabled */
- ACB_HOMDIRREQ = 0x00000002, /* 1 = Home directory required */
- ACB_PWNOTREQ = 0x00000004, /* 1 = User password not required */
- ACB_TEMPDUP = 0x00000008, /* 1 = Temporary duplicate account */
- ACB_NORMAL = 0x00000010, /* 1 = Normal user account */
- ACB_MNS = 0x00000020, /* 1 = MNS logon user account */
- ACB_DOMTRUST = 0x00000040, /* 1 = Interdomain trust account */
- ACB_WSTRUST = 0x00000080, /* 1 = Workstation trust account */
- ACB_SVRTRUST = 0x00000100, /* 1 = Server trust account */
- ACB_PWNOEXP = 0x00000200, /* 1 = User password does not expire */
- ACB_AUTOLOCK = 0x00000400, /* 1 = Account auto locked */
- ACB_ENC_TXT_PWD_ALLOWED = 0x00000800, /* 1 = Encryped text password is allowed */
- ACB_SMARTCARD_REQUIRED = 0x00001000, /* 1 = Smart Card required */
- ACB_TRUSTED_FOR_DELEGATION = 0x00002000, /* 1 = Trusted for Delegation */
- ACB_NOT_DELEGATED = 0x00004000, /* 1 = Not delegated */
- ACB_USE_DES_KEY_ONLY = 0x00008000, /* 1 = Use DES key only */
- ACB_DONT_REQUIRE_PREAUTH = 0x00010000, /* 1 = Preauth not required */
- ACB_PW_EXPIRED = 0x00020000, /* 1 = Password Expired */
- ACB_NO_AUTH_DATA_REQD = 0x00080000 /* 1 = No authorization data required */
- } samr_AcctFlags;
-
- typedef [bitmap32bit] bitmap {
- SAMR_ACCESS_CONNECT_TO_SERVER = 0x00000001,
- SAMR_ACCESS_SHUTDOWN_SERVER = 0x00000002,
- SAMR_ACCESS_INITIALIZE_SERVER = 0x00000004,
- SAMR_ACCESS_CREATE_DOMAIN = 0x00000008,
- SAMR_ACCESS_ENUM_DOMAINS = 0x00000010,
- SAMR_ACCESS_OPEN_DOMAIN = 0x00000020
- } samr_ConnectAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_USER_ACCESS_GET_NAME_ETC = 0x00000001,
- SAMR_USER_ACCESS_GET_LOCALE = 0x00000002,
- SAMR_USER_ACCESS_SET_LOC_COM = 0x00000004,
- SAMR_USER_ACCESS_GET_LOGONINFO = 0x00000008,
- SAMR_USER_ACCESS_GET_ATTRIBUTES = 0x00000010,
- SAMR_USER_ACCESS_SET_ATTRIBUTES = 0x00000020,
- SAMR_USER_ACCESS_CHANGE_PASSWORD = 0x00000040,
- SAMR_USER_ACCESS_SET_PASSWORD = 0x00000080,
- SAMR_USER_ACCESS_GET_GROUPS = 0x00000100,
- SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP = 0x00000200,
- SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP = 0x00000400
- } samr_UserAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 = 0x00000001,
- SAMR_DOMAIN_ACCESS_SET_INFO_1 = 0x00000002,
- SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 = 0x00000004,
- SAMR_DOMAIN_ACCESS_SET_INFO_2 = 0x00000008,
- SAMR_DOMAIN_ACCESS_CREATE_USER = 0x00000010,
- SAMR_DOMAIN_ACCESS_CREATE_GROUP = 0x00000020,
- SAMR_DOMAIN_ACCESS_CREATE_ALIAS = 0x00000040,
- SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS = 0x00000080,
- SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS = 0x00000100,
- SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT = 0x00000200,
- SAMR_DOMAIN_ACCESS_SET_INFO_3 = 0x00000400
- } samr_DomainAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_GROUP_ACCESS_LOOKUP_INFO = 0x00000001,
- SAMR_GROUP_ACCESS_SET_INFO = 0x00000002,
- SAMR_GROUP_ACCESS_ADD_MEMBER = 0x00000004,
- SAMR_GROUP_ACCESS_REMOVE_MEMBER = 0x00000008,
- SAMR_GROUP_ACCESS_GET_MEMBERS = 0x00000010
- } samr_GroupAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_ALIAS_ACCESS_ADD_MEMBER = 0x00000001,
- SAMR_ALIAS_ACCESS_REMOVE_MEMBER = 0x00000002,
- SAMR_ALIAS_ACCESS_GET_MEMBERS = 0x00000004,
- SAMR_ALIAS_ACCESS_LOOKUP_INFO = 0x00000008,
- SAMR_ALIAS_ACCESS_SET_INFO = 0x00000010
- } samr_AliasAccessMask;
-
- /******************/
- /* Function: 0x00 */
- NTSTATUS samr_Connect (
- /* notice the lack of [string] */
- [in,unique] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
-
- /******************/
- /* Function: 0x01 */
- [public] NTSTATUS samr_Close (
- [in,out,ref] policy_handle *handle
- );
-
- /******************/
- /* Function: 0x02 */
-
- NTSTATUS samr_SetSecurity (
- [in,ref] policy_handle *handle,
- [in] security_secinfo sec_info,
- [in,ref] sec_desc_buf *sdbuf
- );
-
- /******************/
- /* Function: 0x03 */
-
- NTSTATUS samr_QuerySecurity (
- [in,ref] policy_handle *handle,
- [in] security_secinfo sec_info,
- [out,unique] sec_desc_buf *sdbuf
- );
-
- /******************/
- /* Function: 0x04 */
-
- /*
- shutdown the SAM - once you call this the SAM will be dead
- */
- NTSTATUS samr_Shutdown (
- [in,ref] policy_handle *connect_handle
- );
-
- /******************/
- /* Function: 0x05 */
- NTSTATUS samr_LookupDomain (
- [in,ref] policy_handle *connect_handle,
- [in,ref] lsa_String *domain_name,
- [out,unique] dom_sid2 *sid
- );
-
-
- /******************/
- /* Function: 0x06 */
-
- typedef struct {
- uint32 idx;
- lsa_String name;
- } samr_SamEntry;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_SamEntry *entries;
- } samr_SamArray;
-
- NTSTATUS samr_EnumDomains (
- [in,ref] policy_handle *connect_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] uint32 buf_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
-
- /************************/
- /* Function 0x07 */
- [public] NTSTATUS samr_OpenDomain(
- [in,ref] policy_handle *connect_handle,
- [in] samr_DomainAccessMask access_mask,
- [in,ref] dom_sid2 *sid,
- [out,ref] policy_handle *domain_handle
- );
-
- /************************/
- /* Function 0x08 */
- /* server roles */
- typedef [v1_enum] enum {
- SAMR_ROLE_STANDALONE = 0,
- SAMR_ROLE_DOMAIN_MEMBER = 1,
- SAMR_ROLE_DOMAIN_BDC = 2,
- SAMR_ROLE_DOMAIN_PDC = 3
- } samr_Role;
-
- /* password properties flags */
- typedef [public,bitmap32bit] bitmap {
- DOMAIN_PASSWORD_COMPLEX = 0x00000001,
- DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002,
- DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004,
- DOMAIN_PASSWORD_LOCKOUT_ADMINS = 0x00000008,
- DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010,
- DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020
- } samr_PasswordProperties;
-
- typedef struct {
- uint16 min_password_length;
- uint16 password_history_length;
- samr_PasswordProperties password_properties;
- /* yes, these are signed. They are in negative 100ns */
- dlong max_password_age;
- dlong min_password_age;
- } samr_DomInfo1;
-
- typedef struct {
- NTTIME force_logoff_time;
- lsa_String oem_information; /* comment */
- lsa_String domain_name;
- lsa_String primary; /* PDC name if this is a BDC */
- udlong sequence_num;
- uint32 unknown2;
- samr_Role role;
- uint32 unknown3;
- uint32 num_users;
- uint32 num_groups;
- uint32 num_aliases;
- } samr_DomGeneralInformation;
-
- typedef struct {
- NTTIME force_logoff_time;
- } samr_DomInfo3;
-
- typedef struct {
- lsa_String oem_information; /* comment */
- } samr_DomOEMInformation;
-
- typedef struct {
- lsa_String domain_name;
- } samr_DomInfo5;
-
- typedef struct {
- lsa_String primary;
- } samr_DomInfo6;
-
- typedef struct {
- samr_Role role;
- } samr_DomInfo7;
-
- typedef struct {
- hyper sequence_num;
- NTTIME domain_create_time;
- } samr_DomInfo8;
-
- typedef struct {
- uint32 unknown; /* w2k3 returns 1 */
- } samr_DomInfo9;
-
- typedef struct {
- samr_DomGeneralInformation general;
- hyper lockout_duration;
- hyper lockout_window;
- uint16 lockout_threshold;
- } samr_DomGeneralInformation2;
-
- typedef struct {
- hyper lockout_duration;
- hyper lockout_window;
- uint16 lockout_threshold;
- } samr_DomInfo12;
-
- typedef struct {
- hyper sequence_num;
- NTTIME domain_create_time;
- uint32 unknown1;
- uint32 unknown2;
- } samr_DomInfo13;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_DomInfo1 info1;
- [case(2)] samr_DomGeneralInformation general;
- [case(3)] samr_DomInfo3 info3;
- [case(4)] samr_DomOEMInformation oem;
- [case(5)] samr_DomInfo5 info5;
- [case(6)] samr_DomInfo6 info6;
- [case(7)] samr_DomInfo7 info7;
- [case(8)] samr_DomInfo8 info8;
- [case(9)] samr_DomInfo9 info9;
- [case(11)] samr_DomGeneralInformation2 general2;
- [case(12)] samr_DomInfo12 info12;
- [case(13)] samr_DomInfo13 info13;
- } samr_DomainInfo;
-
- NTSTATUS samr_QueryDomainInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [out,switch_is(level),unique] samr_DomainInfo *info
- );
-
- /************************/
- /* Function 0x09 */
- /*
- only levels 1, 3, 4, 6, 7, 9, 12 are valid for this
- call in w2k3
- */
- NTSTATUS samr_SetDomainInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in,switch_is(level),ref] samr_DomainInfo *info
- );
-
-
- /************************/
- /* Function 0x0a */
- NTSTATUS samr_CreateDomainGroup(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *name,
- [in] samr_GroupAccessMask access_mask,
- [out,ref] policy_handle *group_handle,
- [out,ref] uint32 *rid
- );
-
-
- /************************/
- /* Function 0x0b */
- NTSTATUS samr_EnumDomainGroups(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] uint32 max_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x0c */
- NTSTATUS samr_CreateUser(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *account_name,
- [in] samr_UserAccessMask access_mask,
- [out,ref] policy_handle *user_handle,
- [out,ref] uint32 *rid
- );
-
- /************************/
- /* Function 0x0d */
-
-
- /* w2k3 treats max_size as max_users*54 and sets the
- resume_handle as the rid of the last user sent
- */
- const int SAMR_ENUM_USERS_MULTIPLIER = 54;
-
- NTSTATUS samr_EnumDomainUsers(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] samr_AcctFlags acct_flags,
- [in] uint32 max_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x0e */
- NTSTATUS samr_CreateDomAlias(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *alias_name,
- [in] samr_AliasAccessMask access_mask,
- [out,ref] policy_handle *alias_handle,
- [out,ref] uint32 *rid
- );
-
- /************************/
- /* Function 0x0f */
- NTSTATUS samr_EnumDomainAliases(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] samr_AcctFlags acct_flags,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x10 */
-
- typedef struct {
- [range(0,1024)] uint32 count;
- [size_is(count)] uint32 *ids;
- } samr_Ids;
-
- NTSTATUS samr_GetAliasMembership(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_SidArray *sids,
- [out,ref] samr_Ids *rids
- );
-
- /************************/
- /* Function 0x11 */
-
- [public] NTSTATUS samr_LookupNames(
- [in,ref] policy_handle *domain_handle,
- [in,range(0,1000)] uint32 num_names,
- [in,size_is(1000),length_is(num_names)] lsa_String names[],
- [out] samr_Ids rids,
- [out] samr_Ids types
- );
-
-
- /************************/
- /* Function 0x12 */
- NTSTATUS samr_LookupRids(
- [in,ref] policy_handle *domain_handle,
- [in,range(0,1000)] uint32 num_rids,
- [in,size_is(1000),length_is(num_rids)] uint32 rids[],
- [out] lsa_Strings names,
- [out] samr_Ids types
- );
-
- /************************/
- /* Function 0x13 */
- NTSTATUS samr_OpenGroup(
- [in,ref] policy_handle *domain_handle,
- [in] samr_GroupAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *group_handle
- );
-
- /* Group attributes */
- typedef [public,bitmap32bit] bitmap {
- SE_GROUP_MANDATORY = 0x00000001,
- SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002,
- SE_GROUP_ENABLED = 0x00000004,
- SE_GROUP_OWNER = 0x00000008,
- SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010,
- SE_GROUP_RESOURCE = 0x20000000,
- SE_GROUP_LOGON_ID = 0xC0000000
- } samr_GroupAttrs;
-
- /************************/
- /* Function 0x14 */
-
- typedef struct {
- lsa_String name;
- samr_GroupAttrs attributes;
- uint32 num_members;
- lsa_String description;
- } samr_GroupInfoAll;
-
- typedef struct {
- samr_GroupAttrs attributes;
- } samr_GroupInfoAttributes;
-
- typedef struct {
- lsa_String description;
- } samr_GroupInfoDescription;
-
- typedef enum {
- GROUPINFOALL = 1,
- GROUPINFONAME = 2,
- GROUPINFOATTRIBUTES = 3,
- GROUPINFODESCRIPTION = 4,
- GROUPINFOALL2 = 5
- } samr_GroupInfoEnum;
-
- typedef [switch_type(samr_GroupInfoEnum)] union {
- [case(GROUPINFOALL)] samr_GroupInfoAll all;
- [case(GROUPINFONAME)] lsa_String name;
- [case(GROUPINFOATTRIBUTES)] samr_GroupInfoAttributes attributes;
- [case(GROUPINFODESCRIPTION)] lsa_String description;
- [case(GROUPINFOALL2)] samr_GroupInfoAll all2;
- } samr_GroupInfo;
-
- NTSTATUS samr_QueryGroupInfo(
- [in,ref] policy_handle *group_handle,
- [in] samr_GroupInfoEnum level,
- [out,switch_is(level),unique] samr_GroupInfo *info
- );
-
- /************************/
- /* Function 0x15 */
- NTSTATUS samr_SetGroupInfo(
- [in,ref] policy_handle *group_handle,
- [in] samr_GroupInfoEnum level,
- [in,switch_is(level),ref] samr_GroupInfo *info
- );
-
- /************************/
- /* Function 0x16 */
- NTSTATUS samr_AddGroupMember(
- [in,ref] policy_handle *group_handle,
- [in] uint32 rid,
- [in] uint32 flags
- );
-
- /************************/
- /* Function 0x17 */
- NTSTATUS samr_DeleteDomainGroup(
- [in,out,ref] policy_handle *group_handle
- );
-
- /************************/
- /* Function 0x18 */
- NTSTATUS samr_DeleteGroupMember(
- [in,ref] policy_handle *group_handle,
- [in] uint32 rid
- );
-
-
- /************************/
- /* Function 0x19 */
- typedef struct {
- uint32 count;
- [size_is(count)] uint32 *rids;
- [size_is(count)] uint32 *types;
- } samr_RidTypeArray;
-
- NTSTATUS samr_QueryGroupMember(
- [in,ref] policy_handle *group_handle,
- [out,unique] samr_RidTypeArray *rids
- );
-
-
- /************************/
- /* Function 0x1a */
-
- /*
- win2003 seems to accept any data at all for the two integers
- below, and doesn't seem to do anything with them that I can
- see. Weird. I really expected the first integer to be a rid
- and the second to be the attributes for that rid member.
- */
- NTSTATUS samr_SetMemberAttributesOfGroup(
- [in,ref] policy_handle *group_handle,
- [in] uint32 unknown1,
- [in] uint32 unknown2
- );
-
-
- /************************/
- /* Function 0x1b */
- NTSTATUS samr_OpenAlias (
- [in,ref] policy_handle *domain_handle,
- [in] samr_AliasAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *alias_handle
- );
-
-
- /************************/
- /* Function 0x1c */
-
- typedef struct {
- lsa_String name;
- uint32 num_members;
- lsa_String description;
- } samr_AliasInfoAll;
-
- typedef enum {
- ALIASINFOALL = 1,
- ALIASINFONAME = 2,
- ALIASINFODESCRIPTION = 3
- } samr_AliasInfoEnum;
-
- typedef [switch_type(samr_AliasInfoEnum)] union {
- [case(ALIASINFOALL)] samr_AliasInfoAll all;
- [case(ALIASINFONAME)] lsa_String name;
- [case(ALIASINFODESCRIPTION)] lsa_String description;
- } samr_AliasInfo;
-
- NTSTATUS samr_QueryAliasInfo(
- [in,ref] policy_handle *alias_handle,
- [in] samr_AliasInfoEnum level,
- [out,switch_is(level),unique] samr_AliasInfo *info
- );
-
- /************************/
- /* Function 0x1d */
- NTSTATUS samr_SetAliasInfo(
- [in,ref] policy_handle *alias_handle,
- [in] samr_AliasInfoEnum level,
- [in,switch_is(level),ref] samr_AliasInfo *info
- );
-
- /************************/
- /* Function 0x1e */
- NTSTATUS samr_DeleteDomAlias(
- [in,out,ref] policy_handle *alias_handle
- );
-
- /************************/
- /* Function 0x1f */
- NTSTATUS samr_AddAliasMember(
- [in,ref] policy_handle *alias_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x20 */
- NTSTATUS samr_DeleteAliasMember(
- [in,ref] policy_handle *alias_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x21 */
- NTSTATUS samr_GetMembersInAlias(
- [in,ref] policy_handle *alias_handle,
- [out,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x22 */
- [public] NTSTATUS samr_OpenUser(
- [in,ref] policy_handle *domain_handle,
- [in] samr_UserAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *user_handle
- );
-
- /************************/
- /* Function 0x23 */
- NTSTATUS samr_DeleteUser(
- [in,out,ref] policy_handle *user_handle
- );
-
- /************************/
- /* Function 0x24 */
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 primary_gid;
- lsa_String description;
- lsa_String comment;
- } samr_UserInfo1;
-
- typedef struct {
- lsa_String comment;
- lsa_String unknown; /* settable, but doesn't stick. probably obsolete */
- uint16 country_code;
- uint16 code_page;
- } samr_UserInfo2;
-
- /* this is also used in samr and netlogon */
- typedef [public, flag(NDR_PAHEX)] struct {
- uint16 units_per_week;
- [size_is(1260), length_is(units_per_week/8)] uint8 *bits;
- } samr_LogonHours;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 rid;
- uint32 primary_gid;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String workstations;
- NTTIME last_logon;
- NTTIME last_logoff;
- NTTIME last_password_change;
- NTTIME allow_password_change;
- NTTIME force_password_change;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- samr_AcctFlags acct_flags;
- } samr_UserInfo3;
-
- typedef struct {
- samr_LogonHours logon_hours;
- } samr_UserInfo4;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 rid;
- uint32 primary_gid;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String description;
- lsa_String workstations;
- NTTIME last_logon;
- NTTIME last_logoff;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- NTTIME last_password_change;
- NTTIME acct_expiry;
- samr_AcctFlags acct_flags;
- } samr_UserInfo5;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- } samr_UserInfo6;
-
- typedef struct {
- lsa_String account_name;
- } samr_UserInfo7;
-
- typedef struct {
- lsa_String full_name;
- } samr_UserInfo8;
-
- typedef struct {
- uint32 primary_gid;
- } samr_UserInfo9;
-
- typedef struct {
- lsa_String home_directory;
- lsa_String home_drive;
- } samr_UserInfo10;
-
- typedef struct {
- lsa_String logon_script;
- } samr_UserInfo11;
-
- typedef struct {
- lsa_String profile_path;
- } samr_UserInfo12;
-
- typedef struct {
- lsa_String description;
- } samr_UserInfo13;
-
- typedef struct {
- lsa_String workstations;
- } samr_UserInfo14;
-
- typedef struct {
- samr_AcctFlags acct_flags;
- } samr_UserInfo16;
-
- typedef struct {
- NTTIME acct_expiry;
- } samr_UserInfo17;
-
- typedef [public, flag(NDR_PAHEX)] struct {
- uint8 hash[16];
- } samr_Password;
-
- typedef struct {
- samr_Password lm_pwd;
- samr_Password nt_pwd;
- boolean8 lm_pwd_active;
- boolean8 nt_pwd_active;
- } samr_UserInfo18;
-
- typedef struct {
- lsa_String parameters;
- } samr_UserInfo20;
-
- /* this defines the bits used for fields_present in info21 */
- typedef [bitmap32bit] bitmap {
- SAMR_FIELD_ACCOUNT_NAME = 0x00000001,
- SAMR_FIELD_FULL_NAME = 0x00000002,
- SAMR_FIELD_RID = 0x00000004,
- SAMR_FIELD_PRIMARY_GID = 0x00000008,
- SAMR_FIELD_DESCRIPTION = 0x00000010,
- SAMR_FIELD_COMMENT = 0x00000020,
- SAMR_FIELD_HOME_DIRECTORY = 0x00000040,
- SAMR_FIELD_HOME_DRIVE = 0x00000080,
- SAMR_FIELD_LOGON_SCRIPT = 0x00000100,
- SAMR_FIELD_PROFILE_PATH = 0x00000200,
- SAMR_FIELD_WORKSTATIONS = 0x00000400,
- SAMR_FIELD_LAST_LOGON = 0x00000800,
- SAMR_FIELD_LAST_LOGOFF = 0x00001000,
- SAMR_FIELD_LOGON_HOURS = 0x00002000,
- SAMR_FIELD_BAD_PWD_COUNT = 0x00004000,
- SAMR_FIELD_NUM_LOGONS = 0x00008000,
- SAMR_FIELD_ALLOW_PWD_CHANGE = 0x00010000,
- SAMR_FIELD_FORCE_PWD_CHANGE = 0x00020000,
- SAMR_FIELD_LAST_PWD_CHANGE = 0x00040000,
- SAMR_FIELD_ACCT_EXPIRY = 0x00080000,
- SAMR_FIELD_ACCT_FLAGS = 0x00100000,
- SAMR_FIELD_PARAMETERS = 0x00200000,
- SAMR_FIELD_COUNTRY_CODE = 0x00400000,
- SAMR_FIELD_CODE_PAGE = 0x00800000,
- SAMR_FIELD_PASSWORD = 0x01000000, /* either of these */
- SAMR_FIELD_PASSWORD2 = 0x02000000, /* two bits seems to work */
- SAMR_FIELD_PRIVATE_DATA = 0x04000000,
- SAMR_FIELD_EXPIRED_FLAG = 0x08000000,
- SAMR_FIELD_SEC_DESC = 0x10000000,
- SAMR_FIELD_OWF_PWD = 0x20000000
- } samr_FieldsPresent;
-
- /* used for 'password_expired' in samr_UserInfo21 */
- const int PASS_MUST_CHANGE_AT_NEXT_LOGON = 0x01;
- const int PASS_DONT_CHANGE_AT_NEXT_LOGON = 0x00;
-
- typedef struct {
- NTTIME last_logon;
- NTTIME last_logoff;
- NTTIME last_password_change;
- NTTIME acct_expiry;
- NTTIME allow_password_change;
- NTTIME force_password_change;
- lsa_String account_name;
- lsa_String full_name;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String description;
- lsa_String workstations;
- lsa_String comment;
- lsa_String parameters;
- lsa_String unknown1;
- lsa_String unknown2;
- lsa_String unknown3;
- uint32 buf_count;
- [size_is(buf_count)] uint8 *buffer;
- uint32 rid;
- uint32 primary_gid;
- samr_AcctFlags acct_flags;
- samr_FieldsPresent fields_present;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- uint16 country_code;
- uint16 code_page;
- uint8 nt_password_set;
- uint8 lm_password_set;
- uint8 password_expired;
- uint8 unknown4;
- } samr_UserInfo21;
-
- typedef [public, flag(NDR_PAHEX)] struct {
- uint8 data[516];
- } samr_CryptPassword;
-
- typedef struct {
- samr_UserInfo21 info;
- samr_CryptPassword password;
- } samr_UserInfo23;
-
- typedef struct {
- samr_CryptPassword password;
- uint8 pw_len;
- } samr_UserInfo24;
-
- typedef [flag(NDR_PAHEX)] struct {
- uint8 data[532];
- } samr_CryptPasswordEx;
-
- typedef struct {
- samr_UserInfo21 info;
- samr_CryptPasswordEx password;
- } samr_UserInfo25;
-
- typedef struct {
- samr_CryptPasswordEx password;
- uint8 pw_len;
- } samr_UserInfo26;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_UserInfo1 info1;
- [case(2)] samr_UserInfo2 info2;
- [case(3)] samr_UserInfo3 info3;
- [case(4)] samr_UserInfo4 info4;
- [case(5)] samr_UserInfo5 info5;
- [case(6)] samr_UserInfo6 info6;
- [case(7)] samr_UserInfo7 info7;
- [case(8)] samr_UserInfo8 info8;
- [case(9)] samr_UserInfo9 info9;
- [case(10)] samr_UserInfo10 info10;
- [case(11)] samr_UserInfo11 info11;
- [case(12)] samr_UserInfo12 info12;
- [case(13)] samr_UserInfo13 info13;
- [case(14)] samr_UserInfo14 info14;
- [case(16)] samr_UserInfo16 info16;
- [case(17)] samr_UserInfo17 info17;
- [case(18)] samr_UserInfo18 info18;
- [case(20)] samr_UserInfo20 info20;
- [case(21)] samr_UserInfo21 info21;
- [case(23)] samr_UserInfo23 info23;
- [case(24)] samr_UserInfo24 info24;
- [case(25)] samr_UserInfo25 info25;
- [case(26)] samr_UserInfo26 info26;
- } samr_UserInfo;
-
- [public] NTSTATUS samr_QueryUserInfo(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_UserInfo *info
- );
-
-
- /************************/
- /* Function 0x25 */
- [public] NTSTATUS samr_SetUserInfo(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [in,ref,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x26 */
- /*
- this is a password change interface that doesn't give
- the server the plaintext password. Depricated.
- */
- NTSTATUS samr_ChangePasswordUser(
- [in,ref] policy_handle *user_handle,
- [in] boolean8 lm_present,
- [in,unique] samr_Password *old_lm_crypted,
- [in,unique] samr_Password *new_lm_crypted,
- [in] boolean8 nt_present,
- [in,unique] samr_Password *old_nt_crypted,
- [in,unique] samr_Password *new_nt_crypted,
- [in] boolean8 cross1_present,
- [in,unique] samr_Password *nt_cross,
- [in] boolean8 cross2_present,
- [in,unique] samr_Password *lm_cross
- );
-
- /************************/
- /* Function 0x27 */
-
- typedef [public] struct {
- uint32 rid;
- samr_GroupAttrs attributes;
- } samr_RidWithAttribute;
-
- typedef [public] struct {
- uint32 count;
- [size_is(count)] samr_RidWithAttribute *rids;
- } samr_RidWithAttributeArray;
-
- NTSTATUS samr_GetGroupsForUser(
- [in,ref] policy_handle *user_handle,
- [out,unique] samr_RidWithAttributeArray *rids
- );
-
- /************************/
- /* Function 0x28 */
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_AcctFlags acct_flags;
- lsa_String account_name;
- lsa_String description;
- lsa_String full_name;
- } samr_DispEntryGeneral;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryGeneral *entries;
- } samr_DispInfoGeneral;
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_AcctFlags acct_flags;
- lsa_String account_name;
- lsa_String description;
- } samr_DispEntryFull;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryFull *entries;
- } samr_DispInfoFull;
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_GroupAttrs acct_flags;
- lsa_String account_name;
- lsa_String description;
- } samr_DispEntryFullGroup;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryFullGroup *entries;
- } samr_DispInfoFullGroups;
-
- typedef struct {
- uint32 idx;
- lsa_AsciiStringLarge account_name;
- } samr_DispEntryAscii;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryAscii *entries;
- } samr_DispInfoAscii;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_DispInfoGeneral info1;/* users */
- [case(2)] samr_DispInfoFull info2; /* trust accounts? */
- [case(3)] samr_DispInfoFullGroups info3; /* groups */
- [case(4)] samr_DispInfoAscii info4; /* users */
- [case(5)] samr_DispInfoAscii info5; /* groups */
- } samr_DispInfo;
-
- NTSTATUS samr_QueryDisplayInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
-
- /************************/
- /* Function 0x29 */
-
- /*
- this seems to be an alphabetic search function. The returned index
- is the index for samr_QueryDisplayInfo needed to get names occurring
- after the specified name. The supplied name does not need to exist
- in the database (for example you can supply just a first letter for
- searching starting at that letter)
-
- The level corresponds to the samr_QueryDisplayInfo level
- */
- NTSTATUS samr_GetDisplayEnumerationIndex(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] lsa_String name,
- [out] uint32 idx
- );
-
-
-
- /************************/
- /* Function 0x2a */
-
- /*
- w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
- */
- NTSTATUS samr_TestPrivateFunctionsDomain(
- [in,ref] policy_handle *domain_handle
- );
-
-
- /************************/
- /* Function 0x2b */
-
- /*
- w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
- */
- NTSTATUS samr_TestPrivateFunctionsUser(
- [in,ref] policy_handle *user_handle
- );
-
-
- /************************/
- /* Function 0x2c */
-
- typedef struct {
- uint16 min_password_length;
- samr_PasswordProperties password_properties;
- } samr_PwInfo;
-
- [public] NTSTATUS samr_GetUserPwInfo(
- [in,ref] policy_handle *user_handle,
- [out] samr_PwInfo info
- );
-
- /************************/
- /* Function 0x2d */
- NTSTATUS samr_RemoveMemberFromForeignDomain(
- [in,ref] policy_handle *domain_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x2e */
-
- /*
- how is this different from QueryDomainInfo ??
- */
- NTSTATUS samr_QueryDomainInfo2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_DomainInfo *info
- );
-
- /************************/
- /* Function 0x2f */
-
- /*
- how is this different from QueryUserInfo ??
- */
- NTSTATUS samr_QueryUserInfo2(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x30 */
-
- /*
- how is this different from QueryDisplayInfo??
- */
- NTSTATUS samr_QueryDisplayInfo2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
- /************************/
- /* Function 0x31 */
-
- /*
- how is this different from GetDisplayEnumerationIndex ??
- */
- NTSTATUS samr_GetDisplayEnumerationIndex2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] lsa_String name,
- [out] uint32 idx
- );
-
-
- /************************/
- /* Function 0x32 */
- NTSTATUS samr_CreateUser2(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *account_name,
- [in] samr_AcctFlags acct_flags,
- [in] samr_UserAccessMask access_mask,
- [out,ref] policy_handle *user_handle,
- [out,ref] uint32 *access_granted,
- [out,ref] uint32 *rid
- );
-
-
- /************************/
- /* Function 0x33 */
-
- /*
- another duplicate. There must be a reason ....
- */
- NTSTATUS samr_QueryDisplayInfo3(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
- /************************/
- /* Function 0x34 */
- NTSTATUS samr_AddMultipleMembersToAlias(
- [in,ref] policy_handle *alias_handle,
- [in,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x35 */
- NTSTATUS samr_RemoveMultipleMembersFromAlias(
- [in,ref] policy_handle *alias_handle,
- [in,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x36 */
-
- NTSTATUS samr_OemChangePasswordUser2(
- [in,unique] lsa_AsciiString *server,
- [in,ref] lsa_AsciiString *account,
- [in,unique] samr_CryptPassword *password,
- [in,unique] samr_Password *hash
- );
-
- /************************/
- /* Function 0x37 */
- NTSTATUS samr_ChangePasswordUser2(
- [in,unique] lsa_String *server,
- [in,ref] lsa_String *account,
- [in,unique] samr_CryptPassword *nt_password,
- [in,unique] samr_Password *nt_verifier,
- [in] boolean8 lm_change,
- [in,unique] samr_CryptPassword *lm_password,
- [in,unique] samr_Password *lm_verifier
- );
-
- /************************/
- /* Function 0x38 */
- NTSTATUS samr_GetDomPwInfo(
- [in,unique] lsa_String *domain_name,
- [out] samr_PwInfo info
- );
-
- /************************/
- /* Function 0x39 */
- NTSTATUS samr_Connect2(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3a */
- /*
- seems to be an exact alias for samr_SetUserInfo()
- */
- [public] NTSTATUS samr_SetUserInfo2(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [in,ref,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x3b */
- /*
- this one is mysterious. I have a few guesses, but nothing working yet
- */
- NTSTATUS samr_SetBootKeyInformation(
- [in,ref] policy_handle *connect_handle,
- [in] uint32 unknown1,
- [in] uint32 unknown2,
- [in] uint32 unknown3
- );
-
- /************************/
- /* Function 0x3c */
- NTSTATUS samr_GetBootKeyInformation(
- [in,ref] policy_handle *domain_handle,
- [out] uint32 unknown
- );
-
- /************************/
- /* Function 0x3d */
- NTSTATUS samr_Connect3(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- /* this unknown value seems to be completely ignored by w2k3 */
- [in] uint32 unknown,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3e */
-
- typedef enum {
- SAMR_CONNECT_PRE_W2K = 1,
- SAMR_CONNECT_W2K = 2,
- SAMR_CONNECT_AFTER_W2K = 3
- } samr_ConnectVersion;
-
- NTSTATUS samr_Connect4(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectVersion client_version,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3f */
-
- typedef enum samr_RejectReason samr_RejectReason;
-
- typedef struct {
- samr_RejectReason reason;
- uint32 unknown1;
- uint32 unknown2;
- } samr_ChangeReject;
-
- NTSTATUS samr_ChangePasswordUser3(
- [in,unique] lsa_String *server,
- [in,ref] lsa_String *account,
- [in,unique] samr_CryptPassword *nt_password,
- [in,unique] samr_Password *nt_verifier,
- [in] boolean8 lm_change,
- [in,unique] samr_CryptPassword *lm_password,
- [in,unique] samr_Password *lm_verifier,
- [in,unique] samr_CryptPassword *password3,
- [out,unique] samr_DomInfo1 *dominfo,
- [out,unique] samr_ChangeReject *reject
- );
-
- /************************/
- /* Function 0x40 */
-
- typedef struct {
- samr_ConnectVersion client_version; /* w2k3 gives 3 */
- uint32 unknown2; /* w2k3 gives 0 */
- } samr_ConnectInfo1;
-
- typedef union {
- [case(1)] samr_ConnectInfo1 info1;
- } samr_ConnectInfo;
-
- [public] NTSTATUS samr_Connect5(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [in,out] uint32 level,
- [in,out,switch_is(level),ref] samr_ConnectInfo *info,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x41 */
- NTSTATUS samr_RidToSid(
- [in,ref] policy_handle *domain_handle,
- [in] uint32 rid,
- [out,unique] dom_sid2 *sid
- );
-
-
- /************************/
- /* Function 0x42 */
-
- /*
- this should set the DSRM password for the server, which is used
- when booting into Directory Services Recovery Mode on a DC. Win2003
- gives me NT_STATUS_NOT_SUPPORTED
- */
-
- NTSTATUS samr_SetDsrmPassword(
- [in,unique] lsa_String *name,
- [in] uint32 unknown,
- [in,unique] samr_Password *hash
- );
-
-
- /************************/
- /* Function 0x43 */
- /************************/
- typedef [bitmap32bit] bitmap {
- SAMR_VALIDATE_FIELD_PASSWORD_LAST_SET = 0x00000001,
- SAMR_VALIDATE_FIELD_BAD_PASSWORD_TIME = 0x00000002,
- SAMR_VALIDATE_FIELD_LOCKOUT_TIME = 0x00000004,
- SAMR_VALIDATE_FIELD_BAD_PASSWORD_COUNT = 0x00000008,
- SAMR_VALIDATE_FIELD_PASSWORD_HISTORY_LENGTH = 0x00000010,
- SAMR_VALIDATE_FIELD_PASSWORD_HISTORY = 0x00000020
- } samr_ValidateFieldsPresent;
-
- typedef enum {
- NetValidateAuthentication = 1,
- NetValidatePasswordChange= 2,
- NetValidatePasswordReset = 3
- } samr_ValidatePasswordLevel;
-
- /* NetApi maps samr_ValidationStatus errors to WERRORs. Haven't
- * identified the mapping of
- * - NERR_PasswordFilterError
- * - NERR_PasswordExpired and
- * - NERR_PasswordCantChange
- * yet - Guenther
- */
-
- typedef enum {
- SAMR_VALIDATION_STATUS_SUCCESS = 0,
- SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1,
- SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2,
- SAMR_VALIDATION_STATUS_BAD_PASSWORD = 4,
- SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT = 5,
- SAMR_VALIDATION_STATUS_PWD_TOO_SHORT = 6,
- SAMR_VALIDATION_STATUS_PWD_TOO_LONG = 7,
- SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH = 8,
- SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9
- } samr_ValidationStatus;
-
- typedef struct {
- uint32 length;
- [size_is(length)] uint8 *data;
- } samr_ValidationBlob;
-
- typedef struct {
- samr_ValidateFieldsPresent fields_present;
- NTTIME_hyper last_password_change;
- NTTIME_hyper bad_password_time;
- NTTIME_hyper lockout_time;
- uint32 bad_pwd_count;
- uint32 pwd_history_len;
- [size_is(pwd_history_len)] samr_ValidationBlob *pwd_history;
- } samr_ValidatePasswordInfo;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- samr_ValidationStatus status;
- } samr_ValidatePasswordRepCtr;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_ValidatePasswordRepCtr ctr1;
- [case(2)] samr_ValidatePasswordRepCtr ctr2;
- [case(3)] samr_ValidatePasswordRepCtr ctr3;
- } samr_ValidatePasswordRep;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- lsa_StringLarge password;
- lsa_StringLarge account;
- samr_ValidationBlob hash;
- boolean8 pwd_must_change_at_next_logon;
- boolean8 clear_lockout;
- } samr_ValidatePasswordReq3;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- lsa_StringLarge password;
- lsa_StringLarge account;
- samr_ValidationBlob hash;
- boolean8 password_matched;
- } samr_ValidatePasswordReq2;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- boolean8 password_matched;
- } samr_ValidatePasswordReq1;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_ValidatePasswordReq1 req1;
- [case(2)] samr_ValidatePasswordReq2 req2;
- [case(3)] samr_ValidatePasswordReq3 req3;
- } samr_ValidatePasswordReq;
-
- NTSTATUS samr_ValidatePassword(
- [in] samr_ValidatePasswordLevel level,
- [in,switch_is(level)] samr_ValidatePasswordReq req,
- [out,unique,switch_is(level)] samr_ValidatePasswordRep *rep
- );
-}
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index b3118d772d..c093b536da 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -37,26 +37,28 @@
#include "../lib/util/util_ldb.h"
#include "param/param.h"
-/* these query macros make samr_Query[User|Group]Info a bit easier to read */
+/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
#define QUERY_STRING(msg, field, attr) \
- r->out.info->field.string = samdb_result_string(msg, attr, "");
+ info->field.string = samdb_result_string(msg, attr, "");
#define QUERY_UINT(msg, field, attr) \
- r->out.info->field = samdb_result_uint(msg, attr, 0);
+ info->field = samdb_result_uint(msg, attr, 0);
#define QUERY_RID(msg, field, attr) \
- r->out.info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
+ info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
#define QUERY_UINT64(msg, field, attr) \
- r->out.info->field = samdb_result_uint64(msg, attr, 0);
+ info->field = samdb_result_uint64(msg, attr, 0);
#define QUERY_APASSC(msg, field, attr) \
- r->out.info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
- a_state->domain_state->domain_dn, msg, attr);
+ info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
+ a_state->domain_state->domain_dn, msg, attr);
#define QUERY_FPASSC(msg, field, attr) \
- r->out.info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
- a_state->domain_state->domain_dn, msg);
+ info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
+ a_state->domain_state->domain_dn, msg);
#define QUERY_LHOURS(msg, field, attr) \
- r->out.info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
+ info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
#define QUERY_AFLAGS(msg, field, attr) \
- r->out.info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+ info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+#define QUERY_PARAMETERS(msg, field, attr) \
+ info->field = samdb_result_parameters(mem_ctx, msg, attr);
/* these are used to make the Set[User|Group]Info code easier to follow */
@@ -136,6 +138,16 @@
set_el->flags = LDB_FLAG_MOD_REPLACE; \
} while (0)
+#define SET_PARAMETERS(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (samdb_msg_add_parameters(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
+} while (0)
+
+
/*
samr_Connect
@@ -217,7 +229,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA
struct dcesrv_handle *h;
struct sec_desc_buf *sd;
- r->out.sdbuf = NULL;
+ *r->out.sdbuf = NULL;
DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
@@ -228,7 +240,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA
sd->sd = samdb_default_security_descriptor(mem_ctx);
- r->out.sdbuf = sd;
+ *r->out.sdbuf = sd;
return NT_STATUS_OK;
}
@@ -265,7 +277,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
int ret;
struct ldb_dn *partitions_basedn;
- r->out.sid = NULL;
+ *r->out.sid = NULL;
DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
@@ -307,7 +319,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_NO_SUCH_DOMAIN;
}
- r->out.sid = sid;
+ *r->out.sid = sid;
return NT_STATUS_OK;
}
@@ -332,8 +344,8 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
struct ldb_dn *partitions_basedn;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
@@ -389,9 +401,9 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
}
}
- r->out.sam = array;
- r->out.num_entries = i;
- array->count = r->out.num_entries;
+ *r->out.sam = array;
+ *r->out.num_entries = i;
+ array->count = *r->out.num_entries;
return NT_STATUS_OK;
}
@@ -765,18 +777,19 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call,
{
struct dcesrv_handle *h;
struct samr_domain_state *d_state;
+ union samr_DomainInfo *info;
struct ldb_message **dom_msgs;
const char * const *attrs = NULL;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
d_state = h->data;
- r->out.info = talloc(mem_ctx, union samr_DomainInfo);
- if (!r->out.info) {
+ info = talloc(mem_ctx, union samr_DomainInfo);
+ if (!info) {
return NT_STATUS_NO_MEMORY;
}
@@ -881,47 +894,49 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call,
}
}
- ZERO_STRUCTP(r->out.info);
+ *r->out.info = info;
+
+ ZERO_STRUCTP(info);
switch (r->in.level) {
case 1:
return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs,
- &r->out.info->info1);
+ &info->info1);
case 2:
return dcesrv_samr_info_DomGeneralInformation(d_state, mem_ctx, dom_msgs,
- &r->out.info->general);
+ &info->general);
case 3:
return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs,
- &r->out.info->info3);
+ &info->info3);
case 4:
return dcesrv_samr_info_DomOEMInformation(d_state, mem_ctx, dom_msgs,
- &r->out.info->oem);
+ &info->oem);
case 5:
return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs,
- &r->out.info->info5);
+ &info->info5);
case 6:
return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs,
- &r->out.info->info6);
+ &info->info6);
case 7:
return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs,
- &r->out.info->info7);
+ &info->info7);
case 8:
return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs,
- &r->out.info->info8);
+ &info->info8);
case 9:
return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs,
- &r->out.info->info9);
+ &info->info9);
case 11:
return dcesrv_samr_info_DomGeneralInformation2(d_state, mem_ctx, dom_msgs,
- &r->out.info->general2);
+ &info->general2);
case 12:
return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs,
- &r->out.info->info12);
+ &info->info12);
case 13:
return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs,
- &r->out.info->info13);
+ &info->info13);
}
-
+
return NT_STATUS_INVALID_INFO_CLASS;
}
@@ -1135,10 +1150,11 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
int ldb_cnt, count, i, first;
struct samr_SamEntry *entries;
const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1189,20 +1205,22 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
- r->out.num_entries = count - first;
- r->out.num_entries = MIN(r->out.num_entries,
+ *r->out.num_entries = count - first;
+ *r->out.num_entries = MIN(*r->out.num_entries,
1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
- if (r->out.num_entries < count - first) {
- *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+ if (*r->out.num_entries < count - first) {
+ *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1492,10 +1510,11 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
int ret, num_filtered_entries, i, first;
struct samr_SamEntry *entries;
const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1539,24 +1558,26 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
- r->out.num_entries = num_filtered_entries - first;
- r->out.num_entries = MIN(r->out.num_entries,
+ *r->out.num_entries = num_filtered_entries - first;
+ *r->out.num_entries = MIN(*r->out.num_entries,
1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
if (first == num_filtered_entries) {
return NT_STATUS_OK;
}
- if (r->out.num_entries < num_filtered_entries - first) {
- *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+ if (*r->out.num_entries < num_filtered_entries - first) {
+ *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1685,10 +1706,11 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call
int ldb_cnt, count, i, first;
struct samr_SamEntry *entries;
const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1748,20 +1770,22 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call
return NT_STATUS_OK;
}
- r->out.num_entries = count - first;
- r->out.num_entries = MIN(r->out.num_entries, 1000);
+ *r->out.num_entries = count - first;
+ *r->out.num_entries = MIN(*r->out.num_entries, 1000);
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
- if (r->out.num_entries < count - first) {
+ if (*r->out.num_entries < count - first) {
*r->out.resume_handle =
- entries[first+r->out.num_entries-1].idx;
+ entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1859,8 +1883,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
const char * const attrs[] = { "sAMAccountType", "objectSid", NULL };
int count;
- ZERO_STRUCT(r->out.rids);
- ZERO_STRUCT(r->out.types);
+ ZERO_STRUCTP(r->out.rids);
+ ZERO_STRUCTP(r->out.types);
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1870,13 +1894,13 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
return NT_STATUS_OK;
}
- r->out.rids.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
- r->out.types.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
- if (!r->out.rids.ids || !r->out.types.ids) {
+ r->out.rids->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+ r->out.types->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+ if (!r->out.rids->ids || !r->out.types->ids) {
return NT_STATUS_NO_MEMORY;
}
- r->out.rids.count = r->in.num_names;
- r->out.types.count = r->in.num_names;
+ r->out.rids->count = r->in.num_names;
+ r->out.types->count = r->in.num_names;
num_mapped = 0;
@@ -1885,8 +1909,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
struct dom_sid *sid;
uint32_t atype, rtype;
- r->out.rids.ids[i] = 0;
- r->out.types.ids[i] = SID_NAME_UNKNOWN;
+ r->out.rids->ids[i] = 0;
+ r->out.types->ids[i] = SID_NAME_UNKNOWN;
count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs,
"sAMAccountName=%s",
@@ -1915,8 +1939,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
continue;
}
- r->out.rids.ids[i] = sid->sub_auths[sid->num_auths-1];
- r->out.types.ids[i] = rtype;
+ r->out.rids->ids[i] = sid->sub_auths[sid->num_auths-1];
+ r->out.types->ids[i] = rtype;
num_mapped++;
}
@@ -1940,8 +1964,8 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
struct lsa_String *names;
uint32_t *ids;
- ZERO_STRUCT(r->out.names);
- ZERO_STRUCT(r->out.types);
+ ZERO_STRUCTP(r->out.names);
+ ZERO_STRUCTP(r->out.types);
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -2002,11 +2026,11 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
}
}
- r->out.names.names = names;
- r->out.names.count = r->in.num_rids;
+ r->out.names->names = names;
+ r->out.names->count = r->in.num_rids;
- r->out.types.ids = ids;
- r->out.types.count = r->in.num_rids;
+ r->out.types->ids = ids;
+ r->out.types->count = r->in.num_rids;
return status;
}
@@ -2103,8 +2127,9 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
+ union samr_GroupInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
@@ -2127,17 +2152,16 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
msg = res->msgs[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_GroupInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_GroupInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
/* Fill in the level */
switch (r->in.level) {
case GROUPINFOALL:
QUERY_STRING(msg, all.name, "sAMAccountName");
- r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
QUERY_UINT (msg, all.num_members, "numMembers")
QUERY_STRING(msg, all.description, "description");
break;
@@ -2145,22 +2169,24 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
QUERY_STRING(msg, name, "sAMAccountName");
break;
case GROUPINFOATTRIBUTES:
- r->out.info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
break;
case GROUPINFODESCRIPTION:
QUERY_STRING(msg, description, "description");
break;
case GROUPINFOALL2:
QUERY_STRING(msg, all2.name, "sAMAccountName");
- r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
QUERY_UINT (msg, all2.num_members, "numMembers")
QUERY_STRING(msg, all2.description, "description");
break;
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -2467,7 +2493,7 @@ static NTSTATUS dcesrv_samr_QueryGroupMember(struct dcesrv_call_state *dce_call,
}
}
- r->out.rids = array;
+ *r->out.rids = array;
return NT_STATUS_OK;
}
@@ -2574,8 +2600,9 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
+ union samr_AliasInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
@@ -2590,11 +2617,10 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
msg = res[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_AliasInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_AliasInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
switch(r->in.level) {
case ALIASINFOALL:
@@ -2609,10 +2635,12 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
QUERY_STRING(msg, description, "description");
break;
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -2989,8 +3017,9 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
struct ldb_context *sam_ctx;
const char * const *attrs = NULL;
+ union samr_UserInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
@@ -3175,11 +3204,10 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
msg = res[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_UserInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_UserInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
/* fill in the reply */
switch (r->in.level) {
@@ -3290,7 +3318,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
break;
case 20:
- QUERY_STRING(msg, info20.parameters, "userParameters");
+ QUERY_PARAMETERS(msg, info20.parameters, "userParameters");
break;
case 21:
@@ -3309,11 +3337,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
QUERY_STRING(msg, info21.description, "description");
QUERY_STRING(msg, info21.workstations, "userWorkstations");
QUERY_STRING(msg, info21.comment, "comment");
- QUERY_STRING(msg, info21.parameters, "userParameters");
+ QUERY_PARAMETERS(msg, info21.parameters, "userParameters");
QUERY_RID (msg, info21.rid, "objectSid");
QUERY_UINT (msg, info21.primary_gid, "primaryGroupID");
QUERY_AFLAGS(msg, info21.acct_flags, "userAccountControl");
- r->out.info->info21.fields_present = 0x00FFFFFF;
+ info->info21.fields_present = 0x00FFFFFF;
QUERY_LHOURS(msg, info21.logon_hours, "logonHours");
QUERY_UINT (msg, info21.bad_password_count, "badPwdCount");
QUERY_UINT (msg, info21.logon_count, "logonCount");
@@ -3323,10 +3351,12 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -3416,7 +3446,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
break;
case 20:
- SET_STRING(msg, info20.parameters, "userParameters");
+ SET_PARAMETERS(msg, info20.parameters, "userParameters");
break;
case 21:
@@ -3446,7 +3476,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info21.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info21.parameters, "userParameters");
+ SET_PARAMETERS(msg, info21.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info21.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3477,7 +3507,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info23.info.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info23.info.parameters, "userParameters");
+ SET_PARAMETERS(msg, info23.info.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info23.info.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3533,7 +3563,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info25.info.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info25.info.parameters, "userParameters");
+ SET_PARAMETERS(msg, info25.info.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info25.info.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3650,7 +3680,7 @@ static NTSTATUS dcesrv_samr_GetGroupsForUser(struct dcesrv_call_state *dce_call,
}
}
- r->out.rids = array;
+ *r->out.rids = array;
return NT_STATUS_OK;
}
@@ -3808,65 +3838,65 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call,
count += 1;
}
- r->out.total_size = count;
+ *r->out.total_size = count;
if (r->in.start_idx >= count) {
- r->out.returned_size = 0;
+ *r->out.returned_size = 0;
switch(r->in.level) {
case 1:
- r->out.info.info1.count = r->out.returned_size;
- r->out.info.info1.entries = NULL;
+ r->out.info->info1.count = *r->out.returned_size;
+ r->out.info->info1.entries = NULL;
break;
case 2:
- r->out.info.info2.count = r->out.returned_size;
- r->out.info.info2.entries = NULL;
+ r->out.info->info2.count = *r->out.returned_size;
+ r->out.info->info2.entries = NULL;
break;
case 3:
- r->out.info.info3.count = r->out.returned_size;
- r->out.info.info3.entries = NULL;
+ r->out.info->info3.count = *r->out.returned_size;
+ r->out.info->info3.entries = NULL;
break;
case 4:
- r->out.info.info4.count = r->out.returned_size;
- r->out.info.info4.entries = NULL;
+ r->out.info->info4.count = *r->out.returned_size;
+ r->out.info->info4.entries = NULL;
break;
case 5:
- r->out.info.info5.count = r->out.returned_size;
- r->out.info.info5.entries = NULL;
+ r->out.info->info5.count = *r->out.returned_size;
+ r->out.info->info5.entries = NULL;
break;
}
} else {
- r->out.returned_size = MIN(count - r->in.start_idx,
+ *r->out.returned_size = MIN(count - r->in.start_idx,
r->in.max_entries);
switch(r->in.level) {
case 1:
- r->out.info.info1.count = r->out.returned_size;
- r->out.info.info1.entries =
+ r->out.info->info1.count = *r->out.returned_size;
+ r->out.info->info1.entries =
&(entriesGeneral[r->in.start_idx]);
break;
case 2:
- r->out.info.info2.count = r->out.returned_size;
- r->out.info.info2.entries =
+ r->out.info->info2.count = *r->out.returned_size;
+ r->out.info->info2.entries =
&(entriesFull[r->in.start_idx]);
break;
case 3:
- r->out.info.info3.count = r->out.returned_size;
- r->out.info.info3.entries =
+ r->out.info->info3.count = *r->out.returned_size;
+ r->out.info->info3.entries =
&(entriesFullGroup[r->in.start_idx]);
break;
case 4:
- r->out.info.info4.count = r->out.returned_size;
- r->out.info.info4.entries =
+ r->out.info->info4.count = *r->out.returned_size;
+ r->out.info->info4.entries =
&(entriesAscii[r->in.start_idx]);
break;
case 5:
- r->out.info.info5.count = r->out.returned_size;
- r->out.info.info5.entries =
+ r->out.info->info5.count = *r->out.returned_size;
+ r->out.info->info5.entries =
&(entriesAscii[r->in.start_idx]);
break;
}
}
- return (r->out.returned_size < (count - r->in.start_idx)) ?
+ return (*r->out.returned_size < (count - r->in.start_idx)) ?
STATUS_MORE_ENTRIES : NT_STATUS_OK;
}
@@ -3910,18 +3940,18 @@ static NTSTATUS dcesrv_samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TA
struct dcesrv_handle *h;
struct samr_account_state *a_state;
- ZERO_STRUCT(r->out.info);
+ ZERO_STRUCTP(r->out.info);
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
a_state = h->data;
- r->out.info.min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
- a_state->domain_state->domain_dn, "minPwdLength",
- NULL);
- r->out.info.password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
- a_state->account_dn,
- "pwdProperties", NULL);
+ r->out.info->min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+ a_state->domain_state->domain_dn, "minPwdLength",
+ NULL);
+ r->out.info->password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+ a_state->account_dn,
+ "pwdProperties", NULL);
return NT_STATUS_OK;
}
@@ -4008,11 +4038,10 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo2(struct dcesrv_call_state *dce_call,
ZERO_STRUCT(r1.out);
r1.in.domain_handle = r->in.domain_handle;
r1.in.level = r->in.level;
-
+ r1.out.info = r->out.info;
+
status = dcesrv_samr_QueryDomainInfo(dce_call, mem_ctx, &r1);
- r->out.info = r1.out.info;
-
return status;
}
@@ -4028,13 +4057,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo2(struct dcesrv_call_state *dce_call, T
struct samr_QueryUserInfo r1;
NTSTATUS status;
- ZERO_STRUCT(r1.out);
r1.in.user_handle = r->in.user_handle;
r1.in.level = r->in.level;
+ r1.out.info = r->out.info;
status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1);
-
- r->out.info = r1.out.info;
return status;
}
@@ -4054,14 +4081,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call
q.in.start_idx = r->in.start_idx;
q.in.max_entries = r->in.max_entries;
q.in.buf_size = r->in.buf_size;
- ZERO_STRUCT(q.out);
+ q.out.total_size = r->out.total_size;
+ q.out.returned_size = r->out.returned_size;
+ q.out.info = r->out.info;
result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
- r->out.total_size = q.out.total_size;
- r->out.returned_size = q.out.returned_size;
- r->out.info = q.out.info;
-
return result;
}
@@ -4090,14 +4115,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo3(struct dcesrv_call_state *dce_call
q.in.start_idx = r->in.start_idx;
q.in.max_entries = r->in.max_entries;
q.in.buf_size = r->in.buf_size;
- ZERO_STRUCT(q.out);
+ q.out.total_size = r->out.total_size;
+ q.out.returned_size = r->out.returned_size;
+ q.out.info = r->out.info;
result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
- r->out.total_size = q.out.total_size;
- r->out.returned_size = q.out.returned_size;
- r->out.info = q.out.info;
-
return result;
}
@@ -4138,7 +4161,7 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL };
struct ldb_context *sam_ctx;
- ZERO_STRUCT(r->out.info);
+ ZERO_STRUCTP(r->out.info);
sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
@@ -4156,8 +4179,8 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- r->out.info.min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
- r->out.info.password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
+ r->out.info->min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
+ r->out.info->password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
talloc_free(msgs);
@@ -4267,9 +4290,9 @@ static NTSTATUS dcesrv_samr_Connect5(struct dcesrv_call_state *dce_call, TALLOC_
status = dcesrv_samr_Connect(dce_call, mem_ctx, &c);
- r->out.info->info1.client_version = SAMR_CONNECT_AFTER_W2K;
- r->out.info->info1.unknown2 = 0;
- r->out.level = r->in.level;
+ r->out.info_out->info1.client_version = SAMR_CONNECT_AFTER_W2K;
+ r->out.info_out->info1.unknown2 = 0;
+ *r->out.level_out = r->in.level_in;
return status;
}
@@ -4289,8 +4312,8 @@ static NTSTATUS dcesrv_samr_RidToSid(struct dcesrv_call_state *dce_call, TALLOC_
d_state = h->data;
/* form the users SID */
- r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
- if (!r->out.sid) {
+ *r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
+ if (!*r->out.sid) {
return NT_STATUS_NO_MEMORY;
}
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 1eb6a4f37c..ff8215a673 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -352,7 +352,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
uint8_t new_nt_hash[16], new_lm_hash[16];
struct samr_Password nt_verifier, lm_verifier;
- ZERO_STRUCT(r->out);
+ *r->out.dominfo = NULL;
+ *r->out.reject = NULL;
if (r->in.nt_password == NULL ||
r->in.nt_verifier == NULL) {
@@ -495,8 +496,8 @@ failed:
talloc_free(sam_ctx);
reject = talloc(mem_ctx, struct samr_ChangeReject);
- r->out.dominfo = dominfo;
- r->out.reject = reject;
+ *r->out.dominfo = dominfo;
+ *r->out.reject = reject;
if (reject == NULL) {
return status;
@@ -518,6 +519,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL
struct samr_ChangePasswordUser2 *r)
{
struct samr_ChangePasswordUser3 r2;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
r2.in.server = r->in.server;
r2.in.account = r->in.account;
@@ -527,6 +530,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL
r2.in.lm_password = r->in.lm_password;
r2.in.lm_verifier = r->in.lm_verifier;
r2.in.password3 = NULL;
+ r2.out.dominfo = &dominfo;
+ r2.out.reject = &reject;
return dcesrv_samr_ChangePasswordUser3(dce_call, mem_ctx, &r2);
}
diff --git a/source4/torture/libnet/libnet_domain.c b/source4/torture/libnet/libnet_domain.c
index 7d5be368c2..3c28d1a019 100644
--- a/source4/torture/libnet/libnet_domain.c
+++ b/source4/torture/libnet/libnet_domain.c
@@ -35,12 +35,13 @@
static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, struct lsa_String *domname,
- uint32_t *access_mask, struct dom_sid **sid)
+ uint32_t *access_mask, struct dom_sid **sid_p)
{
NTSTATUS status;
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -59,6 +60,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -70,7 +72,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = *access_mask;
- r3.in.sid = *sid = r2.out.sid;
+ r3.in.sid = *sid_p = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/libnet_group.c b/source4/torture/libnet/libnet_group.c
index 12b8167a86..9c9ecfd525 100644
--- a/source4/torture/libnet/libnet_group.c
+++ b/source4/torture/libnet/libnet_group.c
@@ -42,12 +42,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle group_handle;
+ struct samr_Ids rids, types;
names[0].string = groupname;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("group account lookup '%s'\n", groupname);
@@ -57,7 +60,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -139,6 +142,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -155,6 +159,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -166,7 +171,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/libnet_user.c b/source4/torture/libnet/libnet_user.c
index 6d3e682976..18007dccad 100644
--- a/source4/torture/libnet/libnet_user.c
+++ b/source4/torture/libnet/libnet_user.c
@@ -40,12 +40,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
names[0].string = username;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("user account lookup '%s'\n", username);
@@ -55,7 +58,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -92,6 +95,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -108,6 +112,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -119,7 +124,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/utils.c b/source4/torture/libnet/utils.c
index 54c5f2c29c..942540c80e 100644
--- a/source4/torture/libnet/utils.c
+++ b/source4/torture/libnet/utils.c
@@ -32,12 +32,13 @@
bool test_opendomain(struct torture_context *tctx,
struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, struct lsa_String *domname,
- struct dom_sid2 *sid)
+ struct dom_sid2 *sid_p)
{
NTSTATUS status;
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
torture_comment(tctx, "connecting\n");
@@ -51,6 +52,7 @@ bool test_opendomain(struct torture_context *tctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
torture_comment(tctx, "domain lookup on %s\n", domname->string);
@@ -59,7 +61,7 @@ bool test_opendomain(struct torture_context *tctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
torture_comment(tctx, "opening domain\n");
@@ -68,7 +70,7 @@ bool test_opendomain(struct torture_context *tctx,
torture_assert_ntstatus_ok(tctx, status, "OpenDomain failed");
*handle = domain_handle;
- *sid = *r2.out.sid;
+ *sid_p = **r2.out.sid;
return true;
}
@@ -84,19 +86,22 @@ bool test_user_cleanup(struct torture_context *tctx, struct dcerpc_pipe *p,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
names[0].string = name;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
torture_comment(tctx, "user account lookup '%s'\n", name);
status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
torture_assert_ntstatus_ok(tctx, status, "LookupNames failed");
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -174,12 +179,15 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle group_handle;
+ struct samr_Ids rids, types;
names[0].string = name;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("group account lookup '%s'\n", name);
@@ -189,7 +197,7 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
index c2b849127f..1148262dfe 100644
--- a/source4/torture/rpc/samba3rpc.c
+++ b/source4/torture/rpc/samba3rpc.c
@@ -355,7 +355,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
char **domain,
struct dcerpc_pipe **result_pipe,
struct policy_handle **result_handle,
- struct dom_sid **sid)
+ struct dom_sid **sid_p)
{
struct dcerpc_pipe *samr_pipe;
NTSTATUS status;
@@ -365,7 +365,10 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
struct samr_Connect2 conn;
struct samr_EnumDomains enumdom;
uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ struct samr_SamArray *sam = NULL;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
int dom_idx;
struct lsa_String domain_name;
struct lsa_String user_name;
@@ -423,6 +426,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
enumdom.in.resume_handle = &resume_handle;
enumdom.in.buf_size = (uint32_t)-1;
enumdom.out.resume_handle = &resume_handle;
+ enumdom.out.num_entries = &num_entries;
+ enumdom.out.sam = &sam;
status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
if (!NT_STATUS_IS_OK(status)) {
@@ -430,20 +435,21 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
goto fail;
}
- if (enumdom.out.num_entries != 2) {
+ if (*enumdom.out.num_entries != 2) {
d_printf("samr_EnumDomains returned %d entries, expected 2\n",
- enumdom.out.num_entries);
+ *enumdom.out.num_entries);
status = NT_STATUS_UNSUCCESSFUL;
goto fail;
}
- dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
+ dom_idx = strequal(sam->entries[0].name.string,
"builtin") ? 1:0;
l.in.connect_handle = &conn_handle;
- domain_name.string = enumdom.out.sam->entries[dom_idx].name.string;
+ domain_name.string = sam->entries[dom_idx].name.string;
*domain = talloc_strdup(mem_ctx, domain_name.string);
l.in.domain_name = &domain_name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -453,7 +459,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
o.in.connect_handle = &conn_handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = &domain_handle;
status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
@@ -477,10 +483,13 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
struct samr_LookupNames ln;
struct samr_OpenUser ou;
+ struct samr_Ids rids, types;
ln.in.domain_handle = &domain_handle;
ln.in.num_names = 1;
ln.in.names = &user_name;
+ ln.out.rids = &rids;
+ ln.out.types = &types;
status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
if (!NT_STATUS_IS_OK(status)) {
@@ -491,7 +500,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
ou.in.domain_handle = &domain_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- user_rid = ou.in.rid = ln.out.rids.ids[0];
+ user_rid = ou.in.rid = ln.out.rids->ids[0];
ou.out.user_handle = user_handle;
status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
@@ -509,8 +518,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
*result_pipe = samr_pipe;
*result_handle = user_handle;
- if (sid != NULL) {
- *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
+ if (sid_p != NULL) {
+ *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid);
}
return NT_STATUS_OK;
@@ -555,6 +564,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
struct samr_SetUserInfo sui;
struct samr_QueryUserInfo qui;
union samr_UserInfo u_info;
+ union samr_UserInfo *info;
DATA_BLOB session_key;
@@ -597,6 +607,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
qui.in.user_handle = wks_handle;
qui.in.level = 21;
+ qui.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
if (!NT_STATUS_IS_OK(status)) {
@@ -604,14 +615,14 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
goto done;
}
- qui.out.info->info21.allow_password_change = 0;
- qui.out.info->info21.force_password_change = 0;
- qui.out.info->info21.account_name.string = NULL;
- qui.out.info->info21.rid = 0;
- qui.out.info->info21.acct_expiry = 0;
- qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
+ info->info21.allow_password_change = 0;
+ info->info21.force_password_change = 0;
+ info->info21.account_name.string = NULL;
+ info->info21.rid = 0;
+ info->info21.acct_expiry = 0;
+ info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
- u_info.info21 = qui.out.info->info21;
+ u_info.info21 = info->info21;
sui.in.user_handle = wks_handle;
sui.in.info = &u_info;
sui.in.level = 21;
@@ -721,9 +732,11 @@ static bool join3(struct smbcli_state *cli,
{
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
q.in.user_handle = wks_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -732,7 +745,7 @@ static bool join3(struct smbcli_state *cli,
goto done;
}
- last_password_change = q.out.info->info21.last_password_change;
+ last_password_change = info->info21.last_password_change;
}
cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
@@ -830,9 +843,11 @@ static bool join3(struct smbcli_state *cli,
{
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
q.in.user_handle = wks_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -843,7 +858,7 @@ static bool join3(struct smbcli_state *cli,
if (use_level25) {
if (last_password_change
- == q.out.info->info21.last_password_change) {
+ == info->info21.last_password_change) {
d_printf("(%s) last_password_change unchanged "
"during join, level25 must change "
"it\n", __location__);
@@ -852,7 +867,7 @@ static bool join3(struct smbcli_state *cli,
}
else {
if (last_password_change
- != q.out.info->info21.last_password_change) {
+ != info->info21.last_password_change) {
d_printf("(%s) last_password_change changed "
"during join, level24 doesn't "
"change it\n", __location__);
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index 23c288bfcc..87690178a7 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -59,6 +59,13 @@ static void init_lsa_String(struct lsa_String *string, const char *s)
string->string = s;
}
+static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
+{
+ string->length = length;
+ string->size = length;
+ string->array = (uint16_t *)discard_const(s);
+}
+
bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle)
{
@@ -131,18 +138,20 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p,
NTSTATUS status;
struct samr_QuerySecurity r;
struct samr_SetSecurity s;
+ struct sec_desc_buf *sdbuf = NULL;
r.in.handle = handle;
r.in.sec_info = 7;
+ r.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
- torture_assert(tctx, r.out.sdbuf != NULL, "sdbuf is NULL");
+ torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
s.in.handle = handle;
s.in.sec_info = 7;
- s.in.sdbuf = r.out.sdbuf;
+ s.in.sdbuf = sdbuf;
if (torture_setting_bool(tctx, "samba4", false)) {
torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
@@ -168,6 +177,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
struct samr_QueryUserInfo q;
struct samr_QueryUserInfo q0;
union samr_UserInfo u;
+ union samr_UserInfo *info;
bool ret = true;
const char *test_account_name;
@@ -184,7 +194,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
s2.in.info = &u;
q.in.user_handle = handle;
- q.out.info = &u;
+ q.out.info = &info;
q0 = q;
#define TESTCALL(call, r) \
@@ -204,6 +214,14 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
break; \
}
+#define MEM_EQUAL(s1, s2, length, field) \
+ if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
+ torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+ #field, (const char *)s2, __location__); \
+ ret = false; \
+ break; \
+ }
+
#define INT_EQUAL(i1, i2, field) \
if (i1 != i2) { \
torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
@@ -218,7 +236,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(QueryUserInfo, q) \
s.in.level = lvl1; \
s2.in.level = lvl1; \
- u = *q.out.info; \
+ u = *info; \
if (lvl1 == 21) { \
ZERO_STRUCT(u.info21); \
u.info21.fields_present = fpval; \
@@ -228,21 +246,45 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(SetUserInfo2, s2) \
init_lsa_String(&u.info ## lvl1.field1, ""); \
TESTCALL(QueryUserInfo, q); \
- u = *q.out.info; \
+ u = *info; \
STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
q.in.level = lvl2; \
TESTCALL(QueryUserInfo, q) \
- u = *q.out.info; \
+ u = *info; \
STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
} while (0)
+#define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
+ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+ q.in.level = lvl1; \
+ TESTCALL(QueryUserInfo, q) \
+ s.in.level = lvl1; \
+ s2.in.level = lvl1; \
+ u = *info; \
+ if (lvl1 == 21) { \
+ ZERO_STRUCT(u.info21); \
+ u.info21.fields_present = fpval; \
+ } \
+ init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
+ TESTCALL(SetUserInfo, s) \
+ TESTCALL(SetUserInfo2, s2) \
+ init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
+ TESTCALL(QueryUserInfo, q); \
+ u = *info; \
+ MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
+ q.in.level = lvl2; \
+ TESTCALL(QueryUserInfo, q) \
+ u = *info; \
+ MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
+ } while (0)
+
#define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
q.in.level = lvl1; \
TESTCALL(QueryUserInfo, q) \
s.in.level = lvl1; \
s2.in.level = lvl1; \
- u = *q.out.info; \
+ u = *info; \
if (lvl1 == 21) { \
uint8_t *bits = u.info21.logon_hours.bits; \
ZERO_STRUCT(u.info21); \
@@ -257,11 +299,11 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(SetUserInfo2, s2) \
u.info ## lvl1.field1 = 0; \
TESTCALL(QueryUserInfo, q); \
- u = *q.out.info; \
+ u = *info; \
INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
q.in.level = lvl2; \
TESTCALL(QueryUserInfo, q) \
- u = *q.out.info; \
+ u = *info; \
INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
} while (0)
@@ -359,10 +401,10 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
SAMR_FIELD_WORKSTATIONS);
- TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
- TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
+ TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
+ TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
SAMR_FIELD_PARAMETERS);
- TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
+ TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
SAMR_FIELD_PARAMETERS);
TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
@@ -512,12 +554,14 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx
DATA_BLOB session_key;
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -564,12 +608,14 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t
DATA_BLOB session_key;
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -643,12 +689,14 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc
char *newpass;
struct MD5Context ctx;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
if (makeshort && policy_min_pw_len) {
newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
@@ -725,12 +773,14 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t
uint8_t confounder[16];
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -796,6 +846,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct
NTSTATUS status;
struct samr_SetAliasInfo r;
struct samr_QueryAliasInfo q;
+ union samr_AliasInfo *info;
uint16_t levels[] = {2, 3};
int i;
bool ret = true;
@@ -826,6 +877,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct
q.in.alias_handle = handle;
q.in.level = levels[i];
+ q.out.info = &info;
status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -842,11 +894,13 @@ static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context
struct policy_handle *user_handle)
{
struct samr_GetGroupsForUser r;
+ struct samr_RidWithAttributeArray *rids = NULL;
NTSTATUS status;
torture_comment(tctx, "testing GetGroupsForUser\n");
r.in.user_handle = user_handle;
+ r.out.rids = &rids;
status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
@@ -860,8 +914,11 @@ static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tct
{
NTSTATUS status;
struct samr_GetDomPwInfo r;
+ struct samr_PwInfo info;
r.in.domain_name = domain_name;
+ r.out.info = &info;
+
torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
@@ -893,10 +950,12 @@ static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tc
{
NTSTATUS status;
struct samr_GetUserPwInfo r;
+ struct samr_PwInfo info;
torture_comment(tctx, "Testing GetUserPwInfo\n");
r.in.user_handle = handle;
+ r.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
@@ -911,15 +970,18 @@ static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *t
NTSTATUS status;
struct samr_LookupNames n;
struct lsa_String sname[2];
+ struct samr_Ids rids, types;
init_lsa_String(&sname[0], name);
n.in.domain_handle = domain_handle;
n.in.num_names = 1;
n.in.names = sname;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, tctx, &n);
if (NT_STATUS_IS_OK(status)) {
- *rid = n.out.rids.ids[0];
+ *rid = n.out.rids->ids[0];
} else {
return status;
}
@@ -1071,6 +1133,7 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
@@ -1078,10 +1141,11 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex
return false;
}
pwp.in.user_handle = &user_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1346,12 +1410,14 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co
uint8_t old_lm_hash[16], new_lm_hash[16];
struct samr_GetDomPwInfo dom_pw_info;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
struct lsa_String domain_name;
domain_name.string = "";
dom_pw_info.in.domain_name = &domain_name;
+ dom_pw_info.out.info = &info;
torture_comment(tctx, "Testing OemChangePasswordUser2\n");
@@ -1362,7 +1428,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co
status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = dom_pw_info.out.info.min_password_length;
+ policy_min_pw_len = dom_pw_info.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1515,11 +1581,13 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte
uint8_t old_lm_hash[16], new_lm_hash[16];
struct samr_GetDomPwInfo dom_pw_info;
+ struct samr_PwInfo info;
struct lsa_String domain_name;
domain_name.string = "";
dom_pw_info.in.domain_name = &domain_name;
+ dom_pw_info.out.info = &info;
torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
@@ -1531,7 +1599,7 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte
int policy_min_pw_len = 0;
status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = dom_pw_info.out.info.min_password_length;
+ policy_min_pw_len = dom_pw_info.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1594,6 +1662,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
uint8_t old_nt_hash[16], new_nt_hash[16];
uint8_t old_lm_hash[16], new_lm_hash[16];
NTTIME t;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
torture_comment(tctx, "Testing ChangePasswordUser3\n");
@@ -1641,6 +1711,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
@@ -1670,6 +1742,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
@@ -1712,21 +1786,23 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
- && r.out.dominfo
- && r.out.reject
+ && dominfo
+ && reject
&& handle_reject_reason
- && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
- if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
+ && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
+ if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
- if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
+ if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
}
@@ -1740,54 +1816,54 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
Guenther */
- if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
- (last_password_change + r.out.dominfo->min_password_age > t)) {
+ if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
+ (last_password_change + dominfo->min_password_age > t)) {
- if (r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
- } else if ((r.out.dominfo->min_password_length > 0) &&
- (strlen(newpass) < r.out.dominfo->min_password_length)) {
+ } else if ((dominfo->min_password_length > 0) &&
+ (strlen(newpass) < dominfo->min_password_length)) {
- if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
+ if (reject->reason != SAMR_REJECT_TOO_SHORT) {
printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
- SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
+ SAMR_REJECT_TOO_SHORT, reject->reason);
return false;
}
- } else if ((r.out.dominfo->password_history_length > 0) &&
+ } else if ((dominfo->password_history_length > 0) &&
strequal(oldpass, newpass)) {
- if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
+ if (reject->reason != SAMR_REJECT_IN_HISTORY) {
printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
- SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
+ SAMR_REJECT_IN_HISTORY, reject->reason);
return false;
}
- } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
+ } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
- if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
+ if (reject->reason != SAMR_REJECT_COMPLEXITY) {
printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
- SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
+ SAMR_REJECT_COMPLEXITY, reject->reason);
return false;
}
}
- if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
+ if (reject->reason == SAMR_REJECT_TOO_SHORT) {
/* retry with adjusted size */
return test_ChangePasswordUser3(p, tctx, account_string,
- r.out.dominfo->min_password_length,
+ dominfo->min_password_length,
password, NULL, 0, false);
}
} else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -1823,6 +1899,8 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
char *oldpass;
uint8_t old_nt_hash[16], new_nt_hash[16];
NTTIME t;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
new_random_pass = samr_very_rand_pass(tctx, 128);
@@ -1889,15 +1967,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
r.in.lm_password = NULL;
r.in.lm_verifier = NULL;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -1925,15 +2005,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
r.in.lm_password = NULL;
r.in.lm_verifier = NULL;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -2061,6 +2143,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
{
char *password = NULL;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
NTSTATUS status;
bool ret = true;
@@ -2176,6 +2259,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
q.in.user_handle = user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2184,15 +2268,15 @@ static bool test_user_ops(struct dcerpc_pipe *p,
ret = false;
} else {
uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
- if ((q.out.info->info5.acct_flags) != expected_flags) {
+ if ((info->info5.acct_flags) != expected_flags) {
printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info5.acct_flags,
+ info->info5.acct_flags,
expected_flags);
ret = false;
}
- if (q.out.info->info5.rid != rid) {
+ if (info->info5.rid != rid) {
printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
- q.out.info->info5.rid, rid);
+ info->info5.rid, rid);
}
}
@@ -2481,6 +2565,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
/* set samr_SetDomainInfo level 1 with min_length 5 */
{
struct samr_QueryDomainInfo r;
+ union samr_DomainInfo *info = NULL;
struct samr_SetDomainInfo s;
uint16_t len_old, len;
uint32_t pwd_prop_old;
@@ -2491,6 +2576,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = domain_handle;
r.in.level = 1;
+ r.out.info = &info;
printf("testing samr_QueryDomainInfo level 1\n");
status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
@@ -2500,7 +2586,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
s.in.domain_handle = domain_handle;
s.in.level = 1;
- s.in.info = r.out.info;
+ s.in.info = info;
/* remember the old min length, so we can reset it */
len_old = s.in.info->info1.min_password_length;
@@ -2540,13 +2626,17 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_LookupNames n;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
n.in.domain_handle = domain_handle;
n.in.num_names = 1;
n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
n.in.names[0].string = acct_name;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
if (!NT_STATUS_IS_OK(status)) {
@@ -2556,17 +2646,18 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = domain_handle;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r.in.rid = n.out.rids.ids[0];
+ r.in.rid = n.out.rids->ids[0];
r.out.user_handle = &user_handle;
status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
+ printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
return false;
}
q.in.user_handle = &user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2577,7 +2668,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
printf("calling test_ChangePasswordUser3 with too early password change\n");
if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
- q.out.info->info5.last_password_change, true)) {
+ info->info5.last_password_change, true)) {
ret = false;
}
}
@@ -2607,6 +2698,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
NTSTATUS status;
struct samr_CreateUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_DeleteUser d;
uint32_t rid;
@@ -2654,6 +2746,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
} else {
q.in.user_handle = &user_handle;
q.in.level = 16;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2661,9 +2754,9 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
q.in.level, nt_errstr(status));
ret = false;
} else {
- if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
+ if ((info->info16.acct_flags & acct_flags) != acct_flags) {
printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info16.acct_flags,
+ info->info16.acct_flags,
acct_flags);
ret = false;
}
@@ -2705,6 +2798,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
NTSTATUS status;
struct samr_CreateUser2 r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_DeleteUser d;
struct policy_handle user_handle;
uint32_t rid;
@@ -2783,6 +2877,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
if (NT_STATUS_IS_OK(status)) {
q.in.user_handle = &user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2794,31 +2889,31 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
if (acct_flags == ACB_NORMAL) {
expected_flags |= ACB_PW_EXPIRED;
}
- if ((q.out.info->info5.acct_flags) != expected_flags) {
+ if ((info->info5.acct_flags) != expected_flags) {
printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info5.acct_flags,
+ info->info5.acct_flags,
expected_flags);
ret = false;
}
switch (acct_flags) {
case ACB_SVRTRUST:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
+ if (info->info5.primary_gid != DOMAIN_RID_DCS) {
printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
- DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_DCS, info->info5.primary_gid);
ret = false;
}
break;
case ACB_WSTRUST:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
+ if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
- DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
ret = false;
}
break;
case ACB_NORMAL:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
+ if (info->info5.primary_gid != DOMAIN_RID_USERS) {
printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
- DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_USERS, info->info5.primary_gid);
ret = false;
}
break;
@@ -2852,6 +2947,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryAliasInfo r;
+ union samr_AliasInfo *info;
uint16_t levels[] = {1, 2, 3};
int i;
bool ret = true;
@@ -2861,6 +2957,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.alias_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2878,6 +2975,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupInfo r;
+ union samr_GroupInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
bool ret = true;
@@ -2887,6 +2985,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.group_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2904,11 +3003,13 @@ static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupMember r;
+ struct samr_RidTypeArray *rids = NULL;
bool ret = true;
printf("Testing QueryGroupMember\n");
r.in.group_handle = handle;
+ r.out.rids = &rids;
status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2925,6 +3026,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupInfo r;
+ union samr_GroupInfo *info;
struct samr_SetGroupInfo s;
uint16_t levels[] = {1, 2, 3, 4};
uint16_t set_ok[] = {0, 1, 1, 1};
@@ -2936,6 +3038,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.group_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2948,7 +3051,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
s.in.group_handle = handle;
s.in.level = levels[i];
- s.in.info = r.out.info;
+ s.in.info = *r.out.info;
#if 0
/* disabled this, as it changes the name only from the point of view of samr,
@@ -2990,6 +3093,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryUserInfo r;
+ union samr_UserInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 16, 17, 20, 21};
int i;
@@ -3000,6 +3104,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.user_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3017,6 +3122,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryUserInfo2 r;
+ union samr_UserInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 16, 17, 20, 21};
int i;
@@ -3027,6 +3133,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.user_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3174,6 +3281,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
NTSTATUS status;
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
bool ret = true;
@@ -3192,6 +3300,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
q.in.user_handle = &user_handle;
q.in.level = 16;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -3199,9 +3308,9 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
nt_errstr(status));
ret = false;
} else {
- if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
+ if ((acct_flag_mask & info->info16.acct_flags) == 0) {
printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
- acct_flag_mask, q.out.info->info16.acct_flags, rid);
+ acct_flag_mask, info->info16.acct_flags, rid);
ret = false;
}
}
@@ -3223,6 +3332,11 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
bool ret = true;
struct samr_LookupNames n;
struct samr_LookupRids lr ;
+ struct lsa_Strings names;
+ struct samr_Ids rids, types;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
+
uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
@@ -3236,6 +3350,8 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
r.in.acct_flags = mask = masks[mask_idx];
r.in.max_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
@@ -3244,18 +3360,18 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
return false;
}
- torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
+ torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
- if (r.out.sam->count == 0) {
+ if (sam->count == 0) {
continue;
}
- for (i=0;i<r.out.sam->count;i++) {
+ for (i=0;i<sam->count;i++) {
if (mask) {
- if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
+ if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
ret = false;
}
- } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
+ } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3263,10 +3379,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
printf("Testing LookupNames\n");
n.in.domain_handle = handle;
- n.in.num_names = r.out.sam->count;
- n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
- for (i=0;i<r.out.sam->count;i++) {
- n.in.names[i].string = r.out.sam->entries[i].name.string;
+ n.in.num_names = sam->count;
+ n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
+ n.out.rids = &rids;
+ n.out.types = &types;
+ for (i=0;i<sam->count;i++) {
+ n.in.names[i].string = sam->entries[i].name.string;
}
status = dcerpc_samr_LookupNames(p, tctx, &n);
if (!NT_STATUS_IS_OK(status)) {
@@ -3277,10 +3395,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
printf("Testing LookupRids\n");
lr.in.domain_handle = handle;
- lr.in.num_rids = r.out.sam->count;
- lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
- for (i=0;i<r.out.sam->count;i++) {
- lr.in.rids[i] = r.out.sam->entries[i].idx;
+ lr.in.num_rids = sam->count;
+ lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
+ lr.out.names = &names;
+ lr.out.types = &types;
+ for (i=0;i<sam->count;i++) {
+ lr.in.rids[i] = sam->entries[i].idx;
}
status = dcerpc_samr_LookupRids(p, tctx, &lr);
torture_assert_ntstatus_ok(tctx, status, "LookupRids");
@@ -3337,6 +3457,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_EnumDomainGroups r;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
@@ -3346,6 +3468,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.resume_handle = &resume_handle;
r.in.max_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3353,12 +3477,12 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- if (!r.out.sam) {
+ if (!sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
- if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+ for (i=0;i<sam->count;i++) {
+ if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3372,6 +3496,8 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_EnumDomainAliases r;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
@@ -3379,7 +3505,9 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = handle;
r.in.resume_handle = &resume_handle;
- r.in.acct_flags = (uint32_t)-1;
+ r.in.max_size = (uint32_t)-1;
+ r.out.sam = &sam;
+ r.out.num_entries = &num_entries;
r.out.resume_handle = &resume_handle;
status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
@@ -3388,12 +3516,12 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- if (!r.out.sam) {
+ if (!sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
- if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+ for (i=0;i<sam->count;i++) {
+ if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3409,14 +3537,19 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
+ struct lsa_String name;
+ uint32_t idx = 0;
int i;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
+ init_lsa_String(&name, TEST_ACCOUNT_NAME);
+
r.in.domain_handle = handle;
r.in.level = levels[i];
- init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
+ r.in.name = &name;
+ r.out.idx = &idx;
status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
@@ -3428,7 +3561,7 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m
ret = false;
}
- init_lsa_String(&r.in.name, "zzzzzzzz");
+ init_lsa_String(&name, "zzzzzzzz");
status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
@@ -3450,14 +3583,19 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
+ struct lsa_String name;
+ uint32_t idx = 0;
int i;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
+ init_lsa_String(&name, TEST_ACCOUNT_NAME);
+
r.in.domain_handle = handle;
r.in.level = levels[i];
- init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
+ r.in.name = &name;
+ r.out.idx = &idx;
status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
if (ok_lvl[i] &&
@@ -3468,7 +3606,7 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *
ret = false;
}
- init_lsa_String(&r.in.name, "zzzzzzzz");
+ init_lsa_String(&name, "zzzzzzzz");
status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
@@ -3502,6 +3640,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
{
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
int i, ret = true;
NTSTATUS status;
@@ -3510,16 +3649,16 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
for (i = 0; ; i++) {
switch (querydisplayinfo->in.level) {
case 1:
- if (i >= querydisplayinfo->out.info.info1.count) {
+ if (i >= querydisplayinfo->out.info->info1.count) {
return ret;
}
- r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
+ r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
break;
case 2:
- if (i >= querydisplayinfo->out.info.info2.count) {
+ if (i >= querydisplayinfo->out.info->info2.count) {
return ret;
}
- r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
+ r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
break;
case 3:
/* Groups */
@@ -3543,6 +3682,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
q.in.user_handle = &user_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
@@ -3551,41 +3691,41 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
switch (querydisplayinfo->in.level) {
case 1:
- if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
+ if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
*seen_testuser = true;
}
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
- q.out.info->info21.full_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
- q.out.info->info21.account_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
- q.out.info->info21.description, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
- q.out.info->info21.rid, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
- q.out.info->info21.acct_flags, q.out.info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
+ info->info21.full_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
+ info->info21.account_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
+ info->info21.description, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
+ info->info21.rid, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
+ info->info21.acct_flags, info->info21.account_name);
break;
case 2:
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
- q.out.info->info21.account_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
- q.out.info->info21.description, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
- q.out.info->info21.rid, q.out.info->info21.account_name);
- INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
- q.out.info->info21.acct_flags, q.out.info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
+ info->info21.account_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
+ info->info21.description, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
+ info->info21.rid, info->info21.account_name);
+ INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
+ info->info21.acct_flags, info->info21.account_name);
- if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
+ if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
- q.out.info->info21.account_name.string);
+ info->info21.account_name.string);
}
- if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
+ if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
- q.out.info->info21.account_name.string,
- querydisplayinfo->out.info.info2.entries[i].acct_flags,
- q.out.info->info21.acct_flags);
+ info->info21.account_name.string,
+ querydisplayinfo->out.info->info2.entries[i].acct_flags,
+ info->info21.acct_flags);
return false;
}
@@ -3605,10 +3745,15 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_QueryDisplayInfo r;
struct samr_QueryDomainInfo dom_info;
+ union samr_DomainInfo *info = NULL;
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
bool seen_testuser = false;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo disp_info;
+
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing QueryDisplayInfo level %u\n", levels[i]);
@@ -3620,6 +3765,9 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.level = levels[i];
r.in.max_entries = 2;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &disp_info;
status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
@@ -3632,27 +3780,29 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
ret = false;
}
- r.in.start_idx += r.out.info.info1.count;
+ r.in.start_idx += r.out.info->info1.count;
break;
case 2:
if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
ret = false;
}
- r.in.start_idx += r.out.info.info2.count;
+ r.in.start_idx += r.out.info->info2.count;
break;
case 3:
- r.in.start_idx += r.out.info.info3.count;
+ r.in.start_idx += r.out.info->info3.count;
break;
case 4:
- r.in.start_idx += r.out.info.info4.count;
+ r.in.start_idx += r.out.info->info4.count;
break;
case 5:
- r.in.start_idx += r.out.info.info5.count;
+ r.in.start_idx += r.out.info->info5.count;
break;
}
}
dom_info.in.domain_handle = handle;
dom_info.in.level = 2;
+ dom_info.out.info = &info;
+
/* Check number of users returned is correct */
status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
if (!NT_STATUS_IS_OK(status)) {
@@ -3664,17 +3814,17 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
switch (r.in.level) {
case 1:
case 4:
- if (dom_info.out.info->general.num_users < r.in.start_idx) {
+ if (info->general.num_users < r.in.start_idx) {
printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
- r.in.start_idx, dom_info.out.info->general.num_groups,
- dom_info.out.info->general.domain_name.string);
+ r.in.start_idx, info->general.num_groups,
+ info->general.domain_name.string);
ret = false;
}
if (!seen_testuser) {
struct policy_handle user_handle;
if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
- dom_info.out.info->general.domain_name.string);
+ info->general.domain_name.string);
ret = false;
test_samr_handle_Close(p, mem_ctx, &user_handle);
}
@@ -3682,10 +3832,10 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
break;
case 3:
case 5:
- if (dom_info.out.info->general.num_groups != r.in.start_idx) {
+ if (info->general.num_groups != r.in.start_idx) {
printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
- r.in.start_idx, dom_info.out.info->general.num_groups,
- dom_info.out.info->general.domain_name.string);
+ r.in.start_idx, info->general.num_groups,
+ info->general.domain_name.string);
ret = false;
}
@@ -3705,6 +3855,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
@@ -3714,6 +3867,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.start_idx = 0;
r.in.max_entries = 1000;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3734,6 +3890,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
for (i=0;i<ARRAY_SIZE(levels);i++) {
torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
@@ -3743,6 +3902,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context
r.in.start_idx = 0;
r.in.max_entries = 1000;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3762,6 +3924,9 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
NTSTATUS status;
struct samr_QueryDisplayInfo r;
bool ret = true;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
printf("Testing QueryDisplayInfo continuation\n");
@@ -3770,14 +3935,17 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
r.in.start_idx = 0;
r.in.max_entries = 1;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
do {
status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
- if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
- if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
+ if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
+ if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
printf("expected idx %d but got %d\n",
r.in.start_idx + 1,
- r.out.info.info1.entries[0].idx);
+ r.out.info->info1.entries[0].idx);
break;
}
}
@@ -3791,7 +3959,7 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
r.in.start_idx++;
} while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
NT_STATUS_IS_OK(status)) &&
- r.out.returned_size != 0);
+ *r.out.returned_size != 0);
return ret;
}
@@ -3801,6 +3969,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
{
NTSTATUS status;
struct samr_QueryDomainInfo r;
+ union samr_DomainInfo *info = NULL;
struct samr_SetDomainInfo s;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
@@ -3827,6 +3996,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
r.in.domain_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3838,40 +4008,40 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
switch (levels[i]) {
case 2:
- if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
- levels[i], r.out.info->general.oem_information.string, domain_comment);
+ levels[i], info->general.oem_information.string, domain_comment);
ret = false;
}
- if (!r.out.info->general.primary.string) {
+ if (!info->general.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
levels[i]);
ret = false;
- } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
- if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
+ } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
+ if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
- levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
+ levels[i], info->general.primary.string, dcerpc_server_name(p));
}
}
break;
case 4:
- if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
- levels[i], r.out.info->oem.oem_information.string, domain_comment);
+ levels[i], info->oem.oem_information.string, domain_comment);
ret = false;
}
break;
case 6:
- if (!r.out.info->info6.primary.string) {
+ if (!info->info6.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
levels[i]);
ret = false;
}
break;
case 11:
- if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
- levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
+ levels[i], info->general2.general.oem_information.string, domain_comment);
ret = false;
}
break;
@@ -3881,7 +4051,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
s.in.domain_handle = handle;
s.in.level = levels[i];
- s.in.info = r.out.info;
+ s.in.info = info;
status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
if (set_ok[i]) {
@@ -3918,6 +4088,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context
{
NTSTATUS status;
struct samr_QueryDomainInfo2 r;
+ union samr_DomainInfo *info = NULL;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
int i;
bool ret = true;
@@ -3927,6 +4098,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context
r.in.domain_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3949,8 +4121,13 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_QueryDisplayInfo q2;
NTSTATUS status;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
int num_names = 0;
const char **names = NULL;
@@ -3961,6 +4138,8 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
q1.in.resume_handle = &resume_handle;
q1.in.max_size = 5;
q1.out.resume_handle = &resume_handle;
+ q1.out.num_entries = &num_entries;
+ q1.out.sam = &sam;
status = STATUS_MORE_ENTRIES;
while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
@@ -3970,22 +4149,25 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
break;
- for (i=0; i<q1.out.num_entries; i++) {
+ for (i=0; i<*q1.out.num_entries; i++) {
add_string_to_array(tctx,
- q1.out.sam->entries[i].name.string,
+ sam->entries[i].name.string,
&names, &num_names);
}
}
torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
- torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
+ torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
q2.in.domain_handle = handle;
q2.in.level = 5;
q2.in.start_idx = 0;
q2.in.max_entries = 5;
q2.in.buf_size = (uint32_t)-1;
+ q2.out.total_size = &total_size;
+ q2.out.returned_size = &returned_size;
+ q2.out.info = &info;
status = STATUS_MORE_ENTRIES;
while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
@@ -3995,9 +4177,9 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
break;
- for (i=0; i<q2.out.info.info5.count; i++) {
+ for (i=0; i<q2.out.info->info5.count; i++) {
int j;
- const char *name = q2.out.info.info5.entries[i].account_name.string;
+ const char *name = q2.out.info->info5.entries[i].account_name.string;
bool found = false;
for (j=0; j<num_names; j++) {
if (names[j] == NULL)
@@ -4015,7 +4197,7 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
ret = false;
}
}
- q2.in.start_idx += q2.out.info.info5.count;
+ q2.in.start_idx += q2.out.info->info5.count;
}
if (!NT_STATUS_IS_OK(status)) {
@@ -4076,7 +4258,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_RidToSid r;
NTSTATUS status;
bool ret = true;
- struct dom_sid *calc_sid;
+ struct dom_sid *calc_sid, *out_sid;
int rids[] = { 0, 42, 512, 10200 };
int i;
@@ -4086,6 +4268,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
calc_sid = dom_sid_dup(tctx, domain_sid);
r.in.domain_handle = domain_handle;
r.in.rid = rids[i];
+ r.out.sid = &out_sid;
status = dcerpc_samr_RidToSid(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -4094,9 +4277,9 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
} else {
calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
- if (!dom_sid_equal(calc_sid, r.out.sid)) {
+ if (!dom_sid_equal(calc_sid, out_sid)) {
printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
- dom_sid_string(tctx, r.out.sid),
+ dom_sid_string(tctx, out_sid),
dom_sid_string(tctx, calc_sid));
ret = false;
}
@@ -4112,10 +4295,12 @@ static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_con
struct samr_GetBootKeyInformation r;
NTSTATUS status;
bool ret = true;
+ uint32_t unknown = 0;
torture_comment(tctx, "Testing GetBootKeyInformation\n");
r.in.domain_handle = domain_handle;
+ r.out.unknown = &unknown;
status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -4134,6 +4319,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
struct samr_AddGroupMember r;
struct samr_DeleteGroupMember d;
struct samr_QueryGroupMember q;
+ struct samr_RidTypeArray *rids = NULL;
struct samr_SetMemberAttributesOfGroup s;
uint32_t rid;
@@ -4173,6 +4359,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
}
q.in.group_handle = group_handle;
+ q.out.rids = &rids;
status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
@@ -4388,6 +4575,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
{
NTSTATUS status;
struct samr_LookupDomain r;
+ struct dom_sid2 *sid = NULL;
struct lsa_String n1;
struct lsa_String n2;
bool ret = true;
@@ -4397,6 +4585,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
/* check for correct error codes */
r.in.connect_handle = handle;
r.in.domain_name = &n2;
+ r.out.sid = &sid;
n2.string = NULL;
status = dcerpc_samr_LookupDomain(p, tctx, &r);
@@ -4419,7 +4608,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
ret = false;
}
- if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
+ if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
ret = false;
}
@@ -4433,6 +4622,8 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx
NTSTATUS status;
struct samr_EnumDomains r;
uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ struct samr_SamArray *sam = NULL;
int i;
bool ret = true;
@@ -4440,17 +4631,19 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx
r.in.resume_handle = &resume_handle;
r.in.buf_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
- if (!r.out.sam) {
+ if (!*r.out.sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
+ for (i=0;i<sam->count;i++) {
if (!test_LookupDomain(p, tctx, handle,
- r.out.sam->entries[i].name.string, which_ops)) {
+ sam->entries[i].name.string, which_ops)) {
ret = false;
}
}
@@ -4473,6 +4666,7 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_Connect5 r5;
union samr_ConnectInfo info;
struct policy_handle h;
+ uint32_t level_out = 0;
bool ret = true, got_handle = false;
torture_comment(tctx, "testing samr_Connect\n");
@@ -4553,9 +4747,10 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
r5.in.system_name = "";
r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r5.in.level = 1;
- r5.in.info = &info;
- r5.out.info = &info;
+ r5.in.level_in = 1;
+ r5.out.level_out = &level_out;
+ r5.in.info_in = &info;
+ r5.out.info_out = &info;
r5.out.connect_handle = &h;
status = dcerpc_samr_Connect5(p, tctx, &r5);
diff --git a/source4/torture/rpc/samr_accessmask.c b/source4/torture/rpc/samr_accessmask.c
index bfff8c9267..9a8e442019 100644
--- a/source4/torture/rpc/samr_accessmask.c
+++ b/source4/torture/rpc/samr_accessmask.c
@@ -52,13 +52,15 @@ static NTSTATUS torture_samr_Connect5(struct torture_context *tctx,
NTSTATUS status;
struct samr_Connect5 r5;
union samr_ConnectInfo info;
+ uint32_t level_out = 0;
info.info1.client_version = 0;
info.info1.unknown2 = 0;
r5.in.system_name = "";
- r5.in.level = 1;
- r5.in.info = &info;
- r5.out.info = &info;
+ r5.in.level_in = 1;
+ r5.in.info_in = &info;
+ r5.out.info_out = &info;
+ r5.out.level_out = &level_out;
r5.out.connect_handle = h;
r5.in.access_mask = mask;
@@ -147,6 +149,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
int i;
uint32_t mask;
uint32_t resume_handle = 0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
printf("testing which bits in Connect5 accessmask allows us to EnumDomains\n");
mask = 1;
@@ -170,6 +174,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
ed.in.resume_handle = &resume_handle;
ed.in.buf_size = (uint32_t)-1;
ed.out.resume_handle = &resume_handle;
+ ed.out.num_entries = &num_entries;
+ ed.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &ed);
if (!NT_STATUS_IS_OK(status)) {
@@ -195,6 +201,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
ed.in.resume_handle = &resume_handle;
ed.in.buf_size = (uint32_t)-1;
ed.out.resume_handle = &resume_handle;
+ ed.out.num_entries = &num_entries;
+ ed.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &ed);
if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
@@ -236,7 +244,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
struct samr_SetSecurity ss;
struct security_ace ace;
struct security_descriptor *sd;
- struct sec_desc_buf sdb;
+ struct sec_desc_buf sdb, *sdbuf = NULL;
bool ret = true;
int sd_size;
struct dcerpc_pipe *test_p;
@@ -255,6 +263,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
/* get the current ACL for the SAMR policy handle */
qs.in.handle = &ch;
qs.in.sec_info = SECINFO_DACL;
+ qs.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(p, tctx, &qs);
if (!NT_STATUS_IS_OK(status)) {
printf("QuerySecurity failed - %s\n", nt_errstr(status));
@@ -262,13 +271,13 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
}
/* how big is the security descriptor? */
- sd_size = qs.out.sdbuf->sd_size;
+ sd_size = sdbuf->sd_size;
/* add an ACE to the security descriptor to deny the user the
* 'connect to server' right
*/
- sd = qs.out.sdbuf->sd;
+ sd = sdbuf->sd;
ace.type = SEC_ACE_TYPE_ACCESS_DENIED;
ace.flags = 0;
ace.access_mask = SAMR_ACCESS_CONNECT_TO_SERVER;
@@ -314,7 +323,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
printf("QuerySecurity failed - %s\n", nt_errstr(status));
ret = false;
}
- if (sd_size != qs.out.sdbuf->sd_size) {
+ if (sd_size != sdbuf->sd_size) {
printf("security descriptor changed\n");
ret = false;
}
@@ -387,6 +396,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct policy_handle ch;
struct lsa_String dn;
int i;
@@ -412,6 +422,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
ld.in.connect_handle = &ch;
ld.in.domain_name = &dn;
+ ld.out.sid = &sid;
dn.string = lp_workgroup(tctx->lp_ctx);
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
@@ -471,6 +482,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain od;
struct policy_handle ch;
struct policy_handle dh;
@@ -488,6 +500,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
ld.in.connect_handle = &ch;
ld.in.domain_name = &dn;
+ ld.out.sid = &sid;
dn.string = lp_workgroup(tctx->lp_ctx);
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
if (!NT_STATUS_IS_OK(status)) {
@@ -517,7 +530,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
od.in.connect_handle = &ch;
od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- od.in.sid = ld.out.sid;
+ od.in.sid = *ld.out.sid;
od.out.domain_handle = &dh;
status = dcerpc_samr_OpenDomain(p, tctx, &od);
diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c
index 12ddc934c9..a3fc6f740f 100644
--- a/source4/torture/rpc/samsync.c
+++ b/source4/torture/rpc/samsync.c
@@ -151,17 +151,19 @@ struct samsync_trusted_domain {
static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
struct samsync_state *samsync_state,
const char *domain,
- struct dom_sid **sid)
+ struct dom_sid **sid_p)
{
struct lsa_String name;
struct samr_OpenDomain o;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
struct policy_handle *domain_handle = talloc(mem_ctx, struct policy_handle);
NTSTATUS nt_status;
name.string = domain;
l.in.connect_handle = samsync_state->connect_handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
nt_status = dcerpc_samr_LookupDomain(samsync_state->p_samr, mem_ctx, &l);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -171,11 +173,11 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
o.in.connect_handle = samsync_state->connect_handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = domain_handle;
if (sid) {
- *sid = l.out.sid;
+ *sid_p = *l.out.sid;
}
nt_status = dcerpc_samr_OpenDomain(samsync_state->p_samr, mem_ctx, &o);
@@ -192,10 +194,12 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
struct samr_QuerySecurity r;
+ struct sec_desc_buf *sdbuf = NULL;
NTSTATUS status;
r.in.handle = handle;
r.in.sec_info = 0x7;
+ r.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(samsync_state->p_samr, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -203,7 +207,7 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx,
return NULL;
}
- return r.out.sdbuf;
+ return sdbuf;
}
static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx,
@@ -260,6 +264,15 @@ static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx,
} \
} while (0)
+#define TEST_BINARY_STRING_EQUAL(s1, s2) do {\
+ if (!((!s1.array || s1.array[0]=='\0') && (!s2.array || s2.array[0]=='\0')) \
+ && memcmp(s1.array, s2.array, s1.length * 2) != 0) {\
+ printf("%s: string mismatch: " #s1 ":%s != " #s2 ": %s\n", \
+ __location__, (const char *)s1.array, (const char *)s2.array);\
+ ret = false;\
+ } \
+} while (0)
+
#define TEST_SID_EQUAL(s1, s2) do {\
if (!dom_sid_equal(s1, s2)) {\
printf("%s: dom_sid mismatch: " #s1 ":%s != " #s2 ": %s\n", \
@@ -294,6 +307,7 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
struct netr_DELTA_DOMAIN *domain = delta->delta_union.domain;
struct dom_sid *dom_sid;
struct samr_QueryDomainInfo q[14]; /* q[0] will be unused simple for clarity */
+ union samr_DomainInfo *info[14];
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
NTSTATUS nt_status;
int i;
@@ -341,8 +355,10 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
(long long)samsync_state->seq_num[database_id]);
for (i=0;i<ARRAY_SIZE(levels);i++) {
+
q[levels[i]].in.domain_handle = samsync_state->domain_handle[database_id];
q[levels[i]].in.level = levels[i];
+ q[levels[i]].out.info = &info[levels[i]];
nt_status = dcerpc_samr_QueryDomainInfo(samsync_state->p_samr, mem_ctx, &q[levels[i]]);
@@ -353,23 +369,23 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
}
}
- TEST_STRING_EQUAL(q[5].out.info->info5.domain_name, domain->domain_name);
+ TEST_STRING_EQUAL(info[5]->info5.domain_name, domain->domain_name);
- TEST_STRING_EQUAL(q[2].out.info->general.oem_information, domain->oem_information);
- TEST_STRING_EQUAL(q[4].out.info->oem.oem_information, domain->oem_information);
- TEST_TIME_EQUAL(q[2].out.info->general.force_logoff_time, domain->force_logoff_time);
- TEST_TIME_EQUAL(q[3].out.info->info3.force_logoff_time, domain->force_logoff_time);
+ TEST_STRING_EQUAL(info[2]->general.oem_information, domain->oem_information);
+ TEST_STRING_EQUAL(info[4]->oem.oem_information, domain->oem_information);
+ TEST_TIME_EQUAL(info[2]->general.force_logoff_time, domain->force_logoff_time);
+ TEST_TIME_EQUAL(info[3]->info3.force_logoff_time, domain->force_logoff_time);
- TEST_TIME_EQUAL(q[1].out.info->info1.min_password_length, domain->min_password_length);
- TEST_TIME_EQUAL(q[1].out.info->info1.password_history_length, domain->password_history_length);
- TEST_TIME_EQUAL(q[1].out.info->info1.max_password_age, domain->max_password_age);
- TEST_TIME_EQUAL(q[1].out.info->info1.min_password_age, domain->min_password_age);
+ TEST_TIME_EQUAL(info[1]->info1.min_password_length, domain->min_password_length);
+ TEST_TIME_EQUAL(info[1]->info1.password_history_length, domain->password_history_length);
+ TEST_TIME_EQUAL(info[1]->info1.max_password_age, domain->max_password_age);
+ TEST_TIME_EQUAL(info[1]->info1.min_password_age, domain->min_password_age);
- TEST_UINT64_EQUAL(q[8].out.info->info8.sequence_num,
+ TEST_UINT64_EQUAL(info[8]->info8.sequence_num,
domain->sequence_num);
- TEST_TIME_EQUAL(q[8].out.info->info8.domain_create_time,
+ TEST_TIME_EQUAL(info[8]->info8.domain_create_time,
domain->domain_create_time);
- TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time,
+ TEST_TIME_EQUAL(info[13]->info13.domain_create_time,
domain->domain_create_time);
TEST_SEC_DESC_EQUAL(domain->sdbuf, samr, samsync_state->domain_handle[database_id]);
@@ -425,9 +441,12 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
struct samr_GetGroupsForUser getgroups;
+ struct samr_RidWithAttributeArray *rids;
+
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
printf("SamSync needs domain information before the users\n");
return false;
@@ -446,6 +465,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
q.in.user_handle = &user_handle;
q.in.level = 21;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(user->sdbuf, samr, &user_handle);
@@ -457,6 +477,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
}
getgroups.in.user_handle = &user_handle;
+ getgroups.out.rids = &rids;
nt_status = dcerpc_samr_GetGroupsForUser(samsync_state->p_samr, mem_ctx, &getgroups);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -480,67 +501,67 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
return false;
}
- TEST_STRING_EQUAL(q.out.info->info21.account_name, user->account_name);
- TEST_STRING_EQUAL(q.out.info->info21.full_name, user->full_name);
- TEST_INT_EQUAL(q.out.info->info21.rid, user->rid);
- TEST_INT_EQUAL(q.out.info->info21.primary_gid, user->primary_gid);
- TEST_STRING_EQUAL(q.out.info->info21.home_directory, user->home_directory);
- TEST_STRING_EQUAL(q.out.info->info21.home_drive, user->home_drive);
- TEST_STRING_EQUAL(q.out.info->info21.logon_script, user->logon_script);
- TEST_STRING_EQUAL(q.out.info->info21.description, user->description);
- TEST_STRING_EQUAL(q.out.info->info21.workstations, user->workstations);
+ TEST_STRING_EQUAL(info->info21.account_name, user->account_name);
+ TEST_STRING_EQUAL(info->info21.full_name, user->full_name);
+ TEST_INT_EQUAL(info->info21.rid, user->rid);
+ TEST_INT_EQUAL(info->info21.primary_gid, user->primary_gid);
+ TEST_STRING_EQUAL(info->info21.home_directory, user->home_directory);
+ TEST_STRING_EQUAL(info->info21.home_drive, user->home_drive);
+ TEST_STRING_EQUAL(info->info21.logon_script, user->logon_script);
+ TEST_STRING_EQUAL(info->info21.description, user->description);
+ TEST_STRING_EQUAL(info->info21.workstations, user->workstations);
- TEST_TIME_EQUAL(q.out.info->info21.last_logon, user->last_logon);
- TEST_TIME_EQUAL(q.out.info->info21.last_logoff, user->last_logoff);
+ TEST_TIME_EQUAL(info->info21.last_logon, user->last_logon);
+ TEST_TIME_EQUAL(info->info21.last_logoff, user->last_logoff);
- TEST_INT_EQUAL(q.out.info->info21.logon_hours.units_per_week,
+ TEST_INT_EQUAL(info->info21.logon_hours.units_per_week,
user->logon_hours.units_per_week);
if (ret) {
- if (memcmp(q.out.info->info21.logon_hours.bits, user->logon_hours.bits,
- q.out.info->info21.logon_hours.units_per_week/8) != 0) {
+ if (memcmp(info->info21.logon_hours.bits, user->logon_hours.bits,
+ info->info21.logon_hours.units_per_week/8) != 0) {
printf("Logon hours mismatch\n");
ret = false;
}
}
- TEST_INT_EQUAL(q.out.info->info21.bad_password_count,
+ TEST_INT_EQUAL(info->info21.bad_password_count,
user->bad_password_count);
- TEST_INT_EQUAL(q.out.info->info21.logon_count,
+ TEST_INT_EQUAL(info->info21.logon_count,
user->logon_count);
- TEST_TIME_EQUAL(q.out.info->info21.last_password_change,
+ TEST_TIME_EQUAL(info->info21.last_password_change,
user->last_password_change);
- TEST_TIME_EQUAL(q.out.info->info21.acct_expiry,
+ TEST_TIME_EQUAL(info->info21.acct_expiry,
user->acct_expiry);
- TEST_INT_EQUAL((q.out.info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags);
+ TEST_INT_EQUAL((info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags);
if (user->acct_flags & ACB_PWNOEXP) {
- if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) {
+ if (info->info21.acct_flags & ACB_PW_EXPIRED) {
printf("ACB flags mismatch: both expired and no expiry!\n");
ret = false;
}
- if (q.out.info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) {
+ if (info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) {
printf("ACB flags mismatch: no password expiry, but force password change 0x%016llx (%lld) != 0x%016llx (%lld)\n",
- (unsigned long long)q.out.info->info21.force_password_change,
- (unsigned long long)q.out.info->info21.force_password_change,
+ (unsigned long long)info->info21.force_password_change,
+ (unsigned long long)info->info21.force_password_change,
(unsigned long long)0x7FFFFFFFFFFFFFFFULL, (unsigned long long)0x7FFFFFFFFFFFFFFFULL
);
ret = false;
}
}
- TEST_INT_EQUAL(q.out.info->info21.nt_password_set, user->nt_password_present);
- TEST_INT_EQUAL(q.out.info->info21.lm_password_set, user->lm_password_present);
- TEST_INT_EQUAL(q.out.info->info21.password_expired, user->password_expired);
+ TEST_INT_EQUAL(info->info21.nt_password_set, user->nt_password_present);
+ TEST_INT_EQUAL(info->info21.lm_password_set, user->lm_password_present);
+ TEST_INT_EQUAL(info->info21.password_expired, user->password_expired);
- TEST_STRING_EQUAL(q.out.info->info21.comment, user->comment);
- TEST_STRING_EQUAL(q.out.info->info21.parameters, user->parameters);
+ TEST_STRING_EQUAL(info->info21.comment, user->comment);
+ TEST_BINARY_STRING_EQUAL(info->info21.parameters, user->parameters);
- TEST_INT_EQUAL(q.out.info->info21.country_code, user->country_code);
- TEST_INT_EQUAL(q.out.info->info21.code_page, user->code_page);
+ TEST_INT_EQUAL(info->info21.country_code, user->country_code);
+ TEST_INT_EQUAL(info->info21.code_page, user->code_page);
- TEST_STRING_EQUAL(q.out.info->info21.profile_path, user->profile_path);
+ TEST_STRING_EQUAL(info->info21.profile_path, user->profile_path);
if (user->lm_password_present) {
sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0);
@@ -619,7 +640,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
return true;
}
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED)) {
- if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) {
+ if (info->info21.acct_flags & ACB_PW_EXPIRED) {
return true;
}
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
@@ -654,7 +675,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
TEST_TIME_EQUAL(user->last_logon, info3->base.last_logon);
TEST_TIME_EQUAL(user->acct_expiry, info3->base.acct_expiry);
TEST_TIME_EQUAL(user->last_password_change, info3->base.last_password_change);
- TEST_TIME_EQUAL(q.out.info->info21.force_password_change, info3->base.force_password_change);
+ TEST_TIME_EQUAL(info->info21.force_password_change, info3->base.force_password_change);
/* Does the concept of a logoff time ever really
* exist? (not in any sensible way, according to the
@@ -667,28 +688,28 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
TEST_TIME_EQUAL(user->last_logoff, info3->base.last_logoff);
}
- TEST_INT_EQUAL(getgroups.out.rids->count, info3->base.groups.count);
- if (getgroups.out.rids->count == info3->base.groups.count) {
+ TEST_INT_EQUAL(rids->count, info3->base.groups.count);
+ if (rids->count == info3->base.groups.count) {
int i, j;
- int count = getgroups.out.rids->count;
- bool *matched = talloc_zero_array(mem_ctx, bool, getgroups.out.rids->count);
+ int count = rids->count;
+ bool *matched = talloc_zero_array(mem_ctx, bool, rids->count);
for (i = 0; i < count; i++) {
for (j = 0; j < count; j++) {
- if ((getgroups.out.rids->rids[i].rid ==
+ if ((rids->rids[i].rid ==
info3->base.groups.rids[j].rid)
- && (getgroups.out.rids->rids[i].attributes ==
+ && (rids->rids[i].attributes ==
info3->base.groups.rids[j].attributes)) {
matched[i] = true;
}
}
}
- for (i = 0; i < getgroups.out.rids->count; i++) {
+ for (i = 0; i < rids->count; i++) {
if (matched[i] == false) {
ret = false;
printf("Could not find group RID %u found in getgroups in NETLOGON reply\n",
- getgroups.out.rids->rids[i].rid);
+ rids->rids[i].rid);
}
}
}
@@ -711,6 +732,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
struct samr_OpenAlias r;
struct samr_QueryAliasInfo q;
+ union samr_AliasInfo *info;
struct policy_handle alias_handle;
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
@@ -731,6 +753,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
q.in.alias_handle = &alias_handle;
q.in.level = 1;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(alias->sdbuf, samr, &alias_handle);
@@ -745,8 +768,8 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
return false;
}
- TEST_STRING_EQUAL(q.out.info->all.name, alias->alias_name);
- TEST_STRING_EQUAL(q.out.info->all.description, alias->description);
+ TEST_STRING_EQUAL(info->all.name, alias->alias_name);
+ TEST_STRING_EQUAL(info->all.description, alias->description);
return ret;
}
@@ -760,6 +783,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
struct samr_OpenGroup r;
struct samr_QueryGroupInfo q;
+ union samr_GroupInfo *info;
struct policy_handle group_handle;
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
@@ -780,6 +804,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
q.in.group_handle = &group_handle;
q.in.level = 1;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(group->sdbuf, samr, &group_handle);
@@ -794,9 +819,9 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
return false;
}
- TEST_STRING_EQUAL(q.out.info->all.name, group->group_name);
- TEST_INT_EQUAL(q.out.info->all.attributes, group->attributes);
- TEST_STRING_EQUAL(q.out.info->all.description, group->description);
+ TEST_STRING_EQUAL(info->all.name, group->group_name);
+ TEST_INT_EQUAL(info->all.attributes, group->attributes);
+ TEST_STRING_EQUAL(info->all.description, group->description);
return ret;
}
diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
index ca1655729b..451990a71b 100644
--- a/source4/torture/rpc/schannel.c
+++ b/source4/torture/rpc/schannel.c
@@ -128,6 +128,7 @@ static bool test_samr_ops(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_GetDomPwInfo r;
+ struct samr_PwInfo info;
struct samr_Connect connect;
struct samr_OpenDomain opendom;
int i;
@@ -137,6 +138,7 @@ static bool test_samr_ops(struct torture_context *tctx,
name.string = lp_workgroup(tctx->lp_ctx);
r.in.domain_name = &name;
+ r.out.info = &info;
connect.in.system_name = 0;
connect.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c
index 3408a1924c..3b56d5b0ad 100644
--- a/source4/torture/rpc/testjoin.c
+++ b/source4/torture/rpc/testjoin.c
@@ -59,6 +59,7 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle user_handle;
uint32_t rid;
struct samr_LookupNames n;
+ struct samr_Ids rids, types;
struct lsa_String sname;
struct samr_OpenUser r;
@@ -67,10 +68,12 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
n.in.domain_handle = handle;
n.in.num_names = 1;
n.in.names = &sname;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
if (NT_STATUS_IS_OK(status)) {
- rid = n.out.rids.ids[0];
+ rid = n.out.rids->ids[0];
} else {
return status;
}
@@ -113,7 +116,9 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
struct samr_CreateUser2 r;
struct samr_OpenDomain o;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
struct samr_SetUserInfo s;
union samr_UserInfo u;
struct policy_handle handle;
@@ -172,6 +177,7 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
name.string = domain;
l.in.connect_handle = &handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(join->p, join, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -179,14 +185,14 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
goto failed;
}
- talloc_steal(join, l.out.sid);
- join->dom_sid = l.out.sid;
+ talloc_steal(join, *l.out.sid);
+ join->dom_sid = *l.out.sid;
join->dom_netbios_name = talloc_strdup(join, domain);
if (!join->dom_netbios_name) goto failed;
o.in.connect_handle = &handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = &domain_handle;
status = dcerpc_samr_OpenDomain(join->p, join, &o);
@@ -224,10 +230,11 @@ again:
join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);
pwp.in.user_handle = &join->user_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
random_pw = generate_random_str(join, MAX(8, policy_min_pw_len));
diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c
index 48a2a4d882..a50a0fe473 100644
--- a/source4/winbind/wb_async_helpers.c
+++ b/source4/winbind/wb_async_helpers.c
@@ -325,6 +325,8 @@ struct samr_getuserdomgroups_state {
int num_rids;
uint32_t *rids;
+ struct samr_RidWithAttributeArray *rid_array;
+
struct policy_handle *user_handle;
struct samr_OpenUser o;
struct samr_GetGroupsForUser g;
@@ -386,6 +388,7 @@ static void samr_usergroups_recv_open(struct rpc_request *req)
if (!composite_is_ok(state->ctx)) return;
state->g.in.user_handle = state->user_handle;
+ state->g.out.rids = &state->rid_array;
req = dcerpc_samr_GetGroupsForUser_send(state->samr_pipe, state,
&state->g);
@@ -438,7 +441,7 @@ NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx,
NTSTATUS status = composite_wait(ctx);
if (!NT_STATUS_IS_OK(status)) goto done;
- *num_rids = state->g.out.rids->count;
+ *num_rids = state->rid_array->count;
*rids = talloc_array(mem_ctx, uint32_t, *num_rids);
if (*rids == NULL) {
status = NT_STATUS_NO_MEMORY;
@@ -446,7 +449,7 @@ NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx,
}
for (i=0; i<*num_rids; i++) {
- (*rids)[i] = state->g.out.rids->rids[i].rid;
+ (*rids)[i] = state->rid_array->rids[i].rid;
}
done: