Fix a warning about a shadowed variable by renaming the shadowing var
[obnox/samba/samba-obnox.git] / source4 / libnet / libnet_samsync_ldb.c
index 3c34aca94428b67d00cc5312788b8331be6c0fb8..10e5a34da462591816decb0066678542173a8218 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,
    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"
 #include "libnet/libnet.h"
-#include "libcli/ldap/ldap.h"
+#include "libcli/ldap/ldap_ndr.h"
 #include "dsdb/samdb/samdb.h"
 #include "auth/auth.h"
+#include "../lib/util/util_ldb.h"
 #include "librpc/gen_ndr/ndr_misc.h"
-#include "db_wrap.h"
+#include "ldb_wrap.h"
 #include "libcli/security/security.h"
-#include "librpc/rpc/dcerpc.h"
+#include "param/param.h"
 
 struct samsync_ldb_secret {
        struct samsync_ldb_secret *prev, *next;
@@ -51,12 +51,20 @@ struct samsync_ldb_state {
        const struct libnet_SamSync_state *samsync_state;
 
        struct dom_sid *dom_sid[3];
-       struct ldb_context *sam_ldb, *remote_ldb;
+       struct ldb_context *sam_ldb, *remote_ldb, *pdb;
        struct ldb_dn *base_dn[3];
        struct samsync_ldb_secret *secrets;
        struct samsync_ldb_trusted_domain *trusted_domains;
 };
 
+/* This wrapper is needed for the "ADD_OR_DEL" macros */
+static int samdb_msg_add_string(struct ldb_context *sam_ldb,
+                               TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+                               const char *attr_name, const char *str)
+{
+       return ldb_msg_add_string(msg, attr_name, str);
+}
+
 static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
                                                         struct samsync_ldb_state *state,
                                                         struct dom_sid *sid,
@@ -79,7 +87,7 @@ static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
                *error_string = talloc_asprintf(mem_ctx, 
                                                "Failed to find DN for "
                                                "ForeignSecurityPrincipal container under %s",
-                                               ldb_dn_linearize(mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN]));
+                                               ldb_dn_get_linearized(state->base_dn[SAM_DATABASE_DOMAIN]));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
        
@@ -93,18 +101,16 @@ static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
        if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s", sidstr))
                return NT_STATUS_UNSUCCESSFUL;
        
-       samdb_msg_add_string(state->sam_ldb, mem_ctx, msg,
-                            "objectClass",
-                            "foreignSecurityPrincipal");
+       ldb_msg_add_string(msg, "objectClass", "foreignSecurityPrincipal");
 
        *fsp_dn = msg->dn;
 
        /* create the alias */
