r25446: Merge some changes I made on the way home from SFO:
[jelmer/samba4-debian.git] / source / dsdb / samdb / samdb.c
index 19c6ed773d3e77e7dd4548d9dc7a9a075929f28f..2f755d6c791fb21b8678f37ba6cfd4262440add5 100644 (file)
@@ -9,7 +9,7 @@
 
    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 2 of the License, or
+   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,
@@ -18,8 +18,7 @@
    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, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -36,6 +35,7 @@
 #include "db_wrap.h"
 #include "dsdb/samdb/samdb.h"
 #include "dsdb/common/flags.h"
+#include "param/param.h"
 
 /*
   connect to the SAM database
@@ -45,11 +45,13 @@ struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx,
                                  struct auth_session_info *session_info)
 {
        struct ldb_context *ldb;
-       ldb = ldb_wrap_connect(mem_ctx, lp_sam_url(), session_info,
+       ldb = ldb_wrap_connect(mem_ctx, global_loadparm, 
+                              lp_sam_url(global_loadparm), session_info,
                               NULL, 0, NULL);
        if (!ldb) {
                return NULL;
        }
+       dsdb_make_schema_global(ldb);
        return ldb;
 }
 
@@ -449,9 +451,7 @@ struct dom_sid *samdb_result_sid_prefix(TALLOC_CTX *mem_ctx, const struct ldb_me
 */
 NTTIME samdb_result_nttime(struct ldb_message *msg, const char *attr, NTTIME default_value)
 {
-       const char *str = ldb_msg_find_attr_as_string(msg, attr, NULL);
-       if (!str) return default_value;
-       return nttime_from_string(str);
+       return ldb_msg_find_attr_as_uint64(msg, attr, default_value);
 }
 
 /*
@@ -571,7 +571,7 @@ NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
        struct samr_Password *lmPwdHash, *ntPwdHash;
        if (nt_pwd) {
                int num_nt;
-               num_nt = samdb_result_hashes(mem_ctx, msg, "ntPwdHash", &ntPwdHash);
+               num_nt = samdb_result_hashes(mem_ctx, msg, "unicodePwd", &ntPwdHash);
                if (num_nt == 0) {
                        *nt_pwd = NULL;
                } else if (num_nt > 1) {
@@ -582,7 +582,7 @@ 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, "lmPwdHash", &lmPwdHash);
+               num_lm = samdb_result_hashes(mem_ctx, msg, "dBCSPwd", &lmPwdHash);
                if (num_lm == 0) {
                        *lm_pwd = NULL;
                } else if (num_lm > 1) {
@@ -626,23 +626,24 @@ uint16_t samdb_result_acct_flags(struct ldb_message *msg, const char *attr)
 
 
 /* Find an attribute, with a particular value */
