Add const
[ira/wip.git] / source4 / dsdb / common / util.c
index ba8841ceb06e2e5b9f66e05c80243ff2a60f4e72..cbae2ec24cb84e3c140f829bae216f1f738e951b 100644 (file)
@@ -6,28 +6,31 @@
    Copyright (C) Volker Lendecke 2004
    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006
    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "events/events.h"
 #include "ldb.h"
 #include "ldb_errors.h"
-#include "lib/util/util_ldb.h"
+#include "../lib/util/util_ldb.h"
+#include "../lib/crypto/crypto.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"
@@ -103,7 +106,6 @@ const char *samdb_search_string_v(struct ldb_context *sam_ldb,
 
        return samdb_result_string(res[0], attr_name, NULL);
 }
-                                
 
 /*
   search the sam for a single string attribute in exactly 1 record
@@ -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;
        }
@@ -504,7 +529,7 @@ NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb,
 /*
   pull a samr_Password structutre from a result set. 
 */
-struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr)
+struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, const struct ldb_message *msg, const char *attr)
 {
        struct samr_Password *hash = NULL;
        const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
@@ -518,7 +543,7 @@ struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, struct ldb_message
 /*
   pull an array of samr_Password structutres from a result set. 
 */
-uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg, 
+uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, const struct ldb_message *msg, 
                           const char *attr, struct samr_Password **hashes)
 {
        uint_t count = 0;
@@ -546,7 +571,7 @@ uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
        return count;
 }
 
-NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg, 
+NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ldb_message *msg, 
                                struct samr_Password **lm_pwd, struct samr_Password **nt_pwd) 
 {
        struct samr_Password *lmPwdHash, *ntPwdHash;
@@ -562,14 +587,21 @@ NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
                }
        }
        if (lm_pwd) {
-               int num_lm;
-               num_lm = samdb_result_hashes(mem_ctx, msg, "dBCSPwd", &lmPwdHash);
-               if (num_lm == 0) {
-                       *lm_pwd = NULL;
-               } else if (num_lm > 1) {
-                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
+               /* Ensure that if we have turned off LM
+                * authentication, that we never use the LM hash, even
+                * if we store it */
+               if (lp_lanman_auth(lp_ctx)) {
+                       int num_lm;
+                       num_lm = samdb_result_hashes(mem_ctx, msg, "dBCSPwd", &lmPwdHash);
+                       if (num_lm == 0) {
+                               *lm_pwd = NULL;
+                       } else if (num_lm > 1) {
+                               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+                       } else {
+                               *lm_pwd = &lmPwdHash[0];
+                       }
                } else {
-                       *lm_pwd = &lmPwdHash[0];
+                       *lm_pwd = NULL;
                }
        }
        return NT_STATUS_OK;
@@ -611,10 +643,10 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
        uint32_t acct_flags = samdb_uf2acb(userAccountControl); 
        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 */
@@ -624,6 +656,28 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
        return acct_flags;
 }
 
+struct lsa_BinaryString samdb_result_parameters(TALLOC_CTX *mem_ctx,
+                                               struct ldb_message *msg,
+                                               const char *attr)
+{
+       struct lsa_BinaryString s;
+       const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
+
+       ZERO_STRUCT(s);
+
+       if (!val) {
+               return s;
+       }
+
+       s.array = talloc_array(mem_ctx, uint16_t, val->length/2);
+       if (!s.array) {
+               return s;
+       }
+       s.length = s.size = val->length/2;
+       memcpy(s.array, val->data, val->length);
+
+       return s;
+}
 
 /* Find an attribute, with a particular value */
 
@@ -667,7 +721,7 @@ int samdb_find_or_add_attribute(struct ldb_context *ldb, struct ldb_message *msg
        if (el) {
                return LDB_SUCCESS;
        }
-               
+
        return samdb_msg_add_string(ldb, msg, msg, name, set_value);
 }
 
@@ -863,6 +917,17 @@ int samdb_msg_add_logon_hours(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
        return ldb_msg_add_value(msg, attr_name, &val, NULL);
 }
 
