summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libnet/composite.h5
-rw-r--r--source4/libnet/userman.c34
-rw-r--r--source4/torture/libnet/userman.c26
3 files changed, 56 insertions, 9 deletions
diff --git a/source4/libnet/composite.h b/source4/libnet/composite.h
index 62ad46ee81..70e70d04ee 100644
--- a/source4/libnet/composite.h
+++ b/source4/libnet/composite.h
@@ -59,12 +59,15 @@ struct libnet_rpc_userdel {
};
+#define USERMOD_FIELD_ACCOUNT_NAME ( 0x00000001 )
+#define USERMOD_FIELD_FULL_NAME ( 0x00000002 )
+
struct libnet_rpc_usermod {
struct {
struct policy_handle domain_handle;
const char *username;
- struct usermod {
+ struct usermod_change {
uint32_t fields; /* bitmask field */
const char *account_name;
diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c
index 4d021506bb..37b3d1e723 100644
--- a/source4/libnet/userman.c
+++ b/source4/libnet/userman.c
@@ -428,6 +428,7 @@ struct usermod_state {
struct rpc_request *req;
struct policy_handle domain_handle;
struct policy_handle user_handle;
+ struct usermod_change change;
union samr_UserInfo info;
struct samr_LookupNames lookupname;
struct samr_OpenUser openuser;
@@ -471,21 +472,47 @@ static NTSTATUS usermod_open(struct composite_context *c,
struct usermod_state *s)
{
union samr_UserInfo *i = &s->info;
+ uint16_t level;
c->status = dcerpc_ndr_request_recv(s->req);
NT_STATUS_NOT_OK_RETURN(c->status);
s->setuser.in.user_handle = &s->user_handle;
- /* TODO: decide about the level of UserInfo */
- s->setuser.in.level = 1;
+ /* Prepare UserInfo level and data based on bitmask field */
+ if (s->change.fields) {
+ if (s->change.fields & USERMOD_FIELD_ACCOUNT_NAME) {
+ level = 7;
+ i->info7.account_name.length = 2*strlen_m(s->change.account_name);
+ i->info7.account_name.size = 2*strlen_m(s->change.account_name);
+ i->info7.account_name.string = s->change.account_name;
+
+ s->change.fields ^= USERMOD_FIELD_ACCOUNT_NAME;
+
+ } else if (s->change.fields & USERMOD_FIELD_FULL_NAME) {
+ level = 8;
+ i->info8.full_name.length = 2*strlen_m(s->change.full_name);
+ i->info8.full_name.size = 2*strlen_m(s->change.full_name);
+ i->info8.full_name.string = s->change.full_name;
+
+ s->change.fields ^= USERMOD_FIELD_FULL_NAME;
+ }
+ }
+
+ s->setuser.in.level = level;
s->setuser.in.info = i;
s->req = dcerpc_samr_SetUserInfo_send(s->pipe, c, &s->setuser);
s->req->async.callback = usermod_handler;
s->req->async.private = c;
- s->stage = USERMOD_MODIFY;
+
+ /* Get back here again unless all fields have been set */
+ if (s->change.fields) {
+ s->stage = USERMOD_OPEN;
+ } else {
+ s->stage = USERMOD_MODIFY;
+ }
return NT_STATUS_OK;
}
@@ -554,6 +581,7 @@ struct composite_context *libnet_rpc_usermod_send(struct dcerpc_pipe *p,
s->pipe = p;
s->domain_handle = io->in.domain_handle;
+ s->change = io->in.change;
s->lookupname.in.domain_handle = &io->in.domain_handle;
s->lookupname.in.num_names = 1;
diff --git a/source4/torture/libnet/userman.c b/source4/torture/libnet/userman.c
index 0b499a2bd9..ed07cf019a 100644
--- a/source4/torture/libnet/userman.c
+++ b/source4/torture/libnet/userman.c
@@ -272,13 +272,17 @@ static BOOL test_userdel(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
static BOOL test_usermod(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle *handle, const char *username)
+ struct policy_handle *handle, const char *username,
+ struct usermod_change *change)
{
NTSTATUS status;
struct libnet_rpc_usermod user;
user.in.domain_handle = *handle;
user.in.username = username;
+ user.in.change = *change;
+
+ printf("modifying user\n");
status = libnet_rpc_usermod(p, mem_ctx, &user);
if (!NT_STATUS_IS_OK(status)) {
@@ -404,10 +408,16 @@ BOOL torture_usermod(void)
struct dcerpc_pipe *p;
struct policy_handle h;
struct lsa_String domain_name;
- const char *name = TEST_USERNAME;
+ char *name = TEST_USERNAME;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
+ int i;
+ struct usermod_change changes[] = {
+ { USERMOD_FIELD_ACCOUNT_NAME, "changed", NULL },
+ { USERMOD_FIELD_FULL_NAME, NULL, "Testing full account name" }
+ };
+
mem_ctx = talloc_init("test_userdel");
binding = lp_parm_string(-1, "torture", "binding");
@@ -433,9 +443,15 @@ BOOL torture_usermod(void)
goto done;
}
- if (!test_usermod(p, mem_ctx, &h, name)) {
- ret = False;
- goto done;
+ for (i = 0; i < (sizeof(changes)/sizeof(struct usermod_change)); i++) {
+ if (!test_usermod(p, mem_ctx, &h, name, &changes[i])) {
+ ret = False;
+ goto done;
+ }
+
+ if (changes[i].fields & USERMOD_FIELD_ACCOUNT_NAME) {
+ name = talloc_strdup(mem_ctx, changes[i].account_name);
+ }
}
if (!test_cleanup(p, mem_ctx, &h, name)) {