+
+/* The current callers of this function expect a very specific
+ * behaviour: In particular, objectClass subclass equivilance is not
+ * wanted.  This means that we should not lookup the schema for the
+ * comparison function */
 struct ldb_message_element *samdb_find_attribute(struct ldb_context *ldb, 
                                                 const struct ldb_message *msg, 
                                                 const char *name, const char *value)
 {
        int i;
        struct ldb_message_element *el = ldb_msg_find_element(msg, name);
-       struct ldb_val v;
-
-       v.data = discard_const_p(uint8_t, value);
-       v.length = strlen(value);
 
        if (!el) {
                return NULL;
        }
 
        for (i=0;i<el->num_values;i++) {
-               if (strcasecmp(value, (char *)el->values[i].data) == 0) {
+               if (ldb_attr_cmp(value, (char *)el->values[i].data) == 0) {
                        return el;
                }
        }
@@ -675,7 +676,7 @@ int samdb_find_or_add_attribute(struct ldb_context *ldb, struct ldb_message *msg
   copy from a template record to a message
 */
 int samdb_copy_template(struct ldb_context *ldb, 
-                       struct ldb_message *msg, const char *filter,
+                       struct ldb_message *msg, const char *name,
                        const char **errstring)
 {
        struct ldb_result *res;
@@ -685,15 +686,22 @@ int samdb_copy_template(struct ldb_context *ldb,
 
        *errstring = NULL;      
 
+       if (!ldb_dn_add_child_fmt(basedn, "CN=Template%s", name)) {
+               *errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: Failed to contruct DN for template '%s'", 
+                                            name);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       
        /* pull the template record */
-       ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE, filter, NULL, &res);
+       ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, "cn=*", NULL, &res);
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                *errstring = talloc_steal(msg, ldb_errstring(ldb));
                return ret;
        }
        if (res->count != 1) {
-               *errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: template '%s' matched %d records, expected 1\n", filter, 
+               *errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: template '%s' matched %d records, expected 1", 
+                                            name, 
                                             res->count);
                talloc_free(res);
                return LDB_ERR_OPERATIONS_ERROR;
@@ -703,40 +711,22 @@ int samdb_copy_template(struct ldb_context *ldb,
        for (i = 0; i < t->num_elements; i++) {
                struct ldb_message_element *el = &t->elements[i];
                /* some elements should not be copied from the template */
-               if (strcasecmp(el->name, "cn") == 0 ||
-                   strcasecmp(el->name, "name") == 0 ||
-                   strcasecmp(el->name, "sAMAccountName") == 0 ||
-                   strcasecmp(el->name, "sAMAccountName") == 0 ||
-                   strcasecmp(el->name, "distinguishedName") == 0 ||
-                   strcasecmp(el->name, "objectGUID") == 0) {
+               if (ldb_attr_cmp(el->name, "cn") == 0 ||
+                   ldb_attr_cmp(el->name, "name") == 0 ||
+                   ldb_attr_cmp(el->name, "objectClass") == 0 ||
+                   ldb_attr_cmp(el->name, "sAMAccountName") == 0 ||
+                   ldb_attr_cmp(el->name, "sAMAccountName") == 0 ||
+                   ldb_attr_cmp(el->name, "distinguishedName") == 0 ||
+                   ldb_attr_cmp(el->name, "objectGUID") == 0) {
                        continue;
                }
                for (j = 0; j < el->num_values; j++) {
-                       if (strcasecmp(el->name, "objectClass") == 0) {
-                               if (strcasecmp((char *)el->values[j].data, "Template") == 0 ||
-                                   strcasecmp((char *)el->values[j].data, "userTemplate") == 0 ||
-                                   strcasecmp((char *)el->values[j].data, "groupTemplate") == 0 ||
-                                   strcasecmp((char *)el->values[j].data, "foreignSecurityPrincipalTemplate") == 0 ||
-                                   strcasecmp((char *)el->values[j].data, "aliasTemplate") == 0 || 
-                                   strcasecmp((char *)el->values[j].data, "trustedDomainTemplate") == 0 || 
-                                   strcasecmp((char *)el->values[j].data, "secretTemplate") == 0) {
-                                       continue;
-                               }
-                               ret = samdb_find_or_add_value(ldb, msg, el->name, 
-                                                             (char *)el->values[j].data);
-                               if (ret) {
-                                       *errstring = talloc_asprintf(msg, "Adding objectClass %s failed.\n", el->values[j].data);
-                                       talloc_free(res);
-                                       return ret;
-                               }
-                       } else {
-                               ret = samdb_find_or_add_attribute(ldb, msg, el->name, 
-                                                                 (char *)el->values[j].data);
-                               if (ret) {
-                                       *errstring = talloc_asprintf(msg, "Adding attribute %s failed.\n", el->name);
-                                       talloc_free(res);
-                                       return ret;
-                               }
+                       ret = samdb_find_or_add_attribute(ldb, msg, el->name, 
+                                                         (char *)el->values[j].data);
+                       if (ret) {
+                               *errstring = talloc_asprintf(msg, "Adding attribute %s failed.", el->name);
+                               talloc_free(res);
+                               return ret;
                        }
                }
        }
@@ -1078,7 +1068,7 @@ const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
        struct dom_sid *domain_sid;
 
        /* see if we have a cached copy */
-       domain_sid = ldb_get_opaque(ldb, "cache.domain_sid");
+       domain_sid = (struct dom_sid *)ldb_get_opaque(ldb, "cache.domain_sid");
        if (domain_sid) {
                return domain_sid;
        }
@@ -1136,7 +1126,7 @@ const char *samdb_result_fsmo_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
 /*
   work out the ntds settings dn for the current open ldb
 */
-const struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
+struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
 {
        TALLOC_CTX *tmp_ctx;
        const char *root_attrs[] = { "dsServiceName", NULL };
@@ -1145,7 +1135,7 @@ const struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
        struct ldb_dn *settings_dn;
        
        /* see if we have a cached copy */
-       settings_dn = ldb_get_opaque(ldb, "cache.settings_dn");
+       settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "cache.settings_dn");
        if (settings_dn) {
                return settings_dn;
        }
@@ -1158,8 +1148,11 @@ const struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
 
        ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, ""), LDB_SCOPE_BASE, NULL, root_attrs, &root_res);
        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;
@@ -1183,6 +1176,193 @@ failed:
        return NULL;
 }
 
+/*
+  work out the ntds settings invocationId for the current open ldb
+*/
+const struct GUID *samdb_ntds_invocation_id(struct ldb_context *ldb)
+{
+       TALLOC_CTX *tmp_ctx;
+       const char *attrs[] = { "invocationId", NULL };
+       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) {
+               return invocation_id;
+       }
+
+       tmp_ctx = talloc_new(ldb);
+       if (tmp_ctx == NULL) {
+               goto failed;
+       }
+
+       ret = ldb_search(ldb, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, NULL, attrs, &res);
+       if (ret) {
+               goto failed;
+       }
+       talloc_steal(tmp_ctx, res);
+
+       if (res->count != 1) {
+               goto failed;
+       }
+
+       invocation_id = talloc(tmp_ctx, struct GUID);
+       if (!invocation_id) {
+               goto failed;
+       }
+
+       *invocation_id = samdb_result_guid(res->msgs[0], "invocationId");
+
+       /* cache the domain_sid in the ldb */
+       if (ldb_set_opaque(ldb, "cache.invocation_id", invocation_id) != LDB_SUCCESS) {
+               goto failed;
+       }
+
+       talloc_steal(ldb, invocation_id);
+       talloc_free(tmp_ctx);
+
+       return invocation_id;
+
+failed:
+       DEBUG(1,("Failed to find our own NTDS Settings invocationId in the ldb!\n"));
+       talloc_free(tmp_ctx);
+       return NULL;
+}
+
+bool samdb_set_ntds_invocation_id(struct ldb_context *ldb, const struct GUID *invocation_id_in)
+{
+       TALLOC_CTX *tmp_ctx;
+       struct GUID *invocation_id_new;
+       struct GUID *invocation_id_old;
+
+       /* see if we have a cached copy */
+       invocation_id_old = (struct GUID *)ldb_get_opaque(ldb, 
+                                                        "cache.invocation_id");
+
+       tmp_ctx = talloc_new(ldb);
+       if (tmp_ctx == NULL) {
+               goto failed;
+       }
+
+       invocation_id_new = talloc(tmp_ctx, struct GUID);
+       if (!invocation_id_new) {
+               goto failed;
+       }
+
+       *invocation_id_new = *invocation_id_in;
+
+       /* cache the domain_sid in the ldb */
+       if (ldb_set_opaque(ldb, "cache.invocation_id", invocation_id_new) != LDB_SUCCESS) {
+               goto failed;
+       }
+
+       talloc_steal(ldb, invocation_id_new);
+       talloc_free(tmp_ctx);
+       talloc_free(invocation_id_old);
+
+       return true;
+
+failed:
+       DEBUG(1,("Failed to set our own cached invocationId in the ldb!\n"));
+       talloc_free(tmp_ctx);
+       return false;
+}
+
+/*
+  work out the ntds settings objectGUID for the current open ldb
+*/
+const struct GUID *samdb_ntds_objectGUID(struct ldb_context *ldb)
+{
+       TALLOC_CTX *tmp_ctx;
+       const char *attrs[] = { "objectGUID", NULL };
+       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) {
+               return ntds_guid;
+       }
+
+       tmp_ctx = talloc_new(ldb);
+       if (tmp_ctx == NULL) {
+               goto failed;
+       }
+
+       ret = ldb_search(ldb, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, NULL, attrs, &res);
+       if (ret) {
+               goto failed;
+       }
+       talloc_steal(tmp_ctx, res);
+
+       if (res->count != 1) {
+               goto failed;
+       }
+
+       ntds_guid = talloc(tmp_ctx, struct GUID);
+       if (!ntds_guid) {
+               goto failed;
+       }
+
+       *ntds_guid = samdb_result_guid(res->msgs[0], "objectGUID");
+
+       /* cache the domain_sid in the ldb */
+       if (ldb_set_opaque(ldb, "cache.ntds_guid", ntds_guid) != LDB_SUCCESS) {
+               goto failed;
+       }
+
+       talloc_steal(ldb, ntds_guid);
+       talloc_free(tmp_ctx);
+
+       return ntds_guid;
+
+failed:
+       DEBUG(1,("Failed to find our own NTDS Settings objectGUID in the ldb!\n"));
+       talloc_free(tmp_ctx);
+       return NULL;
+}
+
+bool samdb_set_ntds_objectGUID(struct ldb_context *ldb, const struct GUID *ntds_guid_in)
+{
+       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");
+
+       tmp_ctx = talloc_new(ldb);
+       if (tmp_ctx == NULL) {
+               goto failed;
+       }
+
+       ntds_guid_new = talloc(tmp_ctx, struct GUID);
+       if (!ntds_guid_new) {
+               goto failed;
+       }
+
+       *ntds_guid_new = *ntds_guid_in;
+
+       /* cache the domain_sid in the ldb */
+       if (ldb_set_opaque(ldb, "cache.ntds_guid", ntds_guid_new) != LDB_SUCCESS) {
+               goto failed;
+       }
+
+       talloc_steal(ldb, ntds_guid_new);
+       talloc_free(tmp_ctx);
+       talloc_free(ntds_guid_old);
+
+       return true;
+
+failed:
+       DEBUG(1,("Failed to set our own cached invocationId in the ldb!\n"));
+       talloc_free(tmp_ctx);
+       return false;
+}
+
 /*
   work out the server dn for the current open ldb
 */
