/* Notice: Definition of "dsdb_control_password_change_status" moved into
* "samdb.h" */
+static int msg_find_old_and_new_pwd_val(const struct ldb_message *msg,
+ const char *name,
+ enum ldb_request_type operation,
+ const struct ldb_val **new_val,
+ const struct ldb_val **old_val);
+
struct ph_context {
struct ldb_module *module;
struct ldb_request *req;
static int setup_last_set_field(struct setup_password_fields_io *io)
{
+ struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
const struct ldb_message *msg = NULL;
+ const struct ldb_val *o = NULL;
+ const struct ldb_val *n = NULL;
+ struct ldb_val _n;
+ int64_t val = -1;
+ int ret;
switch (io->ac->req->operation) {
case LDB_ADD:
return LDB_SUCCESS;
}
- /* set it as now */
- unix_to_nt_time(&io->g.last_set, time(NULL));
+ /*
+ * We can't use ldb_msg_find_attr_as_int64(),
+ * we have to use msg_find_old_and_new_pwd_val()
+ */
+ ret = msg_find_old_and_new_pwd_val(msg, "pwdLastSet",
+ io->ac->req->operation,
+ &n, &o);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ /*
+ * NULL => -1
+ * "0" => 0
+ * "-1" => -1
+ *
+ * everything else is invalid
+ */
+ if (n == NULL) {
+ _n = data_blob_string_const("-1");
+ n = &_n;
+ }
+
+ if (n->data == NULL) {
+ _n = data_blob_string_const("");
+ n = &_n;
+ }
+
+ if (strncmp("-1", (const char *)n->data, n->length) != 0) {
+ val = -1;
+ } else if (strncmp("0", (const char *)n->data, n->length) != 0) {
+ val = 0;
+ } else {
+ val = 1; /* invalid */
+ }
+
+ /*
+ * only 0 or -1 are allowed
+ *
+ * -1 means set the current time.
+ */
+ if (val == -1) {
+ unix_to_nt_time(&io->g.last_set, time(NULL));
+ } else if (val == 0) {
+ io->g.last_set = 0;
+ } else {
+ ret = LDB_ERR_OTHER;
+ ldb_asprintf_errstring(ldb,
+ "%08X: %s - setup_last_set_field: pwdLastSet must be 0 or -1 only!",
+ W_ERROR_V(WERR_INVALID_PARAM),
+ ldb_strerror(ret));
+ return ret;
+ }
return LDB_SUCCESS;
}
struct ldb_context *ldb;
struct ph_context *ac;
struct ldb_message_element *userPasswordAttr, *clearTextPasswordAttr,
- *ntAttr, *lmAttr;
+ *ntAttr, *lmAttr, *pwdLastSetAttr;
int ret;
struct ldb_control *bypass = NULL;
bool userPassword = dsdb_user_password_support(module, req, req);
clearTextPasswordAttr = ldb_msg_find_element(req->op.add.message, "clearTextPassword");
ntAttr = ldb_msg_find_element(req->op.add.message, "unicodePwd");
lmAttr = ldb_msg_find_element(req->op.add.message, "dBCSPwd");
+ pwdLastSetAttr = ldb_msg_find_element(req->op.add.message, "pwdLastSet");
- if ((!userPasswordAttr) && (!clearTextPasswordAttr) && (!ntAttr) && (!lmAttr)) {
+ if ((!userPasswordAttr) && (!clearTextPasswordAttr) &&
+ (!ntAttr) && (!lmAttr) && (!pwdLastSetAttr))
+ {
return ldb_next_request(module, req);
}
struct ldb_context *ldb;
struct ph_context *ac;
const char *passwordAttrs[] = { "userPassword", "clearTextPassword",
- "unicodePwd", "dBCSPwd", NULL }, **l;
+ "unicodePwd", "dBCSPwd", "pwdLastSet", NULL }, **l;
unsigned int attr_cnt, del_attr_cnt, add_attr_cnt, rep_attr_cnt;
struct ldb_message_element *passwordAttr;
struct ldb_message *msg;