s3:libnet: accept empty realm for AD domains when only security=domain is set.
[samba.git] / source3 / libnet / libnet_samsync_ldif.c
index 3068f8d3ebc9bf4e704503a8a9624d8b21883ae8..198373e23d256ed7048945fe1214b5d3a78aefb4 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;
@@ -57,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;
@@ -65,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;
+}
+
 /****************************************************************
 ****************************************************************/
 
@@ -83,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';
        }
@@ -97,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;
@@ -105,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");
@@ -115,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);
@@ -124,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");
@@ -135,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);
@@ -150,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");
@@ -159,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);
@@ -173,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");
@@ -337,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;
@@ -345,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;
 }
 
 /*
@@ -513,8 +577,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;
@@ -542,8 +606,10 @@ 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,
@@ -584,7 +650,7 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
        const char *ou;
        const char* nopasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        uchar zero_buf[16];
-       uint32 rid = 0, group_rid = 0, gidNumber = 0;
+       uint32_t rid = 0, group_rid = 0, gidNumber = 0;
        time_t unix_time;
        int i, ret;
 
@@ -609,9 +675,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");
        }
 
@@ -730,8 +796,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);
@@ -776,7 +842,10 @@ 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,
@@ -810,7 +879,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 */
@@ -862,6 +931,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())) {
@@ -870,7 +947,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);
        }
@@ -879,12 +956,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");
@@ -907,27 +978,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;
+       }
+
+       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;
        }
-       if (!(r->mod_file = fdopen(smb_mkstemp(r->mod_name),"w"))) {
-               DEBUG(1, ("Could not open %s\n", r->mod_name));
+
+       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;
@@ -993,10 +1087,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)) {
@@ -1133,12 +1227,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);