@@ -1191,6 +1371,23 @@ struct ldb_dn *samdb_server_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
        return ldb_dn_get_parent(mem_ctx, samdb_ntds_settings_dn(ldb));
 }
 
+/*
+  work out the server dn for the current open ldb
+*/
+struct ldb_dn *samdb_server_site_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
+{
+       struct ldb_dn *server_dn;
+       struct ldb_dn *server_site_dn;
+
+       server_dn = samdb_server_dn(ldb, mem_ctx);
+       if (!server_dn) return NULL;
+
+       server_site_dn = ldb_dn_get_parent(mem_ctx, server_dn);
+
+       talloc_free(server_dn);
+       return server_site_dn;
+}
+
 /*
   work out if we are the PDC for the domain of the current open ldb
 */
@@ -1205,11 +1402,15 @@ BOOL samdb_is_pdc(struct ldb_context *ldb)
 
        tmp_ctx = talloc_new(ldb);
        if (tmp_ctx == NULL) {
-               goto failed;
+               DEBUG(1, ("talloc_new failed in samdb_is_pdc"));
+               return False;
        }
 
        ret = ldb_search(ldb, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
        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);
@@ -1300,13 +1501,12 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
                            struct samr_Password *lmNewHash, 
                            struct samr_Password *ntNewHash,
                            BOOL user_change,