+/*
+  add a parameters element to a message
+*/
+int samdb_msg_add_parameters(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+                            const char *attr_name, struct lsa_BinaryString *parameters)
+{
+       struct ldb_val val;
+       val.length = parameters->length * 2;
+       val.data = (uint8_t *)parameters->array;
+       return ldb_msg_add_value(msg, attr_name, &val, NULL);
+}
 /*
   add a general value element to a message
 */
@@ -980,7 +1045,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 +1064,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(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;
        }
 
@@ -1085,7 +1164,7 @@ struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
        int ret;
        struct ldb_result *root_res;
        struct ldb_dn *settings_dn;
-       
+
        /* see if we have a cached copy */
        settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "cache.settings_dn");
        if (settings_dn) {
@@ -1096,15 +1175,13 @@ struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
        if (tmp_ctx == NULL) {
                goto failed;
        }
-       
 
-       ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, ""), LDB_SCOPE_BASE, NULL, root_attrs, &root_res);
+       ret = ldb_search(ldb, tmp_ctx, &root_res, ldb_dn_new(tmp_ctx, ldb, ""), LDB_SCOPE_BASE, root_attrs, NULL);
        if (ret) {
                DEBUG(1,("Searching for dsServiceName in rootDSE failed: %s\n", 
                         ldb_errstring(ldb)));
                goto failed;
        }
