Update smbrun to allow for settings environment variables.
[samba.git] / source3 / libnet / libnet_samsync_ldif.c
index 64eb9a58da45aa197ef4a285c806fa49ca241c92..dafeadea3c7724d1aa399827b79889e69e98570a 100644 (file)
 */
 
 #include "includes.h"
+#include "system/filesys.h"
 #include "libnet/libnet_samsync.h"
+#include "transfer_file.h"
+#include "passdb.h"
+#include "passdb/pdb_ldap_schema.h"
+#include "lib/util/base64.h"
+
+#ifdef HAVE_LDAP
 
 /* uid's and gid's for writing deltas to ldif */
-static uint32 ldif_gid = 999;
-static uint32 ldif_uid = 999;
+static uint32_t ldif_gid = 999;
+static uint32_t ldif_uid = 999;
+
+/* global counters */
+static uint32_t g_index = 0;
+static uint32_t a_index = 0;
 
 /* Structure for mapping accounts to groups */
 /* Array element is the group rid */
@@ -51,7 +62,7 @@ struct samsync_ldif_context {
        const char *add_template;
        const char *mod_template;
        char *add_name;
-       char *mod_name;
+       char *module_name;
        FILE *add_file;
        FILE *mod_file;
        FILE *ldif_file;
@@ -59,6 +70,33 @@ struct samsync_ldif_context {
        int num_alloced;
 };
 
+/*
+   Returns the substring from src between the first occurrence of
+   the char "front" and the first occurence of the char "back".
+   Mallocs the return string which must be freed.  Not for use
+   with wide character strings.
+*/
+static char *sstring_sub(const char *src, char front, char back)
+{
+       char *temp1, *temp2, *temp3;
+       ptrdiff_t len;
+
+       temp1 = strchr(src, front);
+       if (temp1 == NULL) return NULL;
+       temp2 = strchr(src, back);
+       if (temp2 == NULL) return NULL;
+       len = temp2 - temp1;
+       if (len <= 0) return NULL;
+       temp3 = (char*)SMB_MALLOC(len);
+       if (temp3 == NULL) {
+               DEBUG(1,("Malloc failure in sstring_sub\n"));
+               return NULL;
+       }
+       memcpy(temp3, temp1+1, len-1);
+       temp3[len-1] = '\0';
+       return temp3;
+}
+
 /****************************************************************
 ****************************************************************/
 
@@ -77,6 +115,9 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        if (suffix_attr == NULL) {
                len = strlen(suffix);
                suffix_attr = (char*)SMB_MALLOC(len+1);
+               if (!suffix_attr) {
+                       return NT_STATUS_NO_MEMORY;
+               }
                memcpy(suffix_attr, suffix, len);
                suffix_attr[len] = '\0';
        }
@@ -91,7 +132,7 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        fprintf(add_fd, "\n");
        fflush(add_fd);
 
-       user_suffix = lp_ldap_user_suffix();
+       user_suffix = lp_ldap_user_suffix(talloc_tos());
        if (user_suffix == NULL) {
                SAFE_FREE(suffix_attr);
                return NT_STATUS_NO_MEMORY;
@@ -99,7 +140,7 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        /* If it exists and is distinct from other containers,
           Write the Users entity */
        if (*user_suffix && strcmp(user_suffix, suffix)) {
-               user_attr = sstring_sub(lp_ldap_user_suffix(), '=', ',');
+               user_attr = sstring_sub(lp_ldap_user_suffix(talloc_tos()), '=', ',');
                fprintf(add_fd, "# %s\n", user_suffix);
                fprintf(add_fd, "dn: %s\n", user_suffix);
                fprintf(add_fd, "objectClass: organizationalUnit\n");
@@ -109,7 +150,7 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        }
 
 
-       group_suffix = lp_ldap_group_suffix();
+       group_suffix = lp_ldap_group_suffix(talloc_tos());
        if (group_suffix == NULL) {
                SAFE_FREE(suffix_attr);
                SAFE_FREE(user_attr);
@@ -118,7 +159,7 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        /* If it exists and is distinct from other containers,
           Write the Groups entity */
        if (*group_suffix && strcmp(group_suffix, suffix)) {
-               group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
+               group_attr = sstring_sub(lp_ldap_group_suffix(talloc_tos()), '=', ',');
                fprintf(add_fd, "# %s\n", group_suffix);
                fprintf(add_fd, "dn: %s\n", group_suffix);
                fprintf(add_fd, "objectClass: organizationalUnit\n");
@@ -129,7 +170,7 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
 
        /* If it exists and is distinct from other containers,
           Write the Computers entity */
-       machine_suffix = lp_ldap_machine_suffix();
+       machine_suffix = lp_ldap_machine_suffix(talloc_tos());
        if (machine_suffix == NULL) {
                SAFE_FREE(suffix_attr);
                SAFE_FREE(user_attr);
@@ -144,7 +185,7 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                fprintf(add_fd, "objectClass: organizationalUnit\n");
                /* this isn't totally correct as it assumes that
                   there _must_ be an ou. just fixing memleak now. jmcd */
-               machine_ou = sstring_sub(lp_ldap_machine_suffix(), '=', ',');
+               machine_ou = sstring_sub(lp_ldap_machine_suffix(talloc_tos()), '=', ',');
                fprintf(add_fd, "ou: %s\n", machine_ou);
                SAFE_FREE(machine_ou);
                fprintf(add_fd, "\n");
@@ -153,7 +194,7 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
 
        /* If it exists and is distinct from other containers,
           Write the IdMap entity */
-       idmap_suffix = lp_ldap_idmap_suffix();
+       idmap_suffix = lp_ldap_idmap_suffix(talloc_tos());
        if (idmap_suffix == NULL) {
                SAFE_FREE(suffix_attr);
                SAFE_FREE(user_attr);
@@ -167,7 +208,7 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                fprintf(add_fd, "# %s\n", idmap_suffix);
                fprintf(add_fd, "dn: %s\n", idmap_suffix);
                fprintf(add_fd, "ObjectClass: organizationalUnit\n");
-               s = sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
+               s = sstring_sub(lp_ldap_idmap_suffix(talloc_tos()), '=', ',');
                fprintf(add_fd, "ou: %s\n", s);
                SAFE_FREE(s);
                fprintf(add_fd, "\n");
@@ -178,8 +219,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        fprintf(add_fd, "# %s, %s\n", lp_workgroup(), suffix);
        fprintf(add_fd, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
                suffix);
-       fprintf(add_fd, "objectClass: sambaDomain\n");
-       fprintf(add_fd, "objectClass: sambaUnixIdPool\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_DOMINFO);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_IDPOOL);
        fprintf(add_fd, "sambaDomainName: %s\n", lp_workgroup());
        fprintf(add_fd, "sambaSID: %s\n", sid);
        fprintf(add_fd, "uidNumber: %d\n", ++ldif_uid);
@@ -192,8 +233,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "cn: Domain Admins\n");
        fprintf(add_fd, "memberUid: Administrator\n");
        fprintf(add_fd, "description: Netbios Domain Administrators\n");
@@ -209,8 +250,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Domain Users,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "cn: Domain Users\n");
        fprintf(add_fd, "description: Netbios Domain Users\n");
        fprintf(add_fd, "gidNumber: 513\n");
@@ -225,8 +266,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "cn: Domain Guests\n");
        fprintf(add_fd, "description: Netbios Domain Guests\n");
        fprintf(add_fd, "gidNumber: 514\n");
@@ -241,8 +282,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Domain Computers,ou=%s,%s\n",
                group_attr, suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 515\n");
        fprintf(add_fd, "cn: Domain Computers\n");
        fprintf(add_fd, "description: Netbios Domain Computers accounts\n");
@@ -257,8 +298,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Administrators,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 544\n");
        fprintf(add_fd, "cn: Administrators\n");
        fprintf(add_fd, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
@@ -272,8 +313,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Print Operators,ou=%s,%s\n",
                group_attr, suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 550\n");
        fprintf(add_fd, "cn: Print Operators\n");
        fprintf(add_fd, "description: Netbios Domain Print Operators\n");
@@ -288,8 +329,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Backup Operators,ou=%s,%s\n",
                group_attr, suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 551\n");
        fprintf(add_fd, "cn: Backup Operators\n");
        fprintf(add_fd, "description: Netbios Domain Members can bypass file security to back up files\n");
@@ -303,8 +344,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        fprintf(add_fd, "# Replicators, %s, %s\n", group_attr, suffix);
        fprintf(add_fd, "dn: cn=Replicators,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 552\n");
        fprintf(add_fd, "cn: Replicators\n");
        fprintf(add_fd, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
@@ -331,7 +372,7 @@ static NTSTATUS map_populate_groups(TALLOC_CTX *mem_ctx,
                                    const char *suffix,
                                    const char *builtin_sid)
 {
-       char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
+       char *group_attr = sstring_sub(lp_ldap_group_suffix(talloc_tos()), '=', ',');
 
        /* Map the groups created by populate_ldap_for_ldif */
        groupmap[0].rid         = 512;
@@ -339,100 +380,129 @@ static NTSTATUS map_populate_groups(TALLOC_CTX *mem_ctx,
        groupmap[0].sambaSID    = talloc_asprintf(mem_ctx, "%s-512", sid);
        groupmap[0].group_dn    = talloc_asprintf(mem_ctx,
                "cn=Domain Admins,ou=%s,%s", group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[0].sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[0].group_dn);
+       if (groupmap[0].sambaSID == NULL || groupmap[0].group_dn == NULL) {
+               goto err;
+       }
 
        accountmap[0].rid       = 512;
        accountmap[0].cn        = talloc_strdup(mem_ctx, "Domain Admins");
-       NT_STATUS_HAVE_NO_MEMORY(accountmap[0].cn);
+       if (accountmap[0].cn == NULL) {
+               goto err;
+       }
 
        groupmap[1].rid         = 513;
        groupmap[1].gidNumber   = 513;
        groupmap[1].sambaSID    = talloc_asprintf(mem_ctx, "%s-513", sid);
        groupmap[1].group_dn    = talloc_asprintf(mem_ctx,
                "cn=Domain Users,ou=%s,%s", group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[1].sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[1].group_dn);
+       if (groupmap[1].sambaSID == NULL || groupmap[1].group_dn == NULL) {
+               goto err;
+       }
 
        accountmap[1].rid       = 513;
        accountmap[1].cn        = talloc_strdup(mem_ctx, "Domain Users");
-       NT_STATUS_HAVE_NO_MEMORY(accountmap[1].cn);
+       if (accountmap[1].cn == NULL) {
+               goto err;
+       }
 
        groupmap[2].rid         = 514;
        groupmap[2].gidNumber   = 514;
        groupmap[2].sambaSID    = talloc_asprintf(mem_ctx, "%s-514", sid);
        groupmap[2].group_dn    = talloc_asprintf(mem_ctx,
                "cn=Domain Guests,ou=%s,%s", group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[2].sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[2].group_dn);
+       if (groupmap[2].sambaSID == NULL || groupmap[2].group_dn == NULL) {
+               goto err;
+       }
 
        accountmap[2].rid       = 514;
        accountmap[2].cn        = talloc_strdup(mem_ctx, "Domain Guests");
-       NT_STATUS_HAVE_NO_MEMORY(accountmap[2].cn);
+       if (accountmap[2].cn == NULL) {
+               goto err;
+       }
 
        groupmap[3].rid         = 515;
        groupmap[3].gidNumber   = 515;
        groupmap[3].sambaSID    = talloc_asprintf(mem_ctx, "%s-515", sid);
        groupmap[3].group_dn    = talloc_asprintf(mem_ctx,
                "cn=Domain Computers,ou=%s,%s", group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[3].sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[3].group_dn);
+       if (groupmap[3].sambaSID == NULL || groupmap[3].group_dn == NULL) {
+               goto err;
+       }
 
        accountmap[3].rid       = 515;
        accountmap[3].cn        = talloc_strdup(mem_ctx, "Domain Computers");
-       NT_STATUS_HAVE_NO_MEMORY(accountmap[3].cn);
+       if (accountmap[3].cn == NULL) {
+               goto err;
+       }
 
        groupmap[4].rid         = 544;
        groupmap[4].gidNumber   = 544;
        groupmap[4].sambaSID    = talloc_asprintf(mem_ctx, "%s-544", builtin_sid);
        groupmap[4].group_dn    = talloc_asprintf(mem_ctx,
                "cn=Administrators,ou=%s,%s", group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[4].sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[4].group_dn);
+       if (groupmap[4].sambaSID == NULL || groupmap[4].group_dn == NULL) {
+               goto err;
+       }
 
        accountmap[4].rid       = 515;
        accountmap[4].cn        = talloc_strdup(mem_ctx, "Administrators");
-       NT_STATUS_HAVE_NO_MEMORY(accountmap[4].cn);
+       if (accountmap[4].cn == NULL) {
+               goto err;
+       }
 
        groupmap[5].rid         = 550;
        groupmap[5].gidNumber   = 550;
        groupmap[5].sambaSID    = talloc_asprintf(mem_ctx, "%s-550", builtin_sid);
        groupmap[5].group_dn    = talloc_asprintf(mem_ctx,
                "cn=Print Operators,ou=%s,%s", group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[5].sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[5].group_dn);
+       if (groupmap[5].sambaSID == NULL || groupmap[5].group_dn == NULL) {
+               goto err;
+       }
 
        accountmap[5].rid       = 550;
        accountmap[5].cn        = talloc_strdup(mem_ctx, "Print Operators");
-       NT_STATUS_HAVE_NO_MEMORY(accountmap[5].cn);
+       if (accountmap[5].cn == NULL) {
+               goto err;
+       }
 
        groupmap[6].rid         = 551;
        groupmap[6].gidNumber   = 551;
        groupmap[6].sambaSID    = talloc_asprintf(mem_ctx, "%s-551", builtin_sid);
        groupmap[6].group_dn    = talloc_asprintf(mem_ctx,
                "cn=Backup Operators,ou=%s,%s", group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[6].sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[6].group_dn);
+       if (groupmap[6].sambaSID == NULL || groupmap[6].group_dn == NULL) {
+               goto err;
+       }
 
        accountmap[6].rid       = 551;
        accountmap[6].cn        = talloc_strdup(mem_ctx, "Backup Operators");
-       NT_STATUS_HAVE_NO_MEMORY(accountmap[6].cn);
+       if (accountmap[6].cn == NULL) {
+               goto err;
+       }
 
        groupmap[7].rid         = 552;
        groupmap[7].gidNumber   = 552;
        groupmap[7].sambaSID    = talloc_asprintf(mem_ctx, "%s-552", builtin_sid);
        groupmap[7].group_dn    = talloc_asprintf(mem_ctx,
                "cn=Replicators,ou=%s,%s", group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[7].sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap[7].group_dn);
+       if (groupmap[7].sambaSID == NULL || groupmap[7].group_dn == NULL) {
+               goto err;
+       }
 
        accountmap[7].rid       = 551;
        accountmap[7].cn        = talloc_strdup(mem_ctx, "Replicators");
-       NT_STATUS_HAVE_NO_MEMORY(accountmap[7].cn);
+       if (accountmap[7].cn == NULL) {
+               goto err;
+       }
 
        SAFE_FREE(group_attr);
 
        return NT_STATUS_OK;
+
+  err:
+
+       SAFE_FREE(group_attr);
+       return NT_STATUS_NO_MEMORY;
 }
 
 /*
@@ -440,6 +510,9 @@ static NTSTATUS map_populate_groups(TALLOC_CTX *mem_ctx,
  * UTF8->base64 problem.
  */
 
+static int fprintf_attr(FILE *add_fd, const char *attr_name,
+                       const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
+
 static int fprintf_attr(FILE *add_fd, const char *attr_name,
                        const char *fmt, ...)
 {
@@ -507,8 +580,8 @@ static NTSTATUS fetch_group_info_to_ldif(TALLOC_CTX *mem_ctx,
                                         const char *suffix)
 {
        const char *groupname = r->group_name.string;
-       uint32 grouptype = 0, g_rid = 0;
-       char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
+       uint32_t grouptype = 0, g_rid = 0;
+       char *group_attr = sstring_sub(lp_ldap_group_suffix(talloc_tos()), '=', ',');
 
        /* Set up the group type (always 2 for group info) */
        grouptype = 2;
@@ -536,16 +609,18 @@ static NTSTATUS fetch_group_info_to_ldif(TALLOC_CTX *mem_ctx,
        groupmap->sambaSID      = talloc_asprintf(mem_ctx, "%s-%d", sid, g_rid);
        groupmap->group_dn      = talloc_asprintf(mem_ctx,
             "cn=%s,ou=%s,%s", groupname, group_attr, suffix);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap->sambaSID);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap->group_dn);
+       if (groupmap->sambaSID == NULL || groupmap->group_dn == NULL) {
+               SAFE_FREE(group_attr);
+               return NT_STATUS_NO_MEMORY;
+       }
 
        /* Write the data to the temporary add ldif file */
        fprintf(add_fd, "# %s, %s, %s\n", groupname, group_attr,
                suffix);
        fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", groupname, group_attr,
                     suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf_attr(add_fd, "cn", "%s", groupname);
        fprintf(add_fd, "gidNumber: %d\n", ldif_gid);
        fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID);
@@ -574,14 +649,15 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
        fstring username, logonscript, homedrive, homepath = "", homedir = "";
        fstring hex_nt_passwd, hex_lm_passwd;
        fstring description, profilepath, fullname, sambaSID;
-       uchar lm_passwd[16], nt_passwd[16];
        char *flags, *user_rdn;
        const char *ou;
        const char* nopasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
-       static uchar zero_buf[16];
-       uint32 rid = 0, group_rid = 0, gidNumber = 0;
+       uchar zero_buf[16];
+       uint32_t rid = 0, group_rid = 0, gidNumber = 0;
        time_t unix_time;
-       int i;
+       int i, ret;
+
+       memset(zero_buf, '\0', sizeof(zero_buf));
 
        /* Get the username */
        fstrcpy(username, r->account_name.string);
@@ -602,9 +678,9 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
                } else {
                        snprintf(homedir, sizeof(homedir), "/nobodyshomedir");
                }
-               ou = lp_ldap_user_suffix();
+               ou = lp_ldap_user_suffix(talloc_tos());
        } else {
-               ou = lp_ldap_machine_suffix();
+               ou = lp_ldap_machine_suffix(talloc_tos());
                snprintf(homedir, sizeof(homedir), "/machinehomedir");
        }
 
@@ -628,14 +704,12 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
 
        /* Get lm and nt password data */
        if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
-               sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0);
-               pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags);
+               pdb_sethexpwd(hex_lm_passwd, r->lmpassword.hash, r->acct_flags);
        } else {
                pdb_sethexpwd(hex_lm_passwd, NULL, 0);
        }
        if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
-               sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0);
-               pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags);
+               pdb_sethexpwd(hex_nt_passwd, r->ntpassword.hash, r->acct_flags);
        } else {
                pdb_sethexpwd(hex_nt_passwd, NULL, 0);
        }