-                           BOOL restrictions,
                            enum samr_RejectReason *reject_reason,
                            struct samr_DomInfo1 **_dominfo)
 {
-       const char * const user_attrs[] = { "userAccountControl", "sambaLMPwdHistory", 
-                                           "sambaNTPwdHistory", 
-                                           "lmPwdHash", "ntPwdHash", 
+       const char * const user_attrs[] = { "userAccountControl", "lmPwdHistory", 
+                                           "ntPwdHistory", 
+                                           "dBCSPwd", "unicodePwd", 
                                            "objectSid", 
                                            "pwdLastSet", NULL };
        const char * const domain_attrs[] = { "pwdProperties", "pwdHistoryLength", 
@@ -1321,6 +1521,7 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
        int sambaLMPwdHistory_len, sambaNTPwdHistory_len;
        struct dom_sid *domain_sid;
        struct ldb_message **res;
+       BOOL restrictions;
        int count;
        time_t now = time(NULL);
        NTTIME now_nt;
@@ -1336,13 +1537,20 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
        }
        userAccountControl = samdb_result_uint(res[0],   "userAccountControl", 0);
        sambaLMPwdHistory_len =   samdb_result_hashes(mem_ctx, res[0], 
-                                                "sambaLMPwdHistory", &sambaLMPwdHistory);
+                                                "lmPwdHistory", &sambaLMPwdHistory);
        sambaNTPwdHistory_len =   samdb_result_hashes(mem_ctx, res[0], 
-                                                "sambaNTPwdHistory", &sambaNTPwdHistory);
-       lmPwdHash =          samdb_result_hash(mem_ctx, res[0],   "lmPwdHash");
-       ntPwdHash =          samdb_result_hash(mem_ctx, res[0],   "ntPwdHash");
+                                                "ntPwdHistory", &sambaNTPwdHistory);
+       lmPwdHash =          samdb_result_hash(mem_ctx, res[0],   "dBCSPwd");
+       ntPwdHash =          samdb_result_hash(mem_ctx, res[0],   "unicodePwd");
        pwdLastSet =         samdb_result_uint64(res[0], "pwdLastSet", 0);
 
