s4:dsdb: fix samdb_result_logon_hours() and don't hardcode units_per_week
[metze/samba/wip.git] / source4 / dsdb / common / util.c
index a63c4204cc6879f61467ba421a3b0421529b1799..63870278ceb3f75029723458d6dac6c0bc71c085 100644 (file)
@@ -630,18 +630,25 @@ NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct loadparm_context *lp
 struct samr_LogonHours samdb_result_logon_hours(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr)
 {
        struct samr_LogonHours hours;
-       const int units_per_week = 168;
+       size_t units_per_week = 168;
        const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
+
        ZERO_STRUCT(hours);
-       hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
+
+       if (val) {
+               units_per_week = val->length * 8;
+       }
+
+       hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week/8);
        if (!hours.bits) {
                return hours;
        }
        hours.units_per_week = units_per_week;
-       memset(hours.bits, 0xFF, units_per_week);
+       memset(hours.bits, 0xFF, units_per_week/8);
        if (val) {
-               memcpy(hours.bits, val->data, MIN(val->length, units_per_week));
+               memcpy(hours.bits, val->data, val->length);
        }
+
        return hours;
 }
 
@@ -1994,6 +2001,18 @@ NTSTATUS samdb_set_password(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
         }
 
+       if (user_change) {
+               /* a user password change and we've checked already the old
+                * password somewhere else (callers responsability) */
+               ret = ldb_request_add_control(req,
+                                             DSDB_CONTROL_PASSWORD_CHANGE_OLD_PW_CHECKED_OID,
+                                             true, NULL);
+               if (ret != LDB_SUCCESS) {
+                       talloc_free(req);
+                       talloc_free(msg);
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
        ret = ldb_request_add_control(req,
                                      DSDB_CONTROL_PASSWORD_HASH_VALUES_OID,
                                      true, NULL);
@@ -2693,11 +2712,39 @@ int samdb_is_rodc(struct ldb_context *sam_ctx, const struct GUID *objectGUID, bo
 int samdb_rodc(struct ldb_context *sam_ctx, bool *am_rodc)
 {
        const struct GUID *objectGUID;
+       int ret;
+       bool *cached;
+
+       /* see if we have a cached copy */
+       cached = (bool *)ldb_get_opaque(sam_ctx, "cache.am_rodc");
+       if (cached) {
+               *am_rodc = *cached;
+               return LDB_SUCCESS;
+       }
+
        objectGUID = samdb_ntds_objectGUID(sam_ctx);
        if (!objectGUID) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       return samdb_is_rodc(sam_ctx, objectGUID, am_rodc);
+
+       ret = samdb_is_rodc(sam_ctx, objectGUID, am_rodc);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       cached = talloc(sam_ctx, bool);
+       if (cached == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       *cached = *am_rodc;
+
+       ret = ldb_set_opaque(sam_ctx, "cache.am_rodc", cached);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(cached);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       return LDB_SUCCESS;
 }