summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libnet/userman.c110
1 files changed, 84 insertions, 26 deletions
diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c
index afc093aa83..9faaddb3ff 100644
--- a/source4/libnet/userman.c
+++ b/source4/libnet/userman.c
@@ -557,25 +557,36 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
{
if (s->change.fields == 0) return s->change.fields;
- if (s->change.fields & USERMOD_FIELD_ACCOUNT_NAME) {
+ *level = 0;
+
+ if ((s->change.fields & USERMOD_FIELD_ACCOUNT_NAME) &&
+ (*level == 0 || *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) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_FULL_NAME) &&
+ (*level == 0 || *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) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_DESCRIPTION) &&
+ (*level == 0 || *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) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_COMMENT) &&
+ (*level == 0 || *level == 2)) {
*level = 2;
if (s->stage == USERMOD_QUERY) {
@@ -589,7 +600,10 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
return s->change.fields;
}
- } else if (s->change.fields & USERMOD_FIELD_ALLOW_PASS_CHG) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_ALLOW_PASS_CHG) &&
+ (*level == 0 || *level == 3)) {
*level = 3;
if (s->stage == USERMOD_QUERY) {
@@ -601,7 +615,10 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
return s->change.fields;
}
- } else if (s->change.fields & USERMOD_FIELD_FORCE_PASS_CHG) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_FORCE_PASS_CHG) &&
+ (*level == 0 || *level == 3)) {
*level = 3;
if (s->stage == USERMOD_QUERY) {
@@ -613,7 +630,10 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
return s->change.fields;
}
- } else if (s->change.fields & USERMOD_FIELD_LAST_LOGON) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_LAST_LOGON) &&
+ (*level == 0 || *level == 3)) {
*level = 3;
if (s->stage == USERMOD_QUERY) {
@@ -624,7 +644,10 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
return s->change.fields;
}
- } else if (s->change.fields & USERMOD_FIELD_LAST_LOGOFF) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_LAST_LOGOFF) &&
+ (*level == 0 || *level == 3)) {
*level = 3;
if (s->stage == USERMOD_QUERY) {
@@ -635,7 +658,10 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
return s->change.fields;
}
- } else if (s->change.fields & USERMOD_FIELD_LAST_PASS_CHG) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_LAST_PASS_CHG) &&
+ (*level == 0 || *level == 3)) {
*level = 3;
if (s->stage == USERMOD_QUERY) {
@@ -646,19 +672,28 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
return s->change.fields;
}
- } else if (s->change.fields & USERMOD_FIELD_LOGON_SCRIPT) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_LOGON_SCRIPT) &&
+ (*level == 0 || *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) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_PROFILE_PATH) &&
+ (*level == 0 || *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_HOME_DIRECTORY) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_HOME_DIRECTORY) &&
+ (*level == 0 || *level == 3)) {
*level = 3;
if (s->stage == USERMOD_QUERY) {
@@ -669,7 +704,10 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
return s->change.fields;
}
- } else if (s->change.fields & USERMOD_FIELD_HOME_DRIVE) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_HOME_DRIVE) &&
+ (*level == 0 || *level == 3)) {
*level = 3;
if (s->stage == USERMOD_QUERY) {
@@ -680,13 +718,19 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
return s->change.fields;
}
- } else if (s->change.fields & USERMOD_FIELD_ACCT_EXPIRY) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_ACCT_EXPIRY) &&
+ (*level == 0 || *level == 17)) {
*level = 17;
i->info17.acct_expiry = timeval_to_nttime(s->change.acct_expiry);
s->change.fields ^= USERMOD_FIELD_ACCT_EXPIRY;
- } else if (s->change.fields & USERMOD_FIELD_ACCT_FLAGS) {
+ }
+
+ if ((s->change.fields & USERMOD_FIELD_ACCT_FLAGS) &&
+ (*level == 0 || *level == 16)) {
*level = 16;
i->info16.acct_flags = s->change.acct_flags;
@@ -704,24 +748,19 @@ static uint32_t usermod_setfields(struct usermod_state *s, uint16_t *level,
}
-/**
- * Stage 2: Open user account
- */
-static NTSTATUS usermod_open(struct composite_context *c,
- struct usermod_state *s)
+static NTSTATUS usermod_change(struct composite_context *c,
+ struct usermod_state *s)
{
union samr_UserInfo *i = &s->info;
+
/* set the level to invalid value, so that unless setfields routine
gives it a valid value we report the error correctly */
uint16_t level = 27;
- c->status = dcerpc_ndr_request_recv(s->req);
- NT_STATUS_NOT_OK_RETURN(c->status);
-
/* prepare UserInfo level and data based on bitmask field */
s->change.fields = usermod_setfields(s, &level, i);
- if (level > 26) {
+ if (level < 1 || level > 26) {
/* apparently there's a field that the setfields routine
does not know how to set */
c->state = COMPOSITE_STATE_ERROR;
@@ -759,6 +798,19 @@ static NTSTATUS usermod_open(struct composite_context *c,
/**
+ * Stage 2: Open user account
+ */
+static NTSTATUS usermod_open(struct composite_context *c,
+ struct usermod_state *s)
+{
+ c->status = dcerpc_ndr_request_recv(s->req);
+ NT_STATUS_NOT_OK_RETURN(c->status);
+
+ return usermod_change(c, s);
+}
+
+
+/**
* Stage 2a (optional): Query the user information
*/
static NTSTATUS usermod_query(struct composite_context *c,
@@ -803,7 +855,13 @@ static NTSTATUS usermod_modify(struct composite_context *c,
c->status = dcerpc_ndr_request_recv(s->req);
NT_STATUS_NOT_OK_RETURN(c->status);
- c->state = COMPOSITE_STATE_DONE;
+ if (s->change.fields == 0) {
+ /* all fields have been set - we're done */
+ c->state = COMPOSITE_STATE_DONE;
+ } else {
+ /* something's still not changed - repeat the procedure */
+ return usermod_change(c, s);
+ }
return NT_STATUS_OK;
}