+       /* Only non-trust accounts have restrictions (possibly this
+        * test is the wrong way around, but I like to be restrictive
+        * if possible */
+       restrictions = !(userAccountControl & (UF_INTERDOMAIN_TRUST_ACCOUNT
+                                              |UF_WORKSTATION_TRUST_ACCOUNT
+                                              |UF_SERVER_TRUST_ACCOUNT)); 
+
        if (domain_dn) {
                /* pull the domain parameters */
                count = gendb_search_dn(ctx, mem_ctx, domain_dn, &res, domain_attrs);
@@ -1390,7 +1598,8 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
                *_dominfo = dominfo;
        }
 
-       if (new_pass) {
+       if (restrictions && new_pass) {
+
                /* check the various password restrictions */
                if (restrictions && minPwdLength > strlen_m(new_pass)) {
                        if (reject_reason) {
@@ -1422,7 +1631,7 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
                ntNewHash = &local_ntNewHash;
        }
 
-       if (restrictions && user_change) {
+       if (user_change) {
                /* are all password changes disallowed? */
                if (pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
                        if (reject_reason) {
@@ -1500,15 +1709,15 @@ _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ct
                CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "sambaPassword"));
 
                if (lmNewHash) {
-                       CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "lmPwdHash", lmNewHash));
+                       CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "dBCSPwd", lmNewHash));
                } else {
-                       CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "lmPwdHash"));
+                       CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "dBCSPwd"));
                }
                
                if (ntNewHash) {
-                       CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "ntPwdHash", ntNewHash));
+                       CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "unicodePwd", ntNewHash));
                } else {
-                       CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "ntPwdHash"));
+                       CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "unicodePwd"));
                }
        }
 
@@ -1530,7 +1739,6 @@ _PUBLIC_ NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *me
                                struct samr_Password *lmNewHash, 
                                struct samr_Password *ntNewHash,
                                BOOL user_change,
-                               BOOL restrictions,
                                enum samr_RejectReason *reject_reason,
                                struct samr_DomInfo1 **_dominfo) 
 {
@@ -1572,7 +1780,6 @@ _PUBLIC_ NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *me
                                       msg, new_pass, 
                                       lmNewHash, ntNewHash,
                                       user_change, /* This is a password set, not change */
-                                      restrictions, /* run restriction tests */
                                       reject_reason, _dominfo);
        if (!NT_STATUS_IS_OK(nt_status)) {
                ldb_transaction_cancel(ctx);