-       ret = samdb_add(state->sam_ldb, mem_ctx, msg);
-       if (ret != 0) {
+       ret = ldb_add(state->sam_ldb, msg);
+       if (ret != LDB_SUCCESS) {
                *error_string = talloc_asprintf(mem_ctx, "Failed to create foreignSecurityPrincipal "
                                                "record %s: %s",
-                                               ldb_dn_linearize(mem_ctx, msg->dn),
+                                               ldb_dn_get_linearized(msg->dn),
                                                ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -155,26 +161,37 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
                        /* Update the domain sid with the incoming
                         * domain (found on LSA pipe, database sid may
                         * be random) */
-                       samdb_msg_add_dom_sid(state->sam_ldb, mem_ctx, 
-                                             msg, "objectSid", state->dom_sid[database]);
+                       ret = samdb_msg_add_dom_sid(state->sam_ldb,
+                                                   mem_ctx,
+                                                   msg,
+                                                   "objectSid",
+                                                   state->dom_sid[database]);
+                       if (ret != LDB_SUCCESS) {
+                               return NT_STATUS_INTERNAL_ERROR;
+                       }
                } else {
                        /* Well, we will have to use the one from the database */
                        state->dom_sid[database] = samdb_search_dom_sid(state->sam_ldb, state,
                                                                        state->base_dn[database], 
                                                                        "objectSid", NULL);
+                       if (state->dom_sid[database] == NULL) {
+                               return NT_STATUS_INTERNAL_ERROR;
+                       }
                }
 
                if (state->samsync_state->domain_guid) {
-                       NTSTATUS nt_status;
                        struct ldb_val v;
-                       nt_status = ndr_push_struct_blob(&v, msg, state->samsync_state->domain_guid,
-                                                        (ndr_push_flags_fn_t)ndr_push_GUID);
-                       if (!NT_STATUS_IS_OK(nt_status)) {
+                       NTSTATUS status;
+                       status = GUID_to_ndr_blob(state->samsync_state->domain_guid, msg, &v);
+                       if (!NT_STATUS_IS_OK(status)) {
                                *error_string = talloc_asprintf(mem_ctx, "ndr_push of domain GUID failed!");
-                               return nt_status;
+                               return status;
                        }
                        
-                       ldb_msg_add_value(msg, "objectGUID", &v, NULL);
+                       ret = ldb_msg_add_value(msg, "objectGUID", &v, NULL);
+                       if (ret != LDB_SUCCESS) {
+                               return NT_STATUS_INTERNAL_ERROR;
+                       }
                }
        } else if (database == SAM_DATABASE_BUILTIN) {
                /* work out the builtin_dn - useful for so many calls its worth
@@ -195,8 +212,8 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       samdb_msg_add_string(state->sam_ldb, mem_ctx, 
-                            msg, "oEMInformation", domain->comment.string);
+       ldb_msg_add_string(msg, "oEMInformation",
+                          domain->oem_information.string);
 
        samdb_msg_add_int64(state->sam_ldb, mem_ctx, 
                            msg, "forceLogoff", domain->force_logoff_time);
@@ -222,10 +239,13 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
 
        /* TODO: Account lockout, password properties */
        
-       ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-
-       if (ret) {
-               return NT_STATUS_INTERNAL_ERROR;
+       ret = dsdb_replace(state->sam_ldb, msg, 0);
+       if (ret != LDB_SUCCESS) {
+               *error_string = talloc_asprintf(mem_ctx,
+                                               "Failed to modify domain record %s: %s",
+                                               ldb_dn_get_linearized(msg->dn),
+                                               ldb_errstring(state->sam_ldb));
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
        return NT_STATUS_OK;
 }
@@ -245,9 +265,10 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
        struct ldb_message *msg;
        struct ldb_message **msgs;
        struct ldb_message **remote_msgs = NULL;
-       int ret, i;
+       unsigned int i;
+       int ret;
        uint32_t acb;
-       BOOL add = False;
+       bool add = false;
        const char *attrs[] = { NULL };
        /* we may change this to a global search, then fill in only the things not in ldap later */
        const char *remote_attrs[] = { "userPrincipalName", "servicePrincipalName", 
@@ -275,7 +296,7 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                                                ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        } else if (ret == 0) {
-               add = True;
+               add = true;
        } else if (ret > 1) {
                *error_string = talloc_asprintf(mem_ctx, "More than one user with SID: %s in local LDB", 
                                                dom_sid_string(mem_ctx, user_sid));
@@ -298,7 +319,7 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                } else if (ret == 0) {
                        *error_string = talloc_asprintf(mem_ctx, "User exists in samsync but not in remote LDAP domain! (base: %s, SID: %s)", 
-                                                       ldb_dn_linearize(mem_ctx, state->base_dn[database]),
+                                                       ldb_dn_get_linearized(state->base_dn[database]),
                                                        dom_sid_string(mem_ctx, user_sid));
                        return NT_STATUS_NO_SUCH_USER;
                } else if (ret > 1) {
@@ -308,8 +329,7 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                        
                        /* Try to put things in the same location as the remote server */
                } else if (add) {
-                       msg->dn = remote_msgs[0]->dn;
-                       talloc_steal(msg, remote_msgs[0]->dn);
+                       msg->dn = talloc_steal(msg, remote_msgs[0]->dn);
                }
        }
 
@@ -360,29 +380,27 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY; 
        } 
        
-       if (!add) {
-               /* Passwords.  Ensure there is no plaintext stored against
-                * this entry, as we only have hashes */
-               samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,  
-                                    "sambaPassword"); 
-       }
        if (user->lm_password_present) {
                samdb_msg_add_hash(state->sam_ldb, mem_ctx, msg,  
-                                  "lmPwdHash", &user->lmpassword);
+                                  "dBCSPwd", &user->lmpassword);
        } else if (!add) {
                samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,  
-                                    "lmPwdHash"); 
+                                    "dBCSPwd"); 
        }
        if (user->nt_password_present) {
                samdb_msg_add_hash(state->sam_ldb, mem_ctx, msg,  
-                                  "ntPwdHash", &user->ntpassword);
+                                  "unicodePwd", &user->ntpassword);
        } else if (!add) {
                samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,  
-                                    "ntPwdHash"); 
+                                    "unicodePwd"); 
        }
            
        ADD_OR_DEL(string, "comment", comment.string);
