r25048: From the archives (patch found in one of my old working trees):
[kai/samba.git] / source4 / libnet / libnet_samsync_ldb.c
index 4bedbbf119fa28d3eed557ae0025e939e2ef2671..1fa4aece19c76d3b0d3d9d581b5225b2900c4e2b 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 "dsdb/samdb/samdb.h"
 #include "auth/auth.h"
 #include "librpc/gen_ndr/ndr_misc.h"
+#include "db_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;
@@ -76,7 +79,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;
        }
        
@@ -86,9 +89,9 @@ static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
        }
 
        /* add core elements to the ldb_message for the alias */
-       msg->dn = ldb_dn_build_child(mem_ctx, "CN", sidstr, basedn);
-       if (msg->dn == NULL)
-               return NT_STATUS_NO_MEMORY;
+       msg->dn = basedn;
+       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",
@@ -101,7 +104,7 @@ static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
        if (ret != 0) {
                *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;
        }
@@ -125,11 +128,14 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
        }
 
        if (database == SAM_DATABASE_DOMAIN) {
+               struct ldb_dn *partitions_basedn;
                const char *domain_attrs[] =  {"nETBIOSName", "nCName", NULL};
                struct ldb_message **msgs_domain;
                int ret_domain;
 
-               ret_domain = gendb_search(state->sam_ldb, mem_ctx, NULL, &msgs_domain, domain_attrs,
+               partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
+
+               ret_domain = gendb_search(state->sam_ldb, mem_ctx, partitions_basedn, &msgs_domain, domain_attrs,
                                          "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", 
                                          domain_name);
                if (ret_domain == -1) {
@@ -143,7 +149,7 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_SUCH_DOMAIN;                
                }
 
-               state->base_dn[database] = samdb_result_dn(state, msgs_domain[0], "nCName", NULL);
+               state->base_dn[database] = samdb_result_dn(state->sam_ldb, state, msgs_domain[0], "nCName", NULL);
 
                if (state->dom_sid[database]) {
                        /* Update the domain sid with the incoming
@@ -168,14 +174,17 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
                                return nt_status;
                        }
                        
-                       ldb_msg_add_value(msg, "objectGUID", &v);
+                       ldb_msg_add_value(msg, "objectGUID", &v, NULL);
                }
        } else if (database == SAM_DATABASE_BUILTIN) {
                /* work out the builtin_dn - useful for so many calls its worth
                   fetching here */
                const char *dnstring = samdb_search_string(state->sam_ldb, mem_ctx, NULL,
                                                           "distinguishedName", "objectClass=builtinDomain");
-               state->base_dn[database] = ldb_dn_explode(state, dnstring);
+               state->base_dn[database] = ldb_dn_new(state, state->sam_ldb, dnstring);
+               if ( ! ldb_dn_validate(state->base_dn[database])) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
        } else {
                /* PRIVs DB */
                return NT_STATUS_INVALID_PARAMETER;
@@ -235,7 +244,7 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
        const struct dom_sid *user_sid;
        struct ldb_message *msg;
        struct ldb_message **msgs;
-       struct ldb_message **remote_msgs;
+       struct ldb_message **remote_msgs = NULL;
        int ret, i;
        uint32_t acb;
        BOOL add = False;
@@ -289,7 +298,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) {
@@ -351,23 +360,25 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY; 
        } 
        
-       /* 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 (!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);
-       } else {
+                                  "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);
-       } else {
+                                  "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);
@@ -410,8 +421,8 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
                                     "objectClass", obj_class);
                if (!msg->dn) {
-                       msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
-                                                       "CN=%s, CN=%s", cn_name, container);
+                       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;             
                        }
@@ -421,21 +432,28 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                if (ret != 0) {
                        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 = 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_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) {
                        *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;
                }
@@ -477,7 +495,7 @@ static NTSTATUS samsync_ldb_delete_user(TALLOC_CTX *mem_ctx,
        ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
        if (ret != 0) {
                *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;
        }
@@ -557,8 +575,8 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
        if (add) {
                samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
                                     "objectClass", obj_class);
-               msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
-                                               "CN=%s, CN=%s", cn_name, container);
+               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;             
                }
@@ -566,7 +584,7 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
                ret = samdb_add(state->sam_ldb, mem_ctx, msg);
                if (ret != 0) {
                        *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;
                }
@@ -574,7 +592,7 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
                ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
                if (ret != 0) {
                        *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;
                }
@@ -616,7 +634,7 @@ static NTSTATUS samsync_ldb_delete_group(TALLOC_CTX *mem_ctx,
        ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
        if (ret != 0) {
                *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;
        }
@@ -680,7 +698,7 @@ 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));
+                       samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "member", ldb_dn_alloc_linearized(mem_ctx, msgs[0]->dn));
                }
                
                talloc_free(msgs);
@@ -689,7 +707,7 @@ static NTSTATUS samsync_ldb_handle_group_member(TALLOC_CTX *mem_ctx,
        ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
        if (ret != 0) {
                *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;
        }
@@ -771,8 +789,8 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
        if (add) {
                samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
                                     "objectClass", obj_class);
-               msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
-                                               "CN=%s, CN=%s", cn_name, container);
+               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;             
                }
@@ -780,7 +798,7 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
                ret = samdb_add(state->sam_ldb, mem_ctx, msg);
                if (ret != 0) {
                        *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;
                }
@@ -788,7 +806,7 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
                ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
                if (ret != 0) {
                        *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;
                }
@@ -825,7 +843,7 @@ static NTSTATUS samsync_ldb_delete_alias(TALLOC_CTX *mem_ctx,
        ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
        if (ret != 0) {
                *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;
        }
@@ -899,7 +917,7 @@ 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));
+               samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "member", ldb_dn_alloc_linearized(mem_ctx, alias_member_dn));
        
                talloc_free(msgs);
        }
@@ -907,7 +925,7 @@ static NTSTATUS samsync_ldb_handle_alias_member(TALLOC_CTX *mem_ctx,
        ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
        if (ret != 0) {
                *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;
        }
@@ -971,7 +989,7 @@ static NTSTATUS samsync_ldb_handle_account(TALLOC_CTX *mem_ctx,
        ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
        if (ret != 0) {
                *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;
        }
 
@@ -1020,7 +1038,7 @@ static NTSTATUS samsync_ldb_delete_account(TALLOC_CTX *mem_ctx,
        ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
        if (ret != 0) {
                *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;
        }
 
@@ -1199,11 +1217,13 @@ 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,
+       state->sam_ldb         = ldb_wrap_connect(mem_ctx, lp_sam_url(), 
+                                                 r->in.session_info,
                                                  ctx->cred, 0, NULL);
 
        r2.out.error_string    = NULL;
        r2.in.binding_string   = r->in.binding_string;
+       r2.in.rid_crypt        = true;
        r2.in.init_fn          = libnet_samsync_ldb_init;
        r2.in.delta_fn         = libnet_samsync_ldb_fn;
        r2.in.fn_ctx           = state;