Avoid the use of extensibleObject in ldap mapping backend.
[kai/samba.git] / source / dsdb / common / util.c
index ba8841ceb06e2e5b9f66e05c80243ff2a60f4e72..a571ae1f793e9150647faa6dc143ad323936a7ee 100644 (file)
 */
 
 #include "includes.h"
+#include "events.h"
 #include "ldb.h"
 #include "ldb_errors.h"
 #include "lib/util/util_ldb.h"
 #include "dsdb/samdb/samdb.h"
 #include "libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_security.h"
+#include "librpc/gen_ndr/ndr_misc.h"
 #include "dsdb/common/flags.h"
 #include "dsdb/common/proto.h"
 #include "libcli/ldap/ldap_ndr.h"
@@ -433,6 +435,29 @@ NTTIME samdb_result_nttime(struct ldb_message *msg, const char *attr, NTTIME def
        return ldb_msg_find_attr_as_uint64(msg, attr, default_value);
 }
 
+/*
+ * Windows uses both 0 and 9223372036854775807 (0x7FFFFFFFFFFFFFFFULL) to
+ * indicate an account doesn't expire.
+ *
+ * When Windows initially creates an account, it sets
+ * accountExpires = 9223372036854775807 (0x7FFFFFFFFFFFFFFF).  However,
+ * when changing from an account having a specific expiration date to
+ * that account never expiring, it sets accountExpires = 0.
+ *
+ * Consolidate that logic here to allow clearer logic for account expiry in
+ * the rest of the code.
+ */
+NTTIME samdb_result_account_expires(struct ldb_message *msg)
+{
+       NTTIME ret = ldb_msg_find_attr_as_uint64(msg, "accountExpires",
+                                                0);
+
+       if (ret == 0)
+               ret = 0x7FFFFFFFFFFFFFFFULL;
+
+       return ret;
+}
+
 /*
   pull a uint64_t from a result set. 
 */
@@ -478,7 +503,7 @@ NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb,
                                          struct ldb_message *msg)
 {
        uint64_t attr_time = samdb_result_uint64(msg, "pwdLastSet", 0);
-       uint32_t userAccountcontrol = samdb_result_uint64(msg, "userAccountControl", 0);
+       uint32_t userAccountControl = samdb_result_uint64(msg, "userAccountControl", 0);
        int64_t maxPwdAge;
 
        /* Machine accounts don't expire, and there is a flag for 'no expiry' */
@@ -493,7 +518,7 @@ NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb,
 
        maxPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn, "maxPwdAge", NULL);
        if (maxPwdAge == 0) {
-               return 0;
+               return 0x7FFFFFFFFFFFFFFFULL;
        } else {
                attr_time -= maxPwdAge;
        }
@@ -980,7 +1005,13 @@ struct ldb_dn *samdb_sites_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx)
 const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
 {
        TALLOC_CTX *tmp_ctx;
-       struct dom_sid *domain_sid;
+       const struct dom_sid *domain_sid;
+       const char *attrs[] = {
+               "objectSid",
+               NULL
+       };
+       struct ldb_result *res;
+       int ret;
 
        /* see if we have a cached copy */
        domain_sid = (struct dom_sid *)ldb_get_opaque(ldb, "cache.domain_sid");
@@ -993,15 +1024,23 @@ const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
                goto failed;
        }
 
-       /* find the domain_sid */
-       domain_sid = samdb_search_dom_sid(ldb, tmp_ctx, ldb_get_default_basedn(ldb),
-                                         "objectSid", "objectClass=domainDNS");
+       ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, attrs, "objectSid=*");
+
+       if (ret != LDB_SUCCESS) {
+               goto failed;
+       }
+       
+       if (res->count != 1) {
+               goto failed;
+       }
+
+       domain_sid = samdb_result_dom_sid(tmp_ctx, res->msgs[0], "objectSid");
        if (domain_sid == NULL) {
                goto failed;
        }
 
        /* cache the domain_sid in the ldb */
-       if (ldb_set_opaque(ldb, "cache.domain_sid", domain_sid) != LDB_SUCCESS) {
+       if (ldb_set_opaque(ldb, "cache.domain_sid", discard_const_p(struct dom_sid, domain_sid)) != LDB_SUCCESS) {
                goto failed;
        }
 
@@ -1440,7 +1479,7 @@ int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
        
        while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
                ret = ldb_search(ldb, sdn, LDB_SCOPE_BASE, 
-                                "(|(objectClass=domain)(objectClass=builtinDomain))", attrs, &res);
+                                "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))", attrs, &res);
                if (ret == LDB_SUCCESS) {
                        talloc_steal(local_ctx, res);
                        if (res->count == 1) {
@@ -1493,7 +1532,7 @@ static bool samdb_password_complexity_ok(const char *pass)
 
   The caller should probably have a transaction wrapping this
 */
-_PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
+NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
                            struct ldb_dn *user_dn,
                            struct ldb_dn *domain_dn,
                            struct ldb_message *mod,
@@ -1733,7 +1772,7 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
   and actually performs the password change
 
 */
-_PUBLIC_ NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
+NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
                                const struct dom_sid *user_sid,
                                const char *new_pass,
                                struct samr_Password *lmNewHash,