From 27c07c98619075d594fcd46c0ad05b83b60bc877 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 11 Mar 2008 14:15:52 +0100 Subject: Convert mapping_tdb.c to dbwrap I know, this is not used anymore, but until ldb knows about ctdb which is blocked by the lack of transactions in ctdb, a tiny patch reactivating mapping_tdb.c might be needed for cluster setups. (This used to be commit 8e0fa453a3d0a2c997a935b6940796612c972708) --- source3/groupdb/mapping.h | 2 + source3/groupdb/mapping_tdb.c | 571 +++++++++++++++++++++--------------------- 2 files changed, 281 insertions(+), 292 deletions(-) diff --git a/source3/groupdb/mapping.h b/source3/groupdb/mapping.h index 4af38314f8..c37ae84b87 100644 --- a/source3/groupdb/mapping.h +++ b/source3/groupdb/mapping.h @@ -2,6 +2,7 @@ #define DATABASE_VERSION_V2 2 /* le format. */ #define GROUP_PREFIX "UNIXGROUP/" +#define GROUP_PREFIX_LEN 10 /* Alias memberships are stored reverse, as memberships. The performance * critical operation is to determine the aliases a SID is member of, not @@ -9,6 +10,7 @@ * hanging of the member as key. */ #define MEMBEROF_PREFIX "MEMBEROF/" +#define MEMBEROF_PREFIX_LEN 9 /* groupdb mapping backend abstraction diff --git a/source3/groupdb/mapping_tdb.c b/source3/groupdb/mapping_tdb.c index 31937840d9..c9c8cdcaeb 100644 --- a/source3/groupdb/mapping_tdb.c +++ b/source3/groupdb/mapping_tdb.c @@ -23,7 +23,7 @@ #include "includes.h" #include "groupdb/mapping.h" -static TDB_CONTEXT *tdb; /* used for driver files */ +static struct db_context *db; /* used for driver files */ static bool enum_group_mapping(const DOM_SID *domsid, enum lsa_SidType sid_name_use, GROUP_MAP **pp_rmap, size_t *p_num_entries, bool unix_only); @@ -34,97 +34,119 @@ static bool group_map_remove(const DOM_SID *sid); ****************************************************************************/ static bool init_group_mapping(void) { - const char *vstring = "INFO/version"; - int32 vers_id; - GROUP_MAP *map_table = NULL; - size_t num_entries = 0; - - if (tdb) - return True; - - tdb = tdb_open_log(state_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - if (!tdb) { - DEBUG(0,("Failed to open group mapping database\n")); - return False; + if (db != NULL) { + return true; } - /* handle a Samba upgrade */ - tdb_lock_bystring(tdb, vstring); - - /* Cope with byte-reversed older versions of the db. */ - vers_id = tdb_fetch_int32(tdb, vstring); - if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) { - /* Written on a bigendian machine with old fetch_int code. Save as le. */ - tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2); - vers_id = DATABASE_VERSION_V2; + db = db_open(NULL, state_path("group_mapping.tdb"), 0, TDB_DEFAULT, + O_RDWR|O_CREAT, 0600); + if (db == NULL) { + DEBUG(0, ("Failed to open group mapping database: %s\n", + strerror(errno))); + return false; } - /* if its an unknown version we remove everthing in the db */ - - if (vers_id != DATABASE_VERSION_V2) { - tdb_traverse(tdb, tdb_traverse_delete_fn, NULL); - tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2); - } +#if 0 + /* + * This code was designed to handle a group mapping version + * upgrade. mapping_tdb is not active by default anymore, so ignore + * this here. + */ + { + const char *vstring = "INFO/version"; + int32 vers_id; + GROUP_MAP *map_table = NULL; + size_t num_entries = 0; + + /* handle a Samba upgrade */ + tdb_lock_bystring(tdb, vstring); + + /* Cope with byte-reversed older versions of the db. */ + vers_id = tdb_fetch_int32(tdb, vstring); + if ((vers_id == DATABASE_VERSION_V1) + || (IREV(vers_id) == DATABASE_VERSION_V1)) { + /* + * Written on a bigendian machine with old fetch_int + * code. Save as le. + */ + tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2); + vers_id = DATABASE_VERSION_V2; + } - tdb_unlock_bystring(tdb, vstring); + /* if its an unknown version we remove everthing in the db */ - /* cleanup any map entries with a gid == -1 */ - - if ( enum_group_mapping( NULL, SID_NAME_UNKNOWN, &map_table, &num_entries, False ) ) { - int i; - - for ( i=0; isid); - if (sid_string == NULL) { + key = group_mapping_key(talloc_tos(), &map->sid); + if (key == NULL) { return NULL; } len = tdb_pack(NULL, sizeof(buf), "ddff", map->gid, map->sid_name_use, map->nt_name, map->comment); - if (len) { - buf = TALLOC_ARRAY(sid_string, char, len); - if (!buf) { - TALLOC_FREE(sid_string); - return false; - } - len = tdb_pack((uint8 *)buf, len, "ddff", map->gid, - map->sid_name_use, map->nt_name, map->comment); - } - key = talloc_asprintf(sid_string, "%s%s", GROUP_PREFIX, sid_string); - if (key == NULL) { - TALLOC_FREE(sid_string); + buf = TALLOC_ARRAY(key, char, len); + if (!buf) { + TALLOC_FREE(key); return false; } + len = tdb_pack((uint8 *)buf, len, "ddff", map->gid, + map->sid_name_use, map->nt_name, map->comment); - dbuf.dsize = len; - dbuf.dptr = (uint8 *)buf; + status = dbwrap_store_bystring( + db, key, make_tdb_data((uint8_t *)buf, len), flag); - ret = (tdb_store_bystring(tdb, key, dbuf, flag) == 0); + TALLOC_FREE(key); - TALLOC_FREE(sid_string); - return ret; + return NT_STATUS_IS_OK(status); } @@ -135,129 +157,121 @@ static bool add_mapping_entry(GROUP_MAP *map, int flag) static bool get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) { TDB_DATA dbuf; - char *key = NULL; - fstring string_sid; + char *key; int ret = 0; /* the key is the SID, retrieving is direct */ - sid_to_fstring(string_sid, &sid); - if (asprintf(&key, "%s%s", GROUP_PREFIX, string_sid) < 0) { + key = group_mapping_key(talloc_tos(), &map->sid); + if (key == NULL) { return false; } - dbuf = tdb_fetch_bystring(tdb, key); - if (!dbuf.dptr) { - SAFE_FREE(key); + dbuf = dbwrap_fetch_bystring(db, key, key); + if (dbuf.dptr == NULL) { + TALLOC_FREE(key); return false; } - SAFE_FREE(key); - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); - SAFE_FREE(dbuf.dptr); + TALLOC_FREE(key); if ( ret == -1 ) { DEBUG(3,("get_group_map_from_sid: tdb_unpack failure\n")); - return False; + return false; } sid_copy(&map->sid, &sid); - return True; + return true; } -/**************************************************************************** - Return the sid and the type of the unix group. -****************************************************************************/ - -static bool get_group_map_from_gid(gid_t gid, GROUP_MAP *map) +static bool dbrec2map(const struct db_record *rec, GROUP_MAP *map) { - TDB_DATA kbuf, dbuf, newkey; - fstring string_sid; - int ret; - - /* we need to enumerate the TDB to find the GID */ - - for (kbuf = tdb_firstkey(tdb); - kbuf.dptr; - newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { - - if (strncmp((const char *)kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue; + if ((rec->key.dsize < strlen(GROUP_PREFIX)) + || (strncmp((char *)rec->key.dptr, GROUP_PREFIX, + GROUP_PREFIX_LEN) != 0)) { + return False; + } - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) - continue; + if (!string_to_sid(&map->sid, (const char *)rec->key.dptr + + GROUP_PREFIX_LEN)) { + return False; + } - fstrcpy(string_sid, (const char *)kbuf.dptr+strlen(GROUP_PREFIX)); + return tdb_unpack(rec->value.dptr, rec->value.dsize, "ddff", + &map->gid, &map->sid_name_use, &map->nt_name, + &map->comment) != -1; +} - string_to_sid(&map->sid, string_sid); +struct find_map_state { + bool found; + const char *name; /* If != NULL, look for name */ + gid_t gid; /* valid iff name == NULL */ + GROUP_MAP *map; +}; - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", - &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); +static int find_map(struct db_record *rec, void *private_data) +{ + struct find_map_state *state = (struct find_map_state *)private_data; - SAFE_FREE(dbuf.dptr); + if (!dbrec2map(rec, state->map)) { + DEBUG(10, ("failed to unpack map\n")); + return 0; + } - if ( ret == -1 ) { - DEBUG(3,("get_group_map_from_gid: tdb_unpack failure\n")); - return False; + if (state->name != NULL) { + if (strequal(state->name, state->map->nt_name)) { + state->found = true; + return 1; } - - if (gid==map->gid) { - SAFE_FREE(kbuf.dptr); - return True; + } + else { + if (state->map->gid == state->gid) { + state->found = true; + return 1; } } - return False; + return 0; } /**************************************************************************** Return the sid and the type of the unix group. ****************************************************************************/ -static bool get_group_map_from_ntname(const char *name, GROUP_MAP *map) +static bool get_group_map_from_gid(gid_t gid, GROUP_MAP *map) { - TDB_DATA kbuf, dbuf, newkey; - fstring string_sid; - int ret; - - /* we need to enumerate the TDB to find the name */ - - for (kbuf = tdb_firstkey(tdb); - kbuf.dptr; - newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { - - if (strncmp((const char *)kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue; + struct find_map_state state; - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) - continue; + state.found = false; + state.name = NULL; /* Indicate we're looking for gid */ + state.gid = gid; + state.map = map; - fstrcpy(string_sid, (const char *)kbuf.dptr+strlen(GROUP_PREFIX)); + db->traverse_read(db, find_map, (void *)&state); - string_to_sid(&map->sid, string_sid); + return state.found; +} - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", - &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); +/**************************************************************************** + Return the sid and the type of the unix group. +****************************************************************************/ - SAFE_FREE(dbuf.dptr); +static bool get_group_map_from_ntname(const char *name, GROUP_MAP *map) +{ + struct find_map_state state; - if ( ret == -1 ) { - DEBUG(3,("get_group_map_from_ntname: tdb_unpack failure\n")); - return False; - } + state.found = false; + state.name = name; + state.map = map; - if ( strequal(name, map->nt_name) ) { - SAFE_FREE(kbuf.dptr); - return True; - } - } + db->traverse_read(db, find_map, (void *)&state); - return False; + return state.found; } /**************************************************************************** @@ -266,123 +280,97 @@ static bool get_group_map_from_ntname(const char *name, GROUP_MAP *map) static bool group_map_remove(const DOM_SID *sid) { - TDB_DATA dbuf; - char *key = NULL; - fstring string_sid; - bool ret; - - /* the key is the SID, retrieving is direct */ - - sid_to_fstring(string_sid, sid); - if (asprintf(&key, "%s%s", GROUP_PREFIX, string_sid) < 0) { - return false; - } + char *key; + bool result; - dbuf = tdb_fetch_bystring(tdb, key); - if (!dbuf.dptr) { - SAFE_FREE(key); + key = group_mapping_key(talloc_tos(), sid); + if (key == NULL) { return false; } - SAFE_FREE(dbuf.dptr); + result = NT_STATUS_IS_OK(dbwrap_delete_bystring(db, key)); - ret = (tdb_delete_bystring(tdb, key) == TDB_SUCCESS); - SAFE_FREE(key); - return ret; + TALLOC_FREE(key); + return result; } /**************************************************************************** Enumerate the group mapping. ****************************************************************************/ -static bool enum_group_mapping(const DOM_SID *domsid, enum lsa_SidType sid_name_use, GROUP_MAP **pp_rmap, - size_t *p_num_entries, bool unix_only) -{ - TDB_DATA kbuf, dbuf, newkey; - fstring string_sid; - GROUP_MAP map; - GROUP_MAP *mapt; - int ret; - size_t entries=0; - DOM_SID grpsid; - uint32 rid; - - *p_num_entries=0; - *pp_rmap=NULL; - - for (kbuf = tdb_firstkey(tdb); - kbuf.dptr; - newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { +struct enum_map_state { + const DOM_SID *domsid; + enum lsa_SidType sid_name_use; + bool unix_only; - if (strncmp((const char *)kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) - continue; - - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) - continue; - - fstrcpy(string_sid, (const char *)kbuf.dptr+strlen(GROUP_PREFIX)); - - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", - &map.gid, &map.sid_name_use, &map.nt_name, &map.comment); - - SAFE_FREE(dbuf.dptr); - - if ( ret == -1 ) { - DEBUG(3,("enum_group_mapping: tdb_unpack failure\n")); - continue; - } - - /* list only the type or everything if UNKNOWN */ - if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) { - DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name)); - continue; - } - - if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) { - DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name)); - continue; - } + size_t num_maps; + GROUP_MAP *maps; +}; - string_to_sid(&grpsid, string_sid); - sid_copy( &map.sid, &grpsid ); - - sid_split_rid( &grpsid, &rid ); +static int collect_map(struct db_record *rec, void *private_data) +{ + struct enum_map_state *state = (struct enum_map_state *)private_data; + GROUP_MAP map; + GROUP_MAP *tmp; - /* Only check the domain if we were given one */ + if (!dbrec2map(rec, &map)) { + return 0; + } + /* list only the type or everything if UNKNOWN */ + if (state->sid_name_use != SID_NAME_UNKNOWN + && state->sid_name_use != map.sid_name_use) { + DEBUG(11,("enum_group_mapping: group %s is not of the " + "requested type\n", map.nt_name)); + return 0; + } - if ( domsid && !sid_equal( domsid, &grpsid ) ) { - DEBUG(11,("enum_group_mapping: group %s is not in " - "domain %s\n", string_sid, - sid_string_dbg(domsid))); - continue; - } + if ((state->unix_only == ENUM_ONLY_MAPPED) && (map.gid == -1)) { + DEBUG(11,("enum_group_mapping: group %s is non mapped\n", + map.nt_name)); + return 0; + } - DEBUG(11,("enum_group_mapping: returning group %s of " - "type %s\n", map.nt_name, - sid_type_lookup(map.sid_name_use))); + if ((state->domsid != NULL) && + (sid_compare_domain(state->domsid, &map.sid) != 0)) { + DEBUG(11,("enum_group_mapping: group %s is not in domain\n", + sid_string_dbg(&map.sid))); + return 0; + } - (*pp_rmap) = SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1); - if (!(*pp_rmap)) { - DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n")); - return False; - } + if (!(tmp = SMB_REALLOC_ARRAY(state->maps, GROUP_MAP, + state->num_maps+1))) { + DEBUG(0,("enum_group_mapping: Unable to enlarge group " + "map!\n")); + return 1; + } - mapt = (*pp_rmap); + state->maps = tmp; + state->maps[state->num_maps] = map; + state->num_maps++; + return 0; +} - mapt[entries].gid = map.gid; - sid_copy( &mapt[entries].sid, &map.sid); - mapt[entries].sid_name_use = map.sid_name_use; - fstrcpy(mapt[entries].nt_name, map.nt_name); - fstrcpy(mapt[entries].comment, map.comment); +static bool enum_group_mapping(const DOM_SID *domsid, + enum lsa_SidType sid_name_use, + GROUP_MAP **pp_rmap, + size_t *p_num_entries, bool unix_only) +{ + struct enum_map_state state; - entries++; + state.domsid = domsid; + state.sid_name_use = sid_name_use; + state.unix_only = unix_only; + state.num_maps = 0; + state.maps = NULL; + if (db->traverse_read(db, collect_map, (void *)&state) != 0) { + return false; } - *p_num_entries=entries; + *pp_rmap = state.maps; + *p_num_entries = state.num_maps; - return True; + return true; } /* This operation happens on session setup, so it should better be fast. We @@ -397,19 +385,19 @@ static NTSTATUS one_alias_membership(const DOM_SID *member, TDB_DATA dbuf; const char *p; NTSTATUS status = NT_STATUS_OK; - TALLOC_CTX *frame; + TALLOC_CTX *frame = talloc_stackframe(); slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, sid_to_fstring(tmp, member)); - dbuf = tdb_fetch_bystring(tdb, key); - + dbuf = dbwrap_fetch_bystring(db, frame, key); if (dbuf.dptr == NULL) { + TALLOC_FREE(frame); return NT_STATUS_OK; } p = (const char *)dbuf.dptr; - frame = talloc_stackframe(); + while (next_token_talloc(frame, &p, &string_sid, " ")) { DOM_SID alias; @@ -424,7 +412,6 @@ static NTSTATUS one_alias_membership(const DOM_SID *member, done: TALLOC_FREE(frame); - SAFE_FREE(dbuf.dptr); return status; } @@ -468,11 +455,11 @@ static bool is_aliasmem(const DOM_SID *alias, const DOM_SID *member) static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) { GROUP_MAP map; - TDB_DATA dbuf; - char *key = NULL; + char *key; fstring string_sid; char *new_memberstring; - int result; + struct db_record *rec; + NTSTATUS status; if (!get_group_map_from_sid(*alias, &map)) return NT_STATUS_NO_SUCH_ALIAS; @@ -485,58 +472,67 @@ static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) return NT_STATUS_MEMBER_IN_ALIAS; sid_to_fstring(string_sid, member); - if (asprintf(&key, "%s%s", MEMBEROF_PREFIX, string_sid) < 0) { + + key = talloc_asprintf(talloc_tos(), "%s%s", MEMBEROF_PREFIX, + string_sid); + if (key == NULL) { return NT_STATUS_NO_MEMORY; } - dbuf = tdb_fetch_bystring(tdb, key); + rec = db->fetch_locked(db, key, string_term_tdb_data(key)); + + if (rec == NULL) { + DEBUG(10, ("fetch_lock failed\n")); + TALLOC_FREE(key); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } sid_to_fstring(string_sid, alias); - if (dbuf.dptr != NULL) { - asprintf(&new_memberstring, "%s %s", (char *)(dbuf.dptr), - string_sid); + if (rec->value.dptr != NULL) { + new_memberstring = talloc_asprintf( + key, "%s %s", (char *)(rec->value.dptr), string_sid); } else { - new_memberstring = SMB_STRDUP(string_sid); + new_memberstring = talloc_strdup(key, string_sid); } if (new_memberstring == NULL) { - SAFE_FREE(key); + TALLOC_FREE(key); return NT_STATUS_NO_MEMORY; } - SAFE_FREE(dbuf.dptr); - dbuf = string_term_tdb_data(new_memberstring); + status = rec->store(rec, string_term_tdb_data(new_memberstring), 0); - result = tdb_store_bystring(tdb, key, dbuf, 0); + TALLOC_FREE(key); - SAFE_FREE(new_memberstring); - SAFE_FREE(key); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("Could not store record: %s\n", nt_errstr(status))); + } - return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED); + return status; } -struct aliasmem_closure { +struct aliasmem_state { const DOM_SID *alias; DOM_SID **sids; size_t *num; }; -static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data, - void *state) +static int collect_aliasmem(struct db_record *rec, void *priv) { - struct aliasmem_closure *closure = (struct aliasmem_closure *)state; + struct aliasmem_state *state = (struct aliasmem_state *)priv; const char *p; char *alias_string; TALLOC_CTX *frame; - if (strncmp((const char *)key.dptr, MEMBEROF_PREFIX, - strlen(MEMBEROF_PREFIX)) != 0) + if (strncmp((const char *)rec->key.dptr, MEMBEROF_PREFIX, + MEMBEROF_PREFIX_LEN) != 0) return 0; - p = (const char *)data.dptr; + p = (const char *)rec->value.dptr; frame = talloc_stackframe(); + while (next_token_talloc(frame, &p, &alias_string, " ")) { DOM_SID alias, member; const char *member_string; @@ -544,14 +540,14 @@ static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data, if (!string_to_sid(&alias, alias_string)) continue; - if (sid_compare(closure->alias, &alias) != 0) + if (sid_compare(state->alias, &alias) != 0) continue; /* Ok, we found the alias we're looking for in the membership * list currently scanned. The key represents the alias * member. Add that. */ - member_string = strchr((const char *)key.dptr, '/'); + member_string = strchr((const char *)rec->key.dptr, '/'); /* Above we tested for MEMBEROF_PREFIX which includes the * slash. */ @@ -563,8 +559,8 @@ static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data, continue; if (!NT_STATUS_IS_OK(add_sid_to_array(NULL, &member, - closure->sids, - closure->num))) + state->sids, + state->num))) { /* talloc fail. */ break; @@ -578,7 +574,7 @@ static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data, static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, size_t *num) { GROUP_MAP map; - struct aliasmem_closure closure; + struct aliasmem_state state; if (!get_group_map_from_sid(*alias, &map)) return NT_STATUS_NO_SUCH_ALIAS; @@ -590,29 +586,28 @@ static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, size_t *num) *sids = NULL; *num = 0; - closure.alias = alias; - closure.sids = sids; - closure.num = num; + state.alias = alias; + state.sids = sids; + state.num = num; - tdb_traverse(tdb, collect_aliasmem, &closure); + db->traverse_read(db, collect_aliasmem, &state); return NT_STATUS_OK; } static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) { - NTSTATUS result; + NTSTATUS status; DOM_SID *sids; size_t i, num; bool found = False; char *member_string; - TDB_DATA dbuf; - char *key = NULL; + char *key; fstring sid_string; - result = alias_memberships(member, 1, &sids, &num); + status = alias_memberships(member, 1, &sids, &num); - if (!NT_STATUS_IS_OK(result)) - return result; + if (!NT_STATUS_IS_OK(status)) + return status; for (i=0; i