-       ADD_OR_DEL(string, "userParameters", parameters.string);
+
+       if (samdb_msg_add_parameters(state->sam_ldb, mem_ctx, msg, "userParameters", &user->parameters) != 0) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        ADD_OR_DEL(uint, "countryCode", country_code);
        ADD_OR_DEL(uint, "codePage", code_page);
 
@@ -418,8 +436,7 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                obj_class = "user";
        }
        if (add) {
-               samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
-                                    "objectClass", obj_class);
+               ldb_msg_add_string(msg, "objectClass", obj_class);
                if (!msg->dn) {
                        msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
                        ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
@@ -428,25 +445,32 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                        }
                }
 
-               ret = samdb_add(state->sam_ldb, mem_ctx, msg);
-               if (ret != 0) {
+               ret = ldb_add(state->sam_ldb, msg);
+               if (ret != LDB_SUCCESS) {
                        struct ldb_dn *first_try_dn = msg->dn;
                        /* Try again with the default DN */
-                       msg->dn = talloc_steal(msg, msgs[0]->dn);
-                       ret = samdb_add(state->sam_ldb, mem_ctx, msg);
-                       if (ret != 0) {
-                               *error_string = talloc_asprintf(mem_ctx, "Failed to create user record.  Tried both %s and %s: %s",
-                                                               ldb_dn_linearize(mem_ctx, first_try_dn),
-                                                               ldb_dn_linearize(mem_ctx, msg->dn),
+                       if (!remote_msgs) {
+                               *error_string = talloc_asprintf(mem_ctx, "Failed to create user record.  Tried %s: %s",
+                                                               ldb_dn_get_linearized(first_try_dn),
                                                                ldb_errstring(state->sam_ldb));
                                return NT_STATUS_INTERNAL_DB_CORRUPTION;
+                       } else {
+                               msg->dn = talloc_steal(msg, remote_msgs[0]->dn);
+                               ret = ldb_add(state->sam_ldb, msg);
+                               if (ret != LDB_SUCCESS) {
+                                       *error_string = talloc_asprintf(mem_ctx, "Failed to create user record.  Tried both %s and %s: %s",
+                                                                       ldb_dn_get_linearized(first_try_dn),
+                                                                       ldb_dn_get_linearized(msg->dn),
+                                                                       ldb_errstring(state->sam_ldb));
+                                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
+                               }
                        }
                }
        } else {
-               ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-               if (ret != 0) {
+               ret = dsdb_replace(state->sam_ldb, msg, 0);
+               if (ret != LDB_SUCCESS) {
                        *error_string = talloc_asprintf(mem_ctx, "Failed to modify user record %s: %s",
-                                                       ldb_dn_linearize(mem_ctx, msg->dn),
+                                                       ldb_dn_get_linearized(msg->dn),
                                                        ldb_errstring(state->sam_ldb));
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
@@ -485,10 +509,10 @@ static NTSTATUS samsync_ldb_delete_user(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
-       if (ret != 0) {
+       ret = ldb_delete(state->sam_ldb, msgs[0]->dn);
+       if (ret != LDB_SUCCESS) {
                *error_string = talloc_asprintf(mem_ctx, "Failed to delete user record %s: %s",
-                                               ldb_dn_linearize(mem_ctx, msgs[0]->dn),
+                                               ldb_dn_get_linearized(msgs[0]->dn),
                                                ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -510,7 +534,7 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
        struct ldb_message *msg;
        struct ldb_message **msgs;
        int ret;
-       BOOL add = False;
+       bool add = false;
        const char *attrs[] = { NULL };
 
        msg = ldb_msg_new(mem_ctx);
@@ -527,7 +551,7 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
                *error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        } else if (ret == 0) {
-               add = True;
+               add = true;
        } else if (ret > 1) {
                *error_string = talloc_asprintf(mem_ctx, "More than one group/alias with SID: %s", 
                                                dom_sid_string(mem_ctx, 
@@ -566,26 +590,25 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
        obj_class = "group";
 
        if (add) {
-               samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
-                                    "objectClass", obj_class);
+               ldb_msg_add_string(msg, "objectClass", obj_class);
                msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
                ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
                if (!msg->dn) {
                        return NT_STATUS_NO_MEMORY;             
                }
 
-               ret = samdb_add(state->sam_ldb, mem_ctx, msg);
-               if (ret != 0) {
+               ret = ldb_add(state->sam_ldb, msg);
+               if (ret != LDB_SUCCESS) {
                        *error_string = talloc_asprintf(mem_ctx, "Failed to create group record %s: %s",
-                                                       ldb_dn_linearize(mem_ctx, msg->dn),
+                                                       ldb_dn_get_linearized(msg->dn),
                                                        ldb_errstring(state->sam_ldb));
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
        } else {
-               ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-               if (ret != 0) {
+               ret = dsdb_replace(state->sam_ldb, msg, 0);
+               if (ret != LDB_SUCCESS) {
                        *error_string = talloc_asprintf(mem_ctx, "Failed to modify group record %s: %s",
-                                                       ldb_dn_linearize(mem_ctx, msg->dn),
+                                                       ldb_dn_get_linearized(msg->dn),
                                                        ldb_errstring(state->sam_ldb));
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
@@ -624,10 +647,10 @@ static NTSTATUS samsync_ldb_delete_group(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
        
-       ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
-       if (ret != 0) {
+       ret = ldb_delete(state->sam_ldb, msgs[0]->dn);
+       if (ret != LDB_SUCCESS) {
                *error_string = talloc_asprintf(mem_ctx, "Failed to delete group record %s: %s",
-                                               ldb_dn_linearize(mem_ctx, msgs[0]->dn),
+                                               ldb_dn_get_linearized(msgs[0]->dn),
                                                ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -642,12 +665,13 @@ static NTSTATUS samsync_ldb_handle_group_member(TALLOC_CTX *mem_ctx,
                                                char **error_string) 
 {
        uint32_t rid = delta->delta_id_union.rid;
-       struct netr_DELTA_GROUP_MEMBER *group_member = delta->delta_union.group_member;
+       struct netr_DELTA_GROUP_MEMBER *delta_group_member = delta->delta_union.group_member;
        struct ldb_message *msg;
        struct ldb_message **msgs;
        int ret;
        const char *attrs[] = { NULL };
-       int i;
+       const char *str_dn;
+       uint32_t i;
 
        msg = ldb_msg_new(mem_ctx);
        if (msg == NULL) {
@@ -677,11 +701,11 @@ static NTSTATUS samsync_ldb_handle_group_member(TALLOC_CTX *mem_ctx,
        
        talloc_free(msgs);
 
-       for (i=0; i<group_member->num_rids; i++) {
+       for (i=0; i<delta_group_member->num_rids; i++) {
                /* search for the group, by rid */
                ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database], &msgs, attrs,
                                   "(&(objectClass=user)(objectSid=%s))", 
-                                  ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], group_member->rids[i]))); 
+                                  ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], delta_group_member->rids[i])));
                
                if (ret == -1) {
                        *error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));
@@ -691,16 +715,19 @@ static NTSTATUS samsync_ldb_handle_group_member(TALLOC_CTX *mem_ctx,
                } else if (ret > 1) {
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                } else {
-                       samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "member", ldb_dn_linearize(mem_ctx, msgs[0]->dn));
+                       str_dn = ldb_dn_alloc_linearized(msg, msgs[0]->dn);
+                       NT_STATUS_HAVE_NO_MEMORY(str_dn);
+                       ret = ldb_msg_add_string(msg, "member", str_dn);
+                       if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
                }
                
                talloc_free(msgs);
        }
        
-       ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-       if (ret != 0) {
+       ret = dsdb_replace(state->sam_ldb, msg, 0);
+       if (ret != LDB_SUCCESS) {
                *error_string = talloc_asprintf(mem_ctx, "Failed to modify group record %s: %s",
-                                               ldb_dn_linearize(mem_ctx, msg->dn),
+                                               ldb_dn_get_linearized(msg->dn),
                                                ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -722,7 +749,7 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
        struct ldb_message *msg;
        struct ldb_message **msgs;
        int ret;
-       BOOL add = False;
+       bool add = false;
        const char *attrs[] = { NULL };
 
        msg = ldb_msg_new(mem_ctx);
@@ -739,7 +766,7 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
                *error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        } else if (ret == 0) {
-               add = True;
+               add = true;
        } else if (ret > 1) {
                *error_string = talloc_asprintf(mem_ctx, "More than one group/alias with SID: %s", 
                                                dom_sid_string(mem_ctx, 
@@ -780,26 +807,25 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
        obj_class = "group";
 
        if (add) {
-               samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
-                                    "objectClass", obj_class);
+               ldb_msg_add_string(msg, "objectClass", obj_class);
                msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
                ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
                if (!msg->dn) {
                        return NT_STATUS_NO_MEMORY;             
                }
 
-               ret = samdb_add(state->sam_ldb, mem_ctx, msg);
-               if (ret != 0) {
+               ret = ldb_add(state->sam_ldb, msg);
+               if (ret != LDB_SUCCESS) {
                        *error_string = talloc_asprintf(mem_ctx, "Failed to create alias record %s: %s",
-                                                       ldb_dn_linearize(mem_ctx, msg->dn),
+                                                       ldb_dn_get_linearized(msg->dn),
                                                        ldb_errstring(state->sam_ldb));
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
        } else {
-               ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-               if (ret != 0) {
+               ret = dsdb_replace(state->sam_ldb, msg, 0);
+               if (ret != LDB_SUCCESS) {
                        *error_string = talloc_asprintf(mem_ctx, "Failed to modify alias record %s: %s",
-                                                       ldb_dn_linearize(mem_ctx, msg->dn),
+                                                       ldb_dn_get_linearized(msg->dn),
                                                        ldb_errstring(state->sam_ldb));
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
@@ -833,10 +859,10 @@ static NTSTATUS samsync_ldb_delete_alias(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
-       if (ret != 0) {
+       ret = ldb_delete(state->sam_ldb, msgs[0]->dn);
+       if (ret != LDB_SUCCESS) {
                *error_string = talloc_asprintf(mem_ctx, "Failed to delete alias record %s: %s",
-                                               ldb_dn_linearize(mem_ctx, msgs[0]->dn),
+                                               ldb_dn_get_linearized(msgs[0]->dn),
                                                ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -856,7 +882,7 @@ static NTSTATUS samsync_ldb_handle_alias_member(TALLOC_CTX *mem_ctx,
        struct ldb_message **msgs;
        int ret;
        const char *attrs[] = { NULL };
-       int i;
+       uint32_t i;
 
        msg = ldb_msg_new(mem_ctx);
        if (msg == NULL) {
@@ -888,6 +914,7 @@ static NTSTATUS samsync_ldb_handle_alias_member(TALLOC_CTX *mem_ctx,
 
        for (i=0; i<alias_member->sids.num_sids; i++) {
                struct ldb_dn *alias_member_dn;
+               const char *str_dn;
                /* search for members, in the top basedn (normal users are builtin aliases) */
                ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN], &msgs, attrs,
                                   "(objectSid=%s)", 
@@ -910,15 +937,18 @@ static NTSTATUS samsync_ldb_handle_alias_member(TALLOC_CTX *mem_ctx,
                } else {
                        alias_member_dn = msgs[0]->dn;
                }
-               samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "member", ldb_dn_linearize(mem_ctx, alias_member_dn));
+               str_dn = ldb_dn_alloc_linearized(msg, alias_member_dn);
+               NT_STATUS_HAVE_NO_MEMORY(str_dn);
+               ret = ldb_msg_add_string(msg, "member", str_dn);
+               if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
        
                talloc_free(msgs);
        }
 
-       ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-       if (ret != 0) {
+       ret = dsdb_replace(state->sam_ldb, msg, 0);
+       if (ret != LDB_SUCCESS) {
                *error_string = talloc_asprintf(mem_ctx, "Failed to modify group record %s: %s",
-                                               ldb_dn_linearize(mem_ctx, msg->dn),
+                                               ldb_dn_get_linearized(msg->dn),
                                                ldb_errstring(state->sam_ldb));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -936,53 +966,41 @@ static NTSTATUS samsync_ldb_handle_account(TALLOC_CTX *mem_ctx,
        struct netr_DELTA_ACCOUNT *account = delta->delta_union.account;
 
        struct ldb_message *msg;
-       struct ldb_message **msgs;
-       struct ldb_dn *privilege_dn;
        int ret;
-       const char *attrs[] = { NULL };
-       int i;
+       uint32_t i;
+       char *dnstr, *sidstr;
 
        msg = ldb_msg_new(mem_ctx);
        if (msg == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       /* search for the account, by sid, in the top basedn */
-       ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN], &msgs, attrs,
-                          "(objectSid=%s)", ldap_encode_ndr_dom_sid(mem_ctx, sid)); 
+       sidstr = dom_sid_string(msg, sid);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
 
-       if (ret == -1) {
-               *error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       } else if (ret == 0) {
-               NTSTATUS nt_status;
-               nt_status = samsync_ldb_add_foreignSecurityPrincipal(mem_ctx, state,
-                                                                    sid,
-                                                                    &privilege_dn,
-                                                                    error_string);
-               privilege_dn = talloc_steal(msg, privilege_dn);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       return nt_status;
-               }
-       } else if (ret > 1) {
-               *error_string = talloc_asprintf(mem_ctx, "More than one account with SID: %s", 
-                                               dom_sid_string(mem_ctx, sid));
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       } else {
-               privilege_dn = talloc_steal(msg, msgs[0]->dn);
-       }
+       dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
 
-       msg->dn = privilege_dn;
+       msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
 
        for (i=0; i< account->privilege_entries; i++) {
-               samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "privilege",
-                                    account->privilege_name[i].string);
+               ldb_msg_add_string(msg, "privilege", account->privilege_name[i].string);
+       }
+
+       ret = dsdb_replace(state->pdb, msg, 0);
+       if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+               if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
+                       talloc_free(msg);
+                       return NT_STATUS_NO_MEMORY;
+               }
+               ldb_msg_add_string(msg, "comment", "added via samsync");
+               ret = ldb_add(state->pdb, msg);         
        }
 
-       ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-       if (ret != 0) {
+       if (ret != LDB_SUCCESS) {
                *error_string = talloc_asprintf(mem_ctx, "Failed to modify privilege record %s",
-                                               ldb_dn_linearize(mem_ctx, msg->dn));
+                                               ldb_dn_get_linearized(msg->dn));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
@@ -1026,12 +1044,12 @@ static NTSTATUS samsync_ldb_delete_account(TALLOC_CTX *mem_ctx,
        }
 
        samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,  
-                            "privilage"); 
+                            "privilege");
 
-       ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-       if (ret != 0) {
+       ret = dsdb_replace(state->sam_ldb, msg, 0);
+       if (ret != LDB_SUCCESS) {
                *error_string = talloc_asprintf(mem_ctx, "Failed to modify privilege record %s",
-                                               ldb_dn_linearize(mem_ctx, msg->dn));
+                                               ldb_dn_get_linearized(msg->dn));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
@@ -1039,13 +1057,13 @@ static NTSTATUS samsync_ldb_delete_account(TALLOC_CTX *mem_ctx,
 }
 
 static NTSTATUS libnet_samsync_ldb_fn(TALLOC_CTX *mem_ctx,             
-                                     void *private,                    
+                                     void *private_data,
                                      enum netr_SamDatabaseID database,
                                      struct netr_DELTA_ENUM *delta,
                                      char **error_string)
 {
        NTSTATUS nt_status = NT_STATUS_OK;
-       struct samsync_ldb_state *state = talloc_get_type(private, struct samsync_ldb_state);
+       struct samsync_ldb_state *state = talloc_get_type(private_data, struct samsync_ldb_state);
 
        *error_string = NULL;
        switch (delta->delta_type) {
@@ -1159,11 +1177,11 @@ static NTSTATUS libnet_samsync_ldb_fn(TALLOC_CTX *mem_ctx,
 }
 
 static NTSTATUS libnet_samsync_ldb_init(TALLOC_CTX *mem_ctx,           
-                                       void *private,
+                                       void *private_data,
                                        struct libnet_SamSync_state *samsync_state,
                                        char **error_string)
 {
-       struct samsync_ldb_state *state = talloc_get_type(private, struct samsync_ldb_state);
+       struct samsync_ldb_state *state = talloc_get_type(private_data, struct samsync_ldb_state);
        const char *server = dcerpc_server_name(samsync_state->netlogon_pipe);
        char *ldap_url;
 
@@ -1184,9 +1202,12 @@ static NTSTATUS libnet_samsync_ldb_init(TALLOC_CTX *mem_ctx,
                }
                ldap_url = talloc_asprintf(state, "ldap://%s", server);
                
-               state->remote_ldb = ldb_wrap_connect(mem_ctx, ldap_url, 
+               state->remote_ldb = ldb_wrap_connect(mem_ctx, 
+                                                    NULL,
+                                                    state->samsync_state->machine_net_ctx->lp_ctx,
+                                                    ldap_url, 
                                                     NULL, state->samsync_state->machine_net_ctx->cred,
-                                                    0, NULL);
+                                                    0);
                if (!state->remote_ldb) {
                        *error_string = talloc_asprintf(mem_ctx, "Failed to connect to remote LDAP server at %s (used to extract additional data in SamSync replication)", ldap_url);
                        return NT_STATUS_NO_LOGON_SERVERS;
@@ -1210,8 +1231,20 @@ NTSTATUS libnet_samsync_ldb(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, str
        state->secrets         = NULL;
        state->trusted_domains = NULL;
 
-       state->sam_ldb         = ldb_wrap_connect(mem_ctx, lp_sam_url(), r->in.session_info,
-                                                 ctx->cred, 0, NULL);
+       state->sam_ldb         = samdb_connect(mem_ctx, 
+                                              ctx->event_ctx,
+                                              ctx->lp_ctx,
+                                              r->in.session_info,
+                                                  0);
+       if (!state->sam_ldb) {
+               return NT_STATUS_INTERNAL_DB_ERROR;
+       }
+
+       state->pdb             = privilege_connect(mem_ctx, 
+                                                  ctx->lp_ctx);
+       if (!state->pdb) {
+               return NT_STATUS_INTERNAL_DB_ERROR;
+       }
 
        r2.out.error_string    = NULL;
        r2.in.binding_string   = r->in.binding_string;