-       talloc_steal(tmp_ctx, root_res);
 
        if (root_res->count != 1) {
                goto failed;
@@ -1138,7 +1215,7 @@ const struct GUID *samdb_ntds_invocation_id(struct ldb_context *ldb)
        int ret;
        struct ldb_result *res;
        struct GUID *invocation_id;
-       
+
        /* see if we have a cached copy */
        invocation_id = (struct GUID *)ldb_get_opaque(ldb, "cache.invocation_id");
        if (invocation_id) {
@@ -1150,11 +1227,10 @@ const struct GUID *samdb_ntds_invocation_id(struct ldb_context *ldb)
                goto failed;
        }
 
-       ret = ldb_search(ldb, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, NULL, attrs, &res);
+       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
        if (ret) {
                goto failed;
        }
-       talloc_steal(tmp_ctx, res);
 
        if (res->count != 1) {
                goto failed;
@@ -1232,7 +1308,7 @@ const struct GUID *samdb_ntds_objectGUID(struct ldb_context *ldb)
        int ret;
        struct ldb_result *res;
        struct GUID *ntds_guid;
-       
+
        /* see if we have a cached copy */
        ntds_guid = (struct GUID *)ldb_get_opaque(ldb, "cache.ntds_guid");
        if (ntds_guid) {
@@ -1244,11 +1320,10 @@ const struct GUID *samdb_ntds_objectGUID(struct ldb_context *ldb)
                goto failed;
        }
 
-       ret = ldb_search(ldb, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, NULL, attrs, &res);
+       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
        if (ret) {
                goto failed;
        }
-       talloc_steal(tmp_ctx, res);
 
        if (res->count != 1) {
                goto failed;
@@ -1282,7 +1357,7 @@ bool samdb_set_ntds_objectGUID(struct ldb_context *ldb, const struct GUID *ntds_
        TALLOC_CTX *tmp_ctx;
        struct GUID *ntds_guid_new;
        struct GUID *ntds_guid_old;
-       
+
        /* see if we have a cached copy */
        ntds_guid_old = (struct GUID *)ldb_get_opaque(ldb, "cache.ntds_guid");
 
@@ -1358,14 +1433,13 @@ bool samdb_is_pdc(struct ldb_context *ldb)
                return false;
        }
 
-       ret = ldb_search(ldb, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
+       ret = ldb_search(ldb, tmp_ctx, &dom_res, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, dom_attrs, NULL);
        if (ret) {
                DEBUG(1,("Searching for fSMORoleOwner in %s failed: %s\n", 
                         ldb_dn_get_linearized(ldb_get_default_basedn(ldb)), 
                         ldb_errstring(ldb)));
                goto failed;
        }
-       talloc_steal(tmp_ctx, dom_res);
        if (dom_res->count != 1) {
                goto failed;
        }
@@ -1405,17 +1479,17 @@ bool samdb_is_gc(struct ldb_context *ldb)
        }
 
        /* Query cn=ntds settings,.... */
-       ret = ldb_search(ldb, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, NULL, attrs, &res);
+       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
        if (ret) {
+               talloc_free(tmp_ctx);
                return false;
        }
        if (res->count != 1) {
-               talloc_free(res);
+               talloc_free(tmp_ctx);
                return false;
        }
 
        options = ldb_msg_find_attr_as_int(res->msgs[0], "options", 0);
-       talloc_free(res);
        talloc_free(tmp_ctx);
 
        /* if options attribute has the 0x00000001 flag set, then enable the global catlog */
@@ -1437,12 +1511,11 @@ int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
 
        local_ctx = talloc_new(mem_ctx);
        if (local_ctx == NULL) return LDB_ERR_OPERATIONS_ERROR;
-       
+
        while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
-               ret = ldb_search(ldb, sdn, LDB_SCOPE_BASE, 
-                                "(|(objectClass=domain)(objectClass=builtinDomain))", attrs, &res);
+               ret = ldb_search(ldb, local_ctx, &res, sdn, LDB_SCOPE_BASE, attrs,
+                                "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
                if (ret == LDB_SUCCESS) {
-                       talloc_steal(local_ctx, res);
                        if (res->count == 1) {
                                break;
                        }
@@ -1493,11 +1566,11 @@ 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,
-                           const char *new_pass,
+                           const DATA_BLOB *new_password,
                            struct samr_Password *lmNewHash, 
                            struct samr_Password *ntNewHash,
                            bool user_change,
@@ -1583,6 +1656,11 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
        minPwdLength =     samdb_result_uint(res[0],   "minPwdLength", 0);
        minPwdAge =        samdb_result_int64(res[0],  "minPwdAge", 0);
 
+       if (userAccountControl & UF_PASSWD_NOTREQD) {
+               /* see [MS-ADTS] 2.2.15 */
+               minPwdLength = 0;
+       }
+
        if (_dominfo) {
                struct samr_DomInfo1 *dominfo;
                /* on failure we need to fill in the reject reasons */
@@ -1598,40 +1676,45 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
                *_dominfo = dominfo;
        }
 
-       if (restrictions && new_pass) {
+       if (restrictions && new_password) {
+               char *new_pass;
 
                /* check the various password restrictions */
-               if (restrictions && minPwdLength > strlen_m(new_pass)) {
+               if (restrictions && minPwdLength > utf16_len_n(new_password->data, new_password->length) / 2) {
                        if (reject_reason) {
                                *reject_reason = SAMR_REJECT_TOO_SHORT;
                        }
                        return NT_STATUS_PASSWORD_RESTRICTION;
                }
-               
-               /* possibly check password complexity */
-               if (restrictions && pwdProperties & DOMAIN_PASSWORD_COMPLEX &&
-                   !samdb_password_complexity_ok(new_pass)) {
-                       if (reject_reason) {
-                               *reject_reason = SAMR_REJECT_COMPLEXITY;
+
+               /* Create the NT hash */
+               mdfour(local_ntNewHash.hash, new_password->data, new_password->length);
+
+               ntNewHash = &local_ntNewHash;
+
+               /* Only check complexity if we can convert it at all.  Assuming unconvertable passwords are 'strong' */
+               if (convert_string_talloc_convenience(mem_ctx, lp_iconv_convenience(ldb_get_opaque(ctx, "loadparm")), 
+                                         CH_UTF16, CH_UNIX, 
+                                         new_password->data, new_password->length, 
+                                         (void **)&new_pass, NULL, false)) {
+
+                       /* possibly check password complexity */
+                       if (restrictions && (pwdProperties & DOMAIN_PASSWORD_COMPLEX) &&
+                           !samdb_password_complexity_ok(new_pass)) {
+                               if (reject_reason) {
+                                       *reject_reason = SAMR_REJECT_COMPLEXITY;
+                               }
+                               return NT_STATUS_PASSWORD_RESTRICTION;
                        }
-                       return NT_STATUS_PASSWORD_RESTRICTION;
-               }
-               
-               /* compute the new nt and lm hashes */
-               if (E_deshash(new_pass, local_lmNewHash.hash)) {
-                       lmNewHash = &local_lmNewHash;
-               }
-               if (!E_md4hash(new_pass, local_ntNewHash.hash)) {
-                       /* If we can't convert this password to UCS2, then we should not accept it */
-                       if (reject_reason) {
-                               *reject_reason = SAMR_REJECT_OTHER;
+
+                       /* compute the new lm hashes (for checking history - case insenitivly!) */
+                       if (E_deshash(new_pass, local_lmNewHash.hash)) {
+                               lmNewHash = &local_lmNewHash;
                        }
-                       return NT_STATUS_PASSWORD_RESTRICTION;
                }
-               ntNewHash = &local_ntNewHash;
        }
 
-       if (user_change) {
+       if (restrictions && user_change) {
                /* are all password changes disallowed? */
                if (pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
                        if (reject_reason) {
@@ -1639,7 +1722,7 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
                        }
                        return NT_STATUS_PASSWORD_RESTRICTION;
                }
-               
+
                /* can this user change password? */
                if (userAccountControl & UF_PASSWD_CANT_CHANGE) {
                        if (reject_reason) {
@@ -1647,7 +1730,7 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
                        }
                        return NT_STATUS_PASSWORD_RESTRICTION;
                }
-               
+
                /* yes, this is a minus. The ages are in negative 100nsec units! */
                if (pwdLastSet - minPwdAge > now_nt) {
                        if (reject_reason) {
@@ -1671,11 +1754,11 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
                                return NT_STATUS_PASSWORD_RESTRICTION;
                        }
                }
-               
+
                /* check the password history */
                sambaLMPwdHistory_len = MIN(sambaLMPwdHistory_len, pwdHistoryLength);
                sambaNTPwdHistory_len = MIN(sambaNTPwdHistory_len, pwdHistoryLength);
-               
+
                for (i=0; lmNewHash && i<sambaLMPwdHistory_len;i++) {
                        if (memcmp(lmNewHash->hash, sambaLMPwdHistory[i].hash, 16) == 0) {
                                if (reject_reason) {
@@ -1697,23 +1780,22 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
 #define CHECK_RET(x) do { if (x != 0) return NT_STATUS_NO_MEMORY; } while(0)
 
        /* the password is acceptable. Start forming the new fields */
-       if (new_pass) {
-               /* if we know the cleartext, then only set it.
+       if (new_password) {
+               /* if we know the cleartext UTF16 password, then set it.
                 * Modules in ldb will set all the appropriate
                 * hashes */
-               CHECK_RET(samdb_msg_add_string(ctx, mem_ctx, mod, 
-                                              "sambaPassword", new_pass));
+               CHECK_RET(ldb_msg_add_value(mod, "clearTextPassword", new_password, NULL));
        } else {
                /* We don't have the cleartext, so delete the old one
                 * and set what we have of the hashes */
-               CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "sambaPassword"));
+               CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "clearTextPassword"));
 
                if (lmNewHash) {
                        CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "dBCSPwd", lmNewHash));
                } else {
                        CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "dBCSPwd"));
                }
-               
+
                if (ntNewHash) {
                        CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "unicodePwd", ntNewHash));
                } else {
@@ -1733,9 +1815,9 @@ _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,
+                               const DATA_BLOB *new_pass,
                                struct samr_Password *lmNewHash, 
                                struct samr_Password *ntNewHash,
                                bool user_change,
@@ -1785,7 +1867,7 @@ _PUBLIC_ NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *me
                ldb_transaction_cancel(ctx);
                return nt_status;
        }
-       
+
        /* modify the samdb record */
        ret = samdb_replace(ctx, mem_ctx, msg);
        if (ret != 0) {
@@ -1812,42 +1894,42 @@ NTSTATUS samdb_create_foreign_security_principal(struct ldb_context *sam_ctx, TA
        struct ldb_dn *basedn;
        const char *sidstr;
        int ret;
-       
+
        sidstr = dom_sid_string(mem_ctx, sid);
        NT_STATUS_HAVE_NO_MEMORY(sidstr);
-       
+
        /* We might have to create a ForeignSecurityPrincipal, even if this user
         * is in our own domain */
-       
+
        msg = ldb_msg_new(mem_ctx);
        if (msg == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
-       
+
        /* TODO: Hmmm. This feels wrong. How do I find the base dn to
         * put the ForeignSecurityPrincipals? d_state->domain_dn does
         * not work, this is wrong for the Builtin domain, there's no
         * cn=For...,cn=Builtin,dc={BASEDN}.  -- vl
         */
-       
+
        basedn = samdb_search_dn(sam_ctx, mem_ctx, NULL,
                                 "(&(objectClass=container)(cn=ForeignSecurityPrincipals))");
-       
+
        if (basedn == NULL) {
                DEBUG(0, ("Failed to find DN for "
                          "ForeignSecurityPrincipal container\n"));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
-       
+
        /* add core elements to the ldb_message for the alias */
        msg->dn = ldb_dn_copy(mem_ctx, basedn);
        if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s", sidstr))
                return NT_STATUS_NO_MEMORY;
-       
+
        samdb_msg_add_string(sam_ctx, mem_ctx, msg,
                             "objectClass",
                             "foreignSecurityPrincipal");
-       
+
        /* create the alias */
        ret = ldb_add(sam_ctx, msg);
        if (ret != 0) {
@@ -1873,12 +1955,12 @@ struct ldb_dn *samdb_dns_domain_to_dn(struct ldb_context *ldb, TALLOC_CTX *mem_c
        const char *binary_encoded;
        const char **split_realm;
        struct ldb_dn *dn;
-       
+
        if (!tmp_ctx) {
                return NULL;
        }
-       
-       split_realm = str_list_make(tmp_ctx, dns_domain, ".");
+
+       split_realm = (const char **)str_list_make(tmp_ctx, dns_domain, ".");
        if (!split_realm) {
                talloc_free(tmp_ctx);
                return NULL;
@@ -1916,7 +1998,7 @@ struct ldb_dn *samdb_domain_to_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
        struct ldb_result *res_domain_ref;
        char *escaped_domain = ldb_binary_encode_string(mem_ctx, domain_name);
        /* find the domain's DN */
-       int ret_domain = ldb_search_exp_fmt(ldb, mem_ctx, 
+       int ret_domain = ldb_search(ldb, mem_ctx,
                                            &res_domain_ref, 
                                            samdb_partitions_dn(ldb, mem_ctx), 
                                            LDB_SCOPE_ONELEVEL, 
@@ -1926,9 +2008,9 @@ struct ldb_dn *samdb_domain_to_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
        if (ret_domain != 0) {
                return NULL;
        }
-       
+
        if (res_domain_ref->count == 0) {
-               ret_domain = ldb_search_exp_fmt(ldb, mem_ctx, 
+               ret_domain = ldb_search(ldb, mem_ctx,
                                                &res_domain_ref, 
                                                samdb_dns_domain_to_dn(ldb, mem_ctx, domain_name),
                                                LDB_SCOPE_BASE,
@@ -1937,19 +2019,19 @@ struct ldb_dn *samdb_domain_to_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
                if (ret_domain != 0) {
                        return NULL;
                }
-       
+
                if (res_domain_ref->count == 1) {
                        return res_domain_ref->msgs[0]->dn;
                }
                return NULL;
        }
-       
+
        if (res_domain_ref->count > 1) {
                DEBUG(0,("Found %d records matching domain [%s]\n", 
                         ret_domain, domain_name));
                return NULL;
        }
-       
+
        return samdb_result_dn(ldb, mem_ctx, res_domain_ref->msgs[0], "nCName", NULL);
 
 }