Make up the right dependencies now that ldb depends on libevents
[metze/samba/wip.git] / source / dsdb / common / util.c
index c9c0285604d705cb36583ba67af7953d07160609..b98112304c9549b71bf766003a3c45871af07c08 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. 
 */
@@ -469,8 +494,8 @@ NTTIME samdb_result_allow_password_change(struct ldb_context *sam_ldb,
 }
 
 /*
-  construct the force_password_change field from the PwdLastSet attribute and the 
-  domain password settings
+  construct the force_password_change field from the PwdLastSet
+  attribute, the userAccountControl and the domain password settings
 */
 NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb, 
                                          TALLOC_CTX *mem_ctx, 
@@ -478,10 +503,12 @@ 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 user_flags = samdb_result_uint64(msg, "userAccountControl", 0);
+       uint32_t userAccountControl = samdb_result_uint64(msg, "userAccountControl", 0);
        int64_t maxPwdAge;
 
-       if (user_flags & UF_DONT_EXPIRE_PASSWD) {
+       /* Machine accounts don't expire, and there is a flag for 'no expiry' */
+       if (!(userAccountControl & UF_NORMAL_ACCOUNT)
+           || (userAccountControl & UF_DONT_EXPIRE_PASSWD)) {
                return 0x7FFFFFFFFFFFFFFFULL;
        }
 
@@ -491,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;
        }
@@ -607,24 +634,17 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
 {
        uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
        uint32_t acct_flags = samdb_uf2acb(userAccountControl); 
-       if ((userAccountControl & UF_NORMAL_ACCOUNT) && !(userAccountControl & UF_DONT_EXPIRE_PASSWD)) {
-               NTTIME must_change_time;
-               NTTIME pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0);
-               if (pwdLastSet == 0) {
-                       acct_flags |= ACB_PW_EXPIRED;
-               } else {
-                       NTTIME now;
-                       
-                       must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, 
-                                                                             domain_dn, msg);
-                       
-                       /* Test account expire time */
-                       unix_to_nt_time(&now, time(NULL));
-                       /* check for expired password */
-                       if ((must_change_time != 0) && (must_change_time < now)) {
-                               acct_flags |= ACB_PW_EXPIRED;
-                       }
-               }
+       NTTIME must_change_time;
+       NTTIME now;
+       
+       must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, 
+                                                             domain_dn, msg);
+       
+       /* Test account expire time */
+       unix_to_nt_time(&now, time(NULL));
+       /* check for expired password */
+       if (must_change_time < now) {
+               acct_flags |= ACB_PW_EXPIRED;
        }
        return acct_flags;
 }
@@ -985,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");
@@ -998,9 +1024,17 @@ 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;
        }
@@ -1445,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) {
@@ -1498,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,
@@ -1738,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,