summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/lookup_sid.c38
-rw-r--r--source3/passdb/pdb_interface.c63
-rw-r--r--source3/passdb/pdb_ldap.c20
-rw-r--r--source3/passdb/pdb_smbpasswd.c9
-rw-r--r--source3/passdb/pdb_tdb.c227
-rw-r--r--source3/passdb/pdb_wbc_sam.c12
6 files changed, 281 insertions, 88 deletions
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index 53845117e2..9c20042a62 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -1308,13 +1308,20 @@ void uid_to_sid(DOM_SID *psid, uid_t uid)
if (!ret || expired) {
/* Not in cache. Ask winbindd. */
if (!winbind_uid_to_sid(psid, uid)) {
- if (!winbind_ping()) {
- legacy_uid_to_sid(psid, uid);
- return;
- }
+ /*
+ * We shouldn't return the NULL SID
+ * here if winbind was running and
+ * couldn't map, as winbind will have
+ * added a negative entry that will
+ * cause us to go though the
+ * legacy_uid_to_sid()
+ * function anyway in the case above
+ * the next time we ask.
+ */
+ DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
+ "for uid %u\n", uid));
- DEBUG(5, ("uid_to_sid: winbind failed to find a sid for uid %u\n",
- uid));
+ legacy_uid_to_sid(psid, uid);
return;
}
}
@@ -1354,13 +1361,20 @@ void gid_to_sid(DOM_SID *psid, gid_t gid)
if (!ret || expired) {
/* Not in cache. Ask winbindd. */
if (!winbind_gid_to_sid(psid, gid)) {
- if (!winbind_ping()) {
- legacy_gid_to_sid(psid, gid);
- return;
- }
+ /*
+ * We shouldn't return the NULL SID
+ * here if winbind was running and
+ * couldn't map, as winbind will have
+ * added a negative entry that will
+ * cause us to go though the
+ * legacy_gid_to_sid()
+ * function anyway in the case above
+ * the next time we ask.
+ */
+ DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
+ "for gid %u\n", gid));
- DEBUG(5, ("gid_to_sid: winbind failed to find a sid for gid %u\n",
- gid));
+ legacy_gid_to_sid(psid, gid);
return;
}
}
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index e618b425e0..1909bd0da4 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -1709,24 +1709,25 @@ static NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
}
#endif
-struct pdb_search *pdb_search_init(enum pdb_search_type type)
+static int pdb_search_destructor(struct pdb_search *search)
{
- TALLOC_CTX *mem_ctx;
- struct pdb_search *result;
-
- mem_ctx = talloc_init("pdb_search");
- if (mem_ctx == NULL) {
- DEBUG(0, ("talloc_init failed\n"));
- return NULL;
+ if (!search->search_ended) {
+ search->search_end(search);
}
+ return 0;
+}
- result = TALLOC_P(mem_ctx, struct pdb_search);
+struct pdb_search *pdb_search_init(TALLOC_CTX *mem_ctx,
+ enum pdb_search_type type)
+{
+ struct pdb_search *result;
+
+ result = talloc(mem_ctx, struct pdb_search);
if (result == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
- result->mem_ctx = mem_ctx;
result->type = type;
result->cache = NULL;
result->num_entries = 0;
@@ -1737,6 +1738,8 @@ struct pdb_search *pdb_search_init(enum pdb_search_type type)
result->next_entry = NULL;
result->search_end = NULL;
+ talloc_set_destructor(result, pdb_search_destructor);
+
return result;
}
@@ -1783,8 +1786,7 @@ static bool next_entry_groups(struct pdb_search *s,
sid_peek_rid(&map->sid, &rid);
- fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
- entry);
+ fill_displayentry(s, rid, 0, map->nt_name, NULL, map->comment, entry);
state->current_group += 1;
return True;
@@ -1802,7 +1804,7 @@ static bool pdb_search_grouptype(struct pdb_search *search,
{
struct group_search *state;
- state = TALLOC_P(search->mem_ctx, struct group_search);
+ state = talloc(search, struct group_search);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
return False;
@@ -1853,7 +1855,7 @@ static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
break;
}
- ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry,
+ ADD_TO_LARGE_ARRAY(search, struct samr_displayentry,
entry, &search->cache, &search->num_entries,
&search->cache_size);
}
@@ -1861,52 +1863,54 @@ static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
return (search->num_entries > idx) ? &search->cache[idx] : NULL;
}
-struct pdb_search *pdb_search_users(uint32 acct_flags)
+struct pdb_search *pdb_search_users(TALLOC_CTX *mem_ctx, uint32 acct_flags)
{
struct pdb_methods *pdb = pdb_get_methods();
struct pdb_search *result;
- result = pdb_search_init(PDB_USER_SEARCH);
+ result = pdb_search_init(mem_ctx, PDB_USER_SEARCH);
if (result == NULL) {
return NULL;
}
if (!pdb->search_users(pdb, result, acct_flags)) {
- talloc_destroy(result->mem_ctx);
+ TALLOC_FREE(result);
return NULL;
}
return result;
}
-struct pdb_search *pdb_search_groups(void)
+struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx)
{
struct pdb_methods *pdb = pdb_get_methods();
struct pdb_search *result;
- result = pdb_search_init(PDB_GROUP_SEARCH);
+ result = pdb_search_init(mem_ctx, PDB_GROUP_SEARCH);
if (result == NULL) {
return NULL;
}
if (!pdb->search_groups(pdb, result)) {
- talloc_destroy(result->mem_ctx);
+ TALLOC_FREE(result);
return NULL;
}
return result;
}
-struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
+struct pdb_search *pdb_search_aliases(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
{
struct pdb_methods *pdb = pdb_get_methods();
struct pdb_search *result;
if (pdb == NULL) return NULL;
- result = pdb_search_init(PDB_ALIAS_SEARCH);
- if (result == NULL) return NULL;
+ result = pdb_search_init(mem_ctx, PDB_ALIAS_SEARCH);
+ if (result == NULL) {
+ return NULL;
+ }
if (!pdb->search_aliases(pdb, result, sid)) {
- talloc_destroy(result->mem_ctx);
+ TALLOC_FREE(result);
return NULL;
}
return result;
@@ -1935,17 +1939,6 @@ uint32 pdb_search_entries(struct pdb_search *search,
return search->num_entries - start_idx;
}
-void pdb_search_destroy(struct pdb_search *search)
-{
- if (search == NULL)
- return;
-
- if (!search->search_ended)
- search->search_end(search);
-
- talloc_destroy(search->mem_ctx);
-}
-
/*******************************************************************
trustdom methods
*******************************************************************/
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 70a1c62bef..77b19e3de9 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -4349,7 +4349,8 @@ static bool ldapsam_search_next_entry(struct pdb_search *search,
!ldapsam_search_nextpage(search))
return False;
- result = state->ldap2displayentry(state, search->mem_ctx, state->connection->ldap_struct,
+ result = state->ldap2displayentry(state, search,
+ state->connection->ldap_struct,
state->current_entry, entry);
if (!result) {
@@ -4508,7 +4509,7 @@ static bool ldapsam_search_users(struct pdb_methods *methods,
(struct ldapsam_privates *)methods->private_data;
struct ldap_search_state *state;
- state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
+ state = talloc(search, struct ldap_search_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
return False;
@@ -4525,10 +4526,10 @@ static bool ldapsam_search_users(struct pdb_methods *methods,
state->base = lp_ldap_suffix();
state->acct_flags = acct_flags;
- state->base = talloc_strdup(search->mem_ctx, state->base);
+ state->base = talloc_strdup(search, state->base);
state->scope = LDAP_SCOPE_SUBTREE;
- state->filter = get_ldap_filter(search->mem_ctx, "*");
- state->attrs = talloc_attrs(search->mem_ctx, "uid", "sambaSid",
+ state->filter = get_ldap_filter(search, "*");
+ state->attrs = talloc_attrs(search, "uid", "sambaSid",
"displayName", "description",
"sambaAcctFlags", NULL);
state->attrsonly = 0;
@@ -4682,7 +4683,7 @@ static bool ldapsam_search_grouptype(struct pdb_methods *methods,
struct ldap_search_state *state;
fstring tmp;
- state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
+ state = talloc(search, struct ldap_search_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
return False;
@@ -4690,15 +4691,14 @@ static bool ldapsam_search_grouptype(struct pdb_methods *methods,
state->connection = ldap_state->smbldap_state;
- state->base = talloc_strdup(search->mem_ctx, lp_ldap_group_suffix());
+ state->base = talloc_strdup(search, lp_ldap_group_suffix());
state->connection = ldap_state->smbldap_state;
state->scope = LDAP_SCOPE_SUBTREE;
- state->filter = talloc_asprintf(search->mem_ctx,
- "(&(objectclass=%s)"
+ state->filter = talloc_asprintf(search, "(&(objectclass=%s)"
"(sambaGroupType=%d)(sambaSID=%s*))",
LDAP_OBJ_GROUPMAP,
type, sid_to_fstring(tmp, sid));
- state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
+ state->attrs = talloc_attrs(search, "cn", "sambaSid",
"displayName", "description",
"sambaGroupType", NULL);
state->attrsonly = 0;
diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c
index b72e0f2cba..d663c7f0b2 100644
--- a/source3/passdb/pdb_smbpasswd.c
+++ b/source3/passdb/pdb_smbpasswd.c
@@ -1566,11 +1566,11 @@ static bool smbpasswd_search_next_entry(struct pdb_search *search,
entry->acct_flags = state->entries[state->current].acct_flags;
entry->account_name = talloc_strdup(
- search->mem_ctx, state->entries[state->current].account_name);
+ search, state->entries[state->current].account_name);
entry->fullname = talloc_strdup(
- search->mem_ctx, state->entries[state->current].fullname);
+ search, state->entries[state->current].fullname);
entry->description = talloc_strdup(
- search->mem_ctx, state->entries[state->current].description);
+ search, state->entries[state->current].description);
if ((entry->account_name == NULL) || (entry->fullname == NULL)
|| (entry->description == NULL)) {
@@ -1593,8 +1593,7 @@ static bool smbpasswd_search_users(struct pdb_methods *methods,
struct smb_passwd *pwd;
FILE *fp;
- search_state = TALLOC_ZERO_P(search->mem_ctx,
- struct smbpasswd_search_state);
+ search_state = talloc_zero(search, struct smbpasswd_search_state);
if (search_state == NULL) {
DEBUG(0, ("talloc failed\n"));
return false;
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index 143a2e2390..73fcfee4b3 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -102,6 +102,7 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
ret = init_samu_from_buffer(user, SAMU_BUFFER_V3,
(uint8 *)rec->value.dptr,
rec->value.dsize);
+ break;
case 4:
ret = init_samu_from_buffer(user, SAMU_BUFFER_V4,
(uint8 *)rec->value.dptr,
@@ -141,6 +142,149 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
return 0;
}
+/**********************************************************************
+ Struct and function to backup an old record.
+ *********************************************************************/
+
+struct tdbsam_backup_state {
+ struct db_context *new_db;
+ bool success;
+};
+
+static int backup_copy_fn(struct db_record *orig_rec, void *state)
+{
+ struct tdbsam_backup_state *bs = (struct tdbsam_backup_state *)state;
+ struct db_record *new_rec;
+ NTSTATUS status;
+
+ new_rec = bs->new_db->fetch_locked(bs->new_db, talloc_tos(), orig_rec->key);
+ if (new_rec == NULL) {
+ bs->success = false;
+ return 1;
+ }
+
+ status = new_rec->store(new_rec, orig_rec->value, TDB_INSERT);
+
+ TALLOC_FREE(new_rec);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ bs->success = false;
+ return 1;
+ }
+ return 0;
+}
+
+/**********************************************************************
+ Make a backup of an old passdb and replace the new one with it. We
+ have to do this as between 3.0.x and 3.2.x the hash function changed
+ by mistake (used unsigned char * instead of char *). This means the
+ previous simple update code will fail due to not being able to find
+ existing records to replace in the tdbsam_convert_one() function. JRA.
+ *********************************************************************/
+
+static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ const char *tmp_fname = NULL;
+ struct db_context *tmp_db = NULL;
+ struct db_context *orig_db = *pp_db;
+ struct tdbsam_backup_state bs;
+ int ret;
+
+ tmp_fname = talloc_asprintf(frame, "%s.tmp", dbname);
+ if (!tmp_fname) {
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ unlink(tmp_fname);
+
+ /* Remember to open this on the NULL context. We need
+ * it to stay around after we return from here. */
+
+ tmp_db = db_open(NULL, tmp_fname, 0,
+ TDB_DEFAULT, O_CREAT|O_RDWR, 0600);
+ if (tmp_db == NULL) {
+ DEBUG(0, ("tdbsam_convert_backup: Failed to create backup TDB passwd "
+ "[%s]\n", tmp_fname));
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ if (orig_db->transaction_start(orig_db) != 0) {
+ DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (1)\n"));
+ unlink(tmp_fname);
+ TALLOC_FREE(tmp_db);
+ TALLOC_FREE(frame);
+ return false;
+ }
+ if (tmp_db->transaction_start(tmp_db) != 0) {
+ DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (2)\n"));
+ orig_db->transaction_cancel(orig_db);
+ unlink(tmp_fname);
+ TALLOC_FREE(tmp_db);
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ bs.new_db = tmp_db;
+ bs.success = true;
+
+ ret = orig_db->traverse(orig_db, backup_copy_fn, (void *)&bs);
+ if (ret < 0) {
+ DEBUG(0, ("tdbsam_convert_backup: traverse failed\n"));
+ goto cancel;
+ }
+
+ if (!bs.success) {
+ DEBUG(0, ("tdbsam_convert_backup: Rewriting records failed\n"));
+ goto cancel;
+ }
+
+ if (orig_db->transaction_commit(orig_db) != 0) {
+ smb_panic("tdbsam_convert_backup: orig commit failed\n");
+ }
+ if (tmp_db->transaction_commit(tmp_db) != 0) {
+ smb_panic("tdbsam_convert_backup: orig commit failed\n");
+ }
+
+ /* This is safe from other users as we know we're
+ * under a mutex here. */
+
+ if (rename(tmp_fname, dbname) == -1) {
+ DEBUG(0, ("tdbsam_convert_backup: rename of %s to %s failed %s\n",
+ tmp_fname,
+ dbname,
+ strerror(errno)));
+ smb_panic("tdbsam_convert_backup: replace passdb failed\n");
+ }
+
+ TALLOC_FREE(frame);
+ TALLOC_FREE(orig_db);
+
+ DEBUG(1, ("tdbsam_convert_backup: updated %s file.\n",
+ dbname ));
+
+ /* Replace the global db pointer. */
+ *pp_db = tmp_db;
+ return true;
+
+ cancel:
+
+ if (orig_db->transaction_cancel(orig_db) != 0) {
+ smb_panic("tdbsam_convert: transaction_cancel failed");
+ }
+
+ if (tmp_db->transaction_cancel(tmp_db) != 0) {
+ smb_panic("tdbsam_convert: transaction_cancel failed");
+ }
+
+ unlink(tmp_fname);
+ TALLOC_FREE(tmp_db);
+ TALLOC_FREE(frame);
+ return false;
+}
+
static bool tdbsam_upgrade_next_rid(struct db_context *db)
{
TDB_CONTEXT *tdb;
@@ -172,43 +316,50 @@ static bool tdbsam_upgrade_next_rid(struct db_context *db)
return true;
}
-static bool tdbsam_convert(struct db_context *db, int32 from)
+static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 from)
{
struct tdbsam_convert_state state;
+ struct db_context *db = NULL;
int ret;
+ if (!tdbsam_convert_backup(name, pp_db)) {
+ DEBUG(0, ("tdbsam_convert: Could not backup %s\n", name));
+ return false;
+ }
+
+ db = *pp_db;
state.from = from;
state.success = true;
if (db->transaction_start(db) != 0) {
- DEBUG(0, ("Could not start transaction\n"));
+ DEBUG(0, ("tdbsam_convert: Could not start transaction\n"));
return false;
}
if (!tdbsam_upgrade_next_rid(db)) {
- DEBUG(0, ("tdbsam_upgrade_next_rid failed\n"));
+ DEBUG(0, ("tdbsam_convert: tdbsam_upgrade_next_rid failed\n"));
goto cancel;
}
ret = db->traverse(db, tdbsam_convert_one, &state);
if (ret < 0) {
- DEBUG(0, ("traverse failed\n"));
+ DEBUG(0, ("tdbsam_convert: traverse failed\n"));
goto cancel;
}
if (!state.success) {
- DEBUG(0, ("Converting records failed\n"));
+ DEBUG(0, ("tdbsam_convert: Converting records failed\n"));
goto cancel;
}
if (dbwrap_store_int32(db, TDBSAM_VERSION_STRING,
TDBSAM_VERSION) != 0) {
- DEBUG(0, ("Could not store tdbsam version\n"));
+ DEBUG(0, ("tdbsam_convert: Could not store tdbsam version\n"));
goto cancel;
}
if (db->transaction_commit(db) != 0) {
- DEBUG(0, ("Could not commit transaction\n"));
+ DEBUG(0, ("tdbsam_convert: Could not commit transaction\n"));
return false;
}
@@ -216,7 +367,7 @@ static bool tdbsam_convert(struct db_context *db, int32 from)
cancel:
if (db->transaction_cancel(db) != 0) {
- smb_panic("transaction_cancel failed");
+ smb_panic("tdbsam_convert: transaction_cancel failed");
}
return false;
@@ -261,17 +412,54 @@ static bool tdbsam_open( const char *name )
}
if ( version < TDBSAM_VERSION ) {
- DEBUG(1, ("tdbsam_open: Converting version %d database to "
- "version %d.\n", version, TDBSAM_VERSION));
+ /*
+ * Ok - we think we're going to have to convert.
+ * Due to the backup process we now must do to
+ * upgrade we have to get a mutex and re-check
+ * the version. Someone else may have upgraded
+ * whilst we were checking.
+ */
+
+ struct named_mutex *mtx = grab_named_mutex(NULL,
+ "tdbsam_upgrade_mutex",
+ 600);
- if ( !tdbsam_convert(db_sam, version) ) {
- DEBUG(0, ("tdbsam_open: Error when trying to convert "
- "tdbsam [%s]\n",name));
+ if (!mtx) {
+ DEBUG(0, ("tdbsam_open: failed to grab mutex.\n"));
TALLOC_FREE(db_sam);
return false;
}
- DEBUG(3, ("TDBSAM converted successfully.\n"));
+ /* Re-check the version */
+ version = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING);
+ if (version == -1) {
+ version = 0; /* Version not found, assume version 0 */
+ }
+
+ /* Compare the version */
+ if (version > TDBSAM_VERSION) {
+ /* Version more recent than the latest known */
+ DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
+ TALLOC_FREE(db_sam);
+ TALLOC_FREE(mtx);
+ return false;
+ }
+
+ if ( version < TDBSAM_VERSION ) {
+ DEBUG(1, ("tdbsam_open: Converting version %d database to "
+ "version %d.\n", version, TDBSAM_VERSION));
+
+ if ( !tdbsam_convert(&db_sam, name, version) ) {
+ DEBUG(0, ("tdbsam_open: Error when trying to convert "
+ "tdbsam [%s]\n",name));
+ TALLOC_FREE(db_sam);
+ TALLOC_FREE(mtx);
+ return false;
+ }
+
+ DEBUG(3, ("TDBSAM converted successfully.\n"));
+ }
+ TALLOC_FREE(mtx);
}
DEBUG(4,("tdbsam_open: successfully opened %s\n", name ));
@@ -882,12 +1070,9 @@ static bool tdbsam_search_next_entry(struct pdb_search *search,
entry->acct_flags = pdb_get_acct_ctrl(user);
entry->rid = rid;
- entry->account_name = talloc_strdup(
- search->mem_ctx, pdb_get_username(user));
- entry->fullname = talloc_strdup(
- search->mem_ctx, pdb_get_fullname(user));
- entry->description = talloc_strdup(
- search->mem_ctx, pdb_get_acct_desc(user));
+ entry->account_name = talloc_strdup(search, pdb_get_username(user));
+ entry->fullname = talloc_strdup(search, pdb_get_fullname(user));
+ entry->description = talloc_strdup(search, pdb_get_acct_desc(user));
TALLOC_FREE(user);
@@ -912,7 +1097,7 @@ static bool tdbsam_search_users(struct pdb_methods *methods,
return false;
}
- state = TALLOC_ZERO_P(search->mem_ctx, struct tdbsam_search_state);
+ state = talloc_zero(search, struct tdbsam_search_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
return false;
diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c
index d2c7fda293..e8116d0995 100644
--- a/source3/passdb/pdb_wbc_sam.c
+++ b/source3/passdb/pdb_wbc_sam.c
@@ -150,7 +150,6 @@ static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods,
NTSTATUS result = NT_STATUS_OK;
char *domain = NULL;
char **account_names = NULL;
- char name[256];
enum lsa_SidType *attr_list = NULL;
int i;
@@ -168,16 +167,19 @@ static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods,
if (attrs[i] == SID_NAME_UNKNOWN) {
names[i] = NULL;
} else {
- snprintf(name, sizeof(name), "%s%c%s", domain,
- *lp_winbind_separator(), account_names[i]);
- names[i] = talloc_strdup(names, name);
+ names[i] = talloc_strdup(names, account_names[i]);
+ if (names[i] == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
}
}
done:
TALLOC_FREE(account_names);
TALLOC_FREE(domain);
- TALLOC_FREE(attrs);
+ TALLOC_FREE(attr_list);
return result;
}