@@ -655,7 +729,10 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
                return NT_STATUS_UNSUCCESSFUL;
        }
        gidNumber = groupmap[i].gidNumber;
-       snprintf(sambaSID, sizeof(sambaSID), groupmap[i].sambaSID);
+       ret = snprintf(sambaSID, sizeof(sambaSID), "%s", groupmap[i].sambaSID);
+       if (ret < 0 || ret == sizeof(sambaSID)) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
        /* Set up sambaAcctFlags */
        flags = pdb_encode_acct_ctrl(r->acct_flags,
@@ -670,9 +747,9 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
        SAFE_FREE(user_rdn);
        fprintf(add_fd, "ObjectClass: top\n");
        fprintf(add_fd, "objectClass: inetOrgPerson\n");
-       fprintf(add_fd, "objectClass: posixAccount\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXACCOUNT);
        fprintf(add_fd, "objectClass: shadowAccount\n");
-       fprintf(add_fd, "objectClass: sambaSamAccount\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_SAMBASAMACCOUNT);
        fprintf_attr(add_fd, "cn", "%s", username);
        fprintf_attr(add_fd, "sn", "%s", username);
        fprintf_attr(add_fd, "uid", "%s", username);
@@ -722,8 +799,8 @@ static NTSTATUS fetch_alias_info_to_ldif(TALLOC_CTX *mem_ctx,
                                         enum netr_SamDatabaseID database_id)
 {
        fstring aliasname, description;
-       uint32 grouptype = 0, g_rid = 0;
-       char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
+       uint32_t grouptype = 0, g_rid = 0;
+       char *group_attr = sstring_sub(lp_ldap_group_suffix(talloc_tos()), '=', ',');
 
        /* Get the alias name */
        fstrcpy(aliasname, r->alias_name.string);
@@ -768,15 +845,18 @@ static NTSTATUS fetch_alias_info_to_ldif(TALLOC_CTX *mem_ctx,
        g_rid = r->rid;
        groupmap->gidNumber = ldif_gid;
        groupmap->sambaSID = talloc_asprintf(mem_ctx, "%s-%d", sid, g_rid);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap->sambaSID);
+       if (groupmap->sambaSID == NULL) {
+               SAFE_FREE(group_attr);
+               return NT_STATUS_NO_MEMORY;
+       }
 
        /* Write the data to the temporary add ldif file */
        fprintf(add_fd, "# %s, %s, %s\n", aliasname, group_attr,
                suffix);
        fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", aliasname, group_attr,
                     suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "cn: %s\n", aliasname);
        fprintf(add_fd, "gidNumber: %d\n", ldif_gid);
        fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID);
@@ -802,7 +882,7 @@ static NTSTATUS fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER *r,
                                            FILE *mod_fd, int alloced)
 {
        fstring group_dn;
-       uint32 group_rid = 0, rid = 0;
+       uint32_t group_rid = 0, rid = 0;
        int i, j, k;
 
        /* Get the dn for the group */
@@ -854,6 +934,14 @@ static NTSTATUS ldif_init_context(TALLOC_CTX *mem_ctx,
        const char *add_template = "/tmp/add.ldif.XXXXXX";
        const char *mod_template = "/tmp/mod.ldif.XXXXXX";
        const char *builtin_sid = "S-1-5-32";
+       mode_t mask;
+       int fd;
+
+       r = talloc_zero(mem_ctx, struct samsync_ldif_context);
+       NT_STATUS_HAVE_NO_MEMORY(r);
+
+       /* Get the ldap suffix */
+       r->suffix = lp_ldap_suffix(talloc_tos());
 
        /* Get other smb.conf data */
        if (!(lp_workgroup()) || !*(lp_workgroup())) {
@@ -862,7 +950,7 @@ static NTSTATUS ldif_init_context(TALLOC_CTX *mem_ctx,
        }
 
        /* Get the ldap suffix */
-       if (!(lp_ldap_suffix()) || !*(lp_ldap_suffix())) {
+       if (!r->suffix || !*r->suffix) {
                DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
                exit(1);
        }
@@ -871,12 +959,6 @@ static NTSTATUS ldif_init_context(TALLOC_CTX *mem_ctx,
                return NT_STATUS_OK;
        }
 
-       r = TALLOC_ZERO_P(mem_ctx, struct samsync_ldif_context);
-       NT_STATUS_HAVE_NO_MEMORY(r);
-
-       /* Get the ldap suffix */
-       r->suffix = lp_ldap_suffix();
-
        /* Ensure we have an output file */
        if (ldif_filename) {
                r->ldif_file = fopen(ldif_filename, "a");
@@ -899,27 +981,50 @@ static NTSTATUS ldif_init_context(TALLOC_CTX *mem_ctx,
        }
 
        r->add_name = talloc_strdup(mem_ctx, add_template);
-       r->mod_name = talloc_strdup(mem_ctx, mod_template);
-       if (!r->add_name || !r->mod_name) {
+       r->module_name = talloc_strdup(mem_ctx, mod_template);
+       if (!r->add_name || !r->module_name) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
+       mask = umask(S_IRWXO | S_IRWXG);
+       fd = mkstemp(r->add_name);
+       umask(mask);
+       if (fd < 0) {
+               DEBUG(1, ("Could not create %s\n", r->add_name));
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
        /* Open the add and mod ldif files */
-       if (!(r->add_file = fdopen(smb_mkstemp(r->add_name),"w"))) {
+       r->add_file = fdopen(fd, "w");
+       if (r->add_file == NULL) {
                DEBUG(1, ("Could not open %s\n", r->add_name));
+               close(fd);
                status = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
-       if (!(r->mod_file = fdopen(smb_mkstemp(r->mod_name),"w"))) {
-               DEBUG(1, ("Could not open %s\n", r->mod_name));
+
+       mask = umask(S_IRWXO | S_IRWXG);
+       fd = mkstemp(r->module_name);
+       umask(mask);
+       if (fd < 0) {
+               DEBUG(1, ("Could not create %s\n", r->module_name));
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       r->mod_file = fdopen(fd, "w");
+       if (r->mod_file == NULL) {
+               DEBUG(1, ("Could not open %s\n", r->module_name));
+               close(fd);
                status = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
 
        /* Allocate initial memory for groupmap and accountmap arrays */
-       r->groupmap = TALLOC_ZERO_ARRAY(mem_ctx, GROUPMAP, 8);
-       r->accountmap = TALLOC_ZERO_ARRAY(mem_ctx, ACCOUNTMAP, 8);
+       r->groupmap = talloc_zero_array(mem_ctx, GROUPMAP, 8);
+       r->accountmap = talloc_zero_array(mem_ctx, ACCOUNTMAP, 8);
        if (r->groupmap == NULL || r->accountmap == NULL) {
                DEBUG(1,("GROUPMAP talloc failed\n"));
                status = NT_STATUS_NO_MEMORY;
@@ -985,10 +1090,10 @@ static void ldif_free_context(struct samsync_ldif_context *r)
                fclose(r->mod_file);
        }
 
-       if ((r->mod_name != NULL) &&
-           strcmp(r->mod_name, r->mod_template) && (unlink(r->mod_name))) {
+       if ((r->module_name != NULL) &&
+           strcmp(r->module_name, r->mod_template) && (unlink(r->module_name))) {
                DEBUG(1,("unlink(%s) failed, error was (%s)\n",
-                        r->mod_name, strerror(errno)));
+                        r->module_name, strerror(errno)));
        }
 
        if (r->ldif_file && (r->ldif_file != stdout)) {
@@ -1045,8 +1150,8 @@ static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
                                     enum netr_SamDatabaseID database_id,
                                     struct netr_DELTA_ENUM *r,
                                     struct samsync_context *ctx,
-                                    uint32_t *a_index,
-                                    uint32_t *g_index)
+                                    uint32_t *a_index_p,
+                                    uint32_t *g_index_p)
 {
        union netr_DELTA_UNION u = r->delta_union;
        union netr_DELTA_ID_UNION id = r->delta_id_union;
@@ -1060,34 +1165,34 @@ static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
                case NETR_DELTA_GROUP:
                        fetch_group_info_to_ldif(mem_ctx,
                                                 u.group,
-                                                &l->groupmap[*g_index],
+                                                &l->groupmap[*g_index_p],
                                                 l->add_file,
                                                 ctx->domain_sid_str,
                                                 l->suffix);
-                       (*g_index)++;
+                       (*g_index_p)++;
                        break;
 
                case NETR_DELTA_USER:
                        fetch_account_info_to_ldif(mem_ctx,
                                                   u.user,
                                                   l->groupmap,
-                                                  &l->accountmap[*a_index],
+                                                  &l->accountmap[*a_index_p],
                                                   l->add_file,
                                                   ctx->domain_sid_str,
                                                   l->suffix,
                                                   l->num_alloced);
-                       (*a_index)++;
+                       (*a_index_p)++;
                        break;
 
                case NETR_DELTA_ALIAS:
                        fetch_alias_info_to_ldif(mem_ctx,
                                                 u.alias,
-                                                &l->groupmap[*g_index],
+                                                &l->groupmap[*g_index_p],
                                                 l->add_file,
                                                 ctx->domain_sid_str,
                                                 l->suffix,
                                                 database_id);
-                       (*g_index)++;
+                       (*g_index_p)++;
                        break;
 
                case NETR_DELTA_GROUP_MEMBER:
@@ -1125,12 +1230,12 @@ static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
                                  uint32_t num_entries)
 {
        /* Re-allocate memory for groupmap and accountmap arrays */
-       l->groupmap = TALLOC_REALLOC_ARRAY(mem_ctx,
+       l->groupmap = talloc_realloc(mem_ctx,
                                           l->groupmap,
                                           GROUPMAP,
                                           num_entries + l->num_alloced);
 
-       l->accountmap = TALLOC_REALLOC_ARRAY(mem_ctx,
+       l->accountmap = talloc_realloc(mem_ctx,
                                             l->accountmap,
                                             ACCOUNTMAP,
                                             num_entries + l->num_alloced);
@@ -1155,15 +1260,12 @@ static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
-                               enum netr_SamDatabaseID database_id,
-                               struct netr_DELTA_ENUM_ARRAY *r,
-                               NTSTATUS result,
-                               struct samsync_context *ctx)
+static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
+                         struct samsync_context *ctx,
+                         enum netr_SamDatabaseID database_id,
+                         uint64_t *sequence_num)
 {
        NTSTATUS status;
-       int i;
-       uint32_t g_index = 0, a_index = 0;
        struct samsync_ldif_context *ldif_ctx =
                (struct samsync_ldif_context *)ctx->private_data;
 
@@ -1173,11 +1275,28 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
                                   ctx->domain_sid_str,
                                   &ldif_ctx);
        if (!NT_STATUS_IS_OK(status)) {
-               goto failed;
+               return status;
        }
 
        ctx->private_data = ldif_ctx;
 
+       return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+                                      enum netr_SamDatabaseID database_id,
+                                      struct netr_DELTA_ENUM_ARRAY *r,
+                                      uint64_t *sequence_num,
+                                      struct samsync_context *ctx)
+{
+       NTSTATUS status;
+       int i;
+       struct samsync_ldif_context *ldif_ctx =
+               (struct samsync_ldif_context *)ctx->private_data;
+
        status = ldif_realloc_maps(mem_ctx, ldif_ctx, r->num_deltas);
        if (!NT_STATUS_IS_OK(status)) {
                goto failed;
@@ -1192,18 +1311,6 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
                }
        }
 
-       /* This was the last query */
-       if (NT_STATUS_IS_OK(result)) {
-               ldif_write_output(database_id, ldif_ctx);
-               if (ldif_ctx->ldif_file != stdout) {
-                       ctx->result_message = talloc_asprintf(mem_ctx,
-                               "Vampired %d accounts and %d groups to %s",
-                               a_index, g_index, ctx->output_filename);
-               }
-               ldif_free_context(ldif_ctx);
-               ctx->private_data = NULL;
-       }
-
        return NT_STATUS_OK;
 
  failed:
@@ -1212,3 +1319,63 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 
        return status;
 }
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS close_ldif(TALLOC_CTX *mem_ctx,
+                          struct samsync_context *ctx,
+                          enum netr_SamDatabaseID database_id,
+                          uint64_t sequence_num)
+{
+       struct samsync_ldif_context *ldif_ctx =
+               (struct samsync_ldif_context *)ctx->private_data;
+
+       /* This was the last query */
+       ldif_write_output(database_id, ldif_ctx);
+       if (ldif_ctx->ldif_file != stdout) {
+               ctx->result_message = talloc_asprintf(ctx,
+                       "Vampired %d accounts and %d groups to %s",
+                       a_index, g_index, ctx->output_filename);
+       }
+
+       ldif_free_context(ldif_ctx);
+       ctx->private_data = NULL;
+
+       return NT_STATUS_OK;
+}
+
+#else /* HAVE_LDAP */
+
+static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
+                         struct samsync_context *ctx,
+                         enum netr_SamDatabaseID database_id,
+                         uint64_t *sequence_num)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+                                      enum netr_SamDatabaseID database_id,
+                                      struct netr_DELTA_ENUM_ARRAY *r,
+                                      uint64_t *sequence_num,
+                                      struct samsync_context *ctx)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS close_ldif(TALLOC_CTX *mem_ctx,
+                          struct samsync_context *ctx,
+                          enum netr_SamDatabaseID database_id,
+                          uint64_t sequence_num)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+#endif
+
+const struct samsync_ops libnet_samsync_ldif_ops = {
+       .startup                = init_ldif,
+       .process_objects        = fetch_sam_entries_ldif,
+       .finish                 = close_ldif,
+};