diff options
-rw-r--r-- | source4/libnet/composite.h | 5 | ||||
-rw-r--r-- | source4/libnet/userman.c | 34 | ||||
-rw-r--r-- | source4/torture/libnet/userman.c | 26 |
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)) { |