diff options
Diffstat (limited to 'source4/libnet')
-rw-r--r-- | source4/libnet/composite.h | 5 | ||||
-rw-r--r-- | source4/libnet/userman.c | 129 |
2 files changed, 94 insertions, 40 deletions
diff --git a/source4/libnet/composite.h b/source4/libnet/composite.h index 256590bc5b..169b65f215 100644 --- a/source4/libnet/composite.h +++ b/source4/libnet/composite.h @@ -62,9 +62,12 @@ struct libnet_rpc_userdel { #define USERMOD_FIELD_ACCOUNT_NAME ( 0x00000001 ) #define USERMOD_FIELD_FULL_NAME ( 0x00000002 ) #define USERMOD_FIELD_DESCRIPTION ( 0x00000010 ) +#define USERMOD_FIELD_COMMENT ( 0x00000020 ) #define USERMOD_FIELD_LOGON_SCRIPT ( 0x00000100 ) #define USERMOD_FIELD_PROFILE_PATH ( 0x00000200 ) #define USERMOD_FIELD_ACCT_EXPIRY ( 0x00004000 ) +#define USERMOD_FIELD_ALLOW_PASS_CHG ( 0x00008000 ) +#define USERMOD_FIELD_ACCT_FLAGS ( 0x00100000 ) struct libnet_rpc_usermod { struct { @@ -77,9 +80,11 @@ struct libnet_rpc_usermod { const char *account_name; const char *full_name; const char *description; + const char *comment; const char *logon_script; const char *profile_path; struct timeval *acct_expiry; + struct timeval *allow_password_change; } change; } in; }; diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c index 6bb0ad4939..f57b5c55f9 100644 --- a/source4/libnet/userman.c +++ b/source4/libnet/userman.c @@ -449,19 +449,20 @@ NTSTATUS libnet_rpc_userdel(struct dcerpc_pipe *pipe, static void usermod_handler(struct rpc_request*); -enum usermod_stage { USERMOD_LOOKUP, USERMOD_OPEN, USERMOD_MODIFY }; +enum usermod_stage { USERMOD_LOOKUP, USERMOD_OPEN, USERMOD_QUERY, USERMOD_MODIFY }; struct usermod_state { - enum usermod_stage stage; - struct dcerpc_pipe *pipe; - 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; - struct samr_SetUserInfo setuser; + enum usermod_stage stage; + struct dcerpc_pipe *pipe; + 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; + struct samr_SetUserInfo setuser; + struct samr_QueryUserInfo queryuser; }; @@ -500,75 +501,120 @@ static NTSTATUS usermod_lookup(struct composite_context *c, } -/** - * Stage 2: Open user account - */ -static NTSTATUS usermod_open(struct composite_context *c, - struct usermod_state *s) +static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level, + union samr_UserInfo *i) { - 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; - - /* Prepare UserInfo level and data based on bitmask field */ if (s->change.fields) { if (s->change.fields & USERMOD_FIELD_ACCOUNT_NAME) { - level = 7; + *level = 7; 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; + *level = 8; i->info8.full_name.string = s->change.full_name; s->change.fields ^= USERMOD_FIELD_FULL_NAME; } else if (s->change.fields & USERMOD_FIELD_DESCRIPTION) { - level = 13; + *level = 13; i->info13.description.string = s->change.description; s->change.fields ^= USERMOD_FIELD_DESCRIPTION; + } else if (s->change.fields & USERMOD_FIELD_COMMENT) { + *level = 2; + + if (s->stage == USERMOD_QUERY) { + /* the user info is obtained, so now set the required field */ + i->info2.comment.string = s->change.comment; + s->change.fields ^= USERMOD_FIELD_COMMENT; + + } else { + /* we need to query the user info before setting one field in it */ + s->stage = USERMOD_QUERY; + return s->change.fields; + } + + } else if (s->change.fields & USERMOD_FIELD_ALLOW_PASS_CHG) { + *level = 3; + + if (s->stage == USERMOD_QUERY) { + i->info3.allow_password_change = timeval_to_nttime(s->change.allow_password_change); + s->change.fields ^= USERMOD_FIELD_ALLOW_PASS_CHG; + + } else { + s->stage = USERMOD_QUERY; + } + } else if (s->change.fields & USERMOD_FIELD_LOGON_SCRIPT) { - level = 11; + *level = 11; i->info11.logon_script.string = s->change.logon_script; s->change.fields ^= USERMOD_FIELD_LOGON_SCRIPT; } else if (s->change.fields & USERMOD_FIELD_PROFILE_PATH) { - level = 12; + *level = 12; i->info12.profile_path.string = s->change.profile_path; s->change.fields ^= USERMOD_FIELD_PROFILE_PATH; } else if (s->change.fields & USERMOD_FIELD_ACCT_EXPIRY) { - level = 17; + *level = 17; i->info17.acct_expiry = timeval_to_nttime(s->change.acct_expiry); s->change.fields ^= USERMOD_FIELD_ACCT_EXPIRY; } } - 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; - - /* Get back here again unless all fields have been set */ + /* We're going to be back here again soon unless all fields have been set */ if (s->change.fields) { s->stage = USERMOD_OPEN; } else { s->stage = USERMOD_MODIFY; } + return s->change.fields; +} + + +/** + * Stage 2: Open user account + */ +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); + + if (s->stage == USERMOD_QUERY) { + s->info = *s->queryuser.out.info; + } + + /* Prepare UserInfo level and data based on bitmask field */ + s->change.fields = usermod_setfields(s, &level, i); + + if (s->stage == USERMOD_QUERY) { + s->queryuser.in.user_handle = &s->user_handle; + s->queryuser.in.level = level; + + s->req = dcerpc_samr_QueryUserInfo_send(s->pipe, c, &s->queryuser); + + } else { + s->setuser.in.user_handle = &s->user_handle; + 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; + return NT_STATUS_OK; } @@ -605,9 +651,12 @@ static void usermod_handler(struct rpc_request *req) case USERMOD_LOOKUP: c->status = usermod_lookup(c, s); break; + case USERMOD_OPEN: + case USERMOD_QUERY: c->status = usermod_open(c, s); break; + case USERMOD_MODIFY: c->status = usermod_modify(c, s); break; |