diff options
author | Volker Lendecke <vlendec@samba.org> | 2004-11-05 23:34:00 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:53:09 -0500 |
commit | 154d5f913b4ce60f731227eb1bb3650c45fcde93 (patch) | |
tree | 6dcd8538e9cc97c4d891082280055d8fe3c8366a | |
parent | 55fe875a44bd63de766d4fbdb91bcc26be146a21 (diff) | |
download | samba-154d5f913b4ce60f731227eb1bb3650c45fcde93.tar.gz samba-154d5f913b4ce60f731227eb1bb3650c45fcde93.tar.bz2 samba-154d5f913b4ce60f731227eb1bb3650c45fcde93.zip |
r3566: Completely replace the queryuseraliases call. The previous implementation does
not exactly match what you would expect.
XP workstations during login actually do this, so we should better become a
bit more correct. The LDAP query issued is not really fully optimal, but it is
a lot faster and more correct than what was there before. The change in
passdb.h makes it possible that queryuseraliases is done with a single ldap
query.
Volker
(This used to be commit 2508d4ed1e16c268fc9f3676b0c6a122e070f93d)
-rw-r--r-- | source3/groupdb/mapping.c | 35 | ||||
-rw-r--r-- | source3/include/passdb.h | 8 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 10 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 12 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 78 | ||||
-rw-r--r-- | source3/passdb/util_sam_sid.c | 13 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 79 | ||||
-rw-r--r-- | source3/rpc_server/srv_util.c | 175 | ||||
-rw-r--r-- | source3/utils/net_groupmap.c | 2 |
9 files changed, 131 insertions, 281 deletions
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 50064415f9..072304ed18 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -496,21 +496,19 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, /* This operation happens on session setup, so it should better be fast. We * store a list of aliases a SID is member of hanging off MEMBEROF/SID. */ -static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num) +static NTSTATUS one_alias_membership(const DOM_SID *member, + DOM_SID **sids, int *num) { fstring key, string_sid; TDB_DATA kbuf, dbuf; const char *p; - *num = 0; - *sids = NULL; - if (!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping\n")); return NT_STATUS_ACCESS_DENIED; } - sid_to_string(string_sid, sid); + sid_to_string(string_sid, member); slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid); kbuf.dsize = strlen(key)+1; @@ -531,7 +529,7 @@ static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num) if (!string_to_sid(&alias, string_sid)) continue; - add_sid_to_array(&alias, sids, num); + add_sid_to_array_unique(&alias, sids, num); if (sids == NULL) return NT_STATUS_NO_MEMORY; @@ -541,6 +539,22 @@ static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num) return NT_STATUS_OK; } +static NTSTATUS alias_memberships(const DOM_SID *members, int num_members, + DOM_SID **sids, int *num) +{ + int i; + + *num = 0; + *sids = NULL; + + for (i=0; i<num_members; i++) { + NTSTATUS status = one_alias_membership(&members[i], sids, num); + if (!NT_STATUS_IS_OK(status)) + return status; + } + return NT_STATUS_OK; +} + static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member) { DOM_SID *sids; @@ -548,7 +562,7 @@ static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member) /* This feels the wrong way round, but the on-disk data structure * dictates it this way. */ - if (!NT_STATUS_IS_OK(alias_memberships(member, &sids, &num))) + if (!NT_STATUS_IS_OK(alias_memberships(member, 1, &sids, &num))) return False; for (i=0; i<num; i++) { @@ -707,7 +721,7 @@ static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) pstring key; fstring sid_string; - result = alias_memberships(member, &sids, &num); + result = alias_memberships(member, 1, &sids, &num); if (!NT_STATUS_IS_OK(result)) return result; @@ -1343,10 +1357,11 @@ NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods, } NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods, - const DOM_SID *sid, + const DOM_SID *members, + int num_members, DOM_SID **aliases, int *num) { - return alias_memberships(sid, aliases, num); + return alias_memberships(members, num_members, aliases, num); } /********************************************************************** diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 7d3e0014b6..8219e90f2b 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -323,9 +323,10 @@ typedef struct pdb_context DOM_SID **members, int *num_members); NTSTATUS (*pdb_enum_alias_memberships)(struct pdb_context *context, - const DOM_SID *alias, + const DOM_SID *members, + int num_members, DOM_SID **aliases, - int *num); + int *num_aliases); void (*free_fn)(struct pdb_context **); @@ -408,7 +409,8 @@ typedef struct pdb_methods const DOM_SID *alias, DOM_SID **members, int *num_members); NTSTATUS (*enum_alias_memberships)(struct pdb_methods *methods, - const DOM_SID *sid, + const DOM_SID *members, + int num_members, DOM_SID **aliases, int *num); void *private_data; /* Private data of some kind */ diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 8ab5150bbe..eec0f72217 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -936,7 +936,7 @@ static void add_local_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num) /* Add nested group memberships */ - if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) + if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases)) return; for (j=0; j<num_aliases; j++) { @@ -1146,7 +1146,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) return result; } -static void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid, +static void add_sid_to_parray_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid, DOM_SID ***sids, int *num_sids) { int i; @@ -1174,15 +1174,15 @@ static void add_local_sids_from_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, DOM_SID *aliases = NULL; int i, num_aliases = 0; - if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) + if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases)) return; if (num_aliases == 0) return; for (i=0; i<num_aliases; i++) - add_sid_to_array_unique(mem_ctx, &aliases[i], user_grpsids, - num_groups); + add_sid_to_parray_unique(mem_ctx, &aliases[i], user_grpsids, + num_groups); SAFE_FREE(aliases); diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index d65b1b3463..5747435e69 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -587,7 +587,8 @@ static NTSTATUS context_enum_aliasmem(struct pdb_context *context, } static NTSTATUS context_enum_alias_memberships(struct pdb_context *context, - const DOM_SID *sid, + const DOM_SID *members, + int num_members, DOM_SID **aliases, int *num) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; @@ -598,8 +599,8 @@ static NTSTATUS context_enum_alias_memberships(struct pdb_context *context, } return context->pdb_methods-> - enum_alias_memberships(context->pdb_methods, sid, aliases, - num); + enum_alias_memberships(context->pdb_methods, members, + num_members, aliases, num); } /****************************************************************** @@ -1125,7 +1126,7 @@ BOOL pdb_enum_aliasmem(const DOM_SID *alias, members, num_members)); } -BOOL pdb_enum_alias_memberships(const DOM_SID *sid, +BOOL pdb_enum_alias_memberships(const DOM_SID *members, int num_members, DOM_SID **aliases, int *num) { struct pdb_context *pdb_context = pdb_get_static_context(False); @@ -1135,7 +1136,8 @@ BOOL pdb_enum_alias_memberships(const DOM_SID *sid, } return NT_STATUS_IS_OK(pdb_context-> - pdb_enum_alias_memberships(pdb_context, sid, + pdb_enum_alias_memberships(pdb_context, members, + num_members, aliases, num)); } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index f7ee8dcb42..058ecb04d3 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -2733,71 +2733,73 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods, } static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, - const DOM_SID *sid, - DOM_SID **aliases, int *num) + const DOM_SID *members, + int num_members, + DOM_SID **aliases, int *num_aliases) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data; + LDAP *ldap_struct; - fstring sid_string; const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL }; LDAPMessage *result = NULL; LDAPMessage *entry = NULL; - int count; + int i; int rc; - pstring filter; + char *filter; + TALLOC_CTX *mem_ctx; - sid_to_string(sid_string, sid); - pstr_sprintf(filter, "(&(|(objectclass=%s)(objectclass=%s))(%s=%s))", - LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY, - get_attr_key2string(groupmap_attr_list, - LDAP_ATTR_SID_LIST), sid_string); + mem_ctx = talloc_init("ldapsam_alias_memberships"); + + if (mem_ctx == NULL) + return NT_STATUS_NO_MEMORY; + + /* This query could be further optimized by adding a + (&(sambaSID=<domain-sid>*)) so that only those aliases that are + asked for in the getuseraliases are returned. */ + + filter = talloc_asprintf(mem_ctx, + "(&(|(objectclass=%s)(objectclass=%s))(|", + LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY); + + for (i=0; i<num_members; i++) + filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)", + filter, + sid_string_static(&members[i])); + + filter = talloc_asprintf(mem_ctx, "%s))", filter); rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(), LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result); + talloc_destroy(mem_ctx); + if (rc != LDAP_SUCCESS) return NT_STATUS_UNSUCCESSFUL; *aliases = NULL; - *num = 0; - - count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, - result); - - if (count < 1) { - ldap_msgfree(result); - return NT_STATUS_OK; - } + *num_aliases = 0; + ldap_struct = ldap_state->smbldap_state->ldap_struct; - for (entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, - result); + for (entry = ldap_first_entry(ldap_struct, result); entry != NULL; - entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, - entry)) + entry = ldap_next_entry(ldap_struct, entry)) { - DOM_SID alias; - char **vals; - vals = ldap_get_values(ldap_state->smbldap_state->ldap_struct, - entry, LDAP_ATTRIBUTE_SID); - - if (vals == NULL) - continue; + fstring sid_str; + DOM_SID sid; - if (vals[0] == NULL) { - ldap_value_free(vals); + if (!smbldap_get_single_attribute(ldap_struct, entry, + LDAP_ATTRIBUTE_SID, + sid_str, + sizeof(sid_str)-1)) continue; - } - if (!string_to_sid(&alias, vals[0])) { - ldap_value_free(vals); + if (!string_to_sid(&sid, sid_str)) continue; - } - add_sid_to_array(&alias, aliases, num); - ldap_value_free(vals); + add_sid_to_array_unique(&sid, aliases, num_aliases); } ldap_msgfree(result); diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index c13159e47f..204f68c121 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -327,3 +327,16 @@ void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num) return; } + + +void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids) +{ + int i; + + for (i=0; i<(*num_sids); i++) { + if (sid_compare(sid, &(*sids)[i]) == 0) + return; + } + + return add_sid_to_array(sid, sids, num_sids); +} diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 37617db5e8..f4348fc83e 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3119,31 +3119,19 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u) { - int num_groups = 0, tmp_num_groups=0; - uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL; + int num_groups = 0; + uint32 *rids=NULL; struct samr_info *info = NULL; - int i,j; + int i; NTSTATUS ntstatus1; NTSTATUS ntstatus2; - /* until i see a real useraliases query, we fack one up */ + DOM_SID *members; + DOM_SID *aliases; + int num_aliases; + BOOL res; - /* I have seen one, JFM 2/12/2001 */ - /* - * Explanation of what this call does: - * for all the SID given in the request: - * return a list of alias (local groups) - * that have those SID as members. - * - * and that's the alias in the domain specified - * in the policy_handle - * - * if the policy handle is on an incorrect sid - * for example a user's sid - * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH - */ - r_u->status = NT_STATUS_OK; DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__)); @@ -3166,40 +3154,43 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, !sid_check_is_builtin(&info->sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; + members = talloc(p->mem_ctx, sizeof(DOM_SID) * q_u->num_sids1); - for (i=0; i<q_u->num_sids1; i++) { + if (members == NULL) + return NT_STATUS_NO_MEMORY; - r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid)); + for (i=0; i<q_u->num_sids1; i++) + sid_copy(&members[i], &q_u->sid[i].sid); - /* - * if there is an error, we just continue as - * it can be an unfound user or group - */ - if (!NT_STATUS_IS_OK(r_u->status)) { - DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n")); - continue; - } + become_root(); + res = pdb_enum_alias_memberships(members, + q_u->num_sids1, &aliases, + &num_aliases); + unbecome_root(); + + if (!res) + return NT_STATUS_UNSUCCESSFUL; - if (tmp_num_groups==0) { - DEBUG(10,("_samr_query_useraliases: no groups found\n")); + rids = NULL; + num_groups = 0; + + for (i=0; i<num_aliases; i++) { + uint32 rid; + + if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid)) continue; - } - new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32)); - if (new_rids==NULL) { - DEBUG(0,("_samr_query_useraliases: could not realloc memory\n")); + rids = talloc_realloc(p->mem_ctx, rids, + sizeof(*rids) * (num_groups+1)); + + if (rids == NULL) return NT_STATUS_NO_MEMORY; - } - rids=new_rids; - for (j=0; j<tmp_num_groups; j++) - rids[j+num_groups]=tmp_rids[j]; - - safe_free(tmp_rids); - - num_groups+=tmp_num_groups; + rids[num_groups] = rid; + num_groups += 1; } - + SAFE_FREE(aliases); + init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK); return NT_STATUS_OK; } diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index ce8e02fae7..215471b444 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -82,181 +82,6 @@ static const rid_name domain_group_rids[] = /******************************************************************* gets a domain user's groups ********************************************************************/ -NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, uint32 **prids, DOM_SID *q_sid) -{ - SAM_ACCOUNT *sam_pass=NULL; - int i, cur_rid=0; - gid_t gid; - gid_t *groups = NULL; - int num_groups; - GROUP_MAP map; - DOM_SID tmp_sid; - fstring user_name; - fstring str_domsid, str_qsid; - uint32 rid,grid; - uint32 *rids=NULL, *new_rids=NULL; - gid_t winbind_gid_low, winbind_gid_high; - BOOL ret; - BOOL winbind_groups_exist; - - *prids=NULL; - *numgroups=0; - - winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high); - - - DEBUG(10,("get_alias_user_groups: looking if SID %s is a member of groups in the SID domain %s\n", - sid_to_string(str_qsid, q_sid), sid_to_string(str_domsid, sid))); - - pdb_init_sam(&sam_pass); - become_root(); - ret = pdb_getsampwsid(sam_pass, q_sid); - unbecome_root(); - if (ret == False) { - pdb_free_sam(&sam_pass); - return NT_STATUS_NO_SUCH_USER; - } - - fstrcpy(user_name, pdb_get_username(sam_pass)); - grid=pdb_get_group_rid(sam_pass); - if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sam_pass), &gid))) { - /* this should never happen */ - DEBUG(2,("get_alias_user_groups: sid_to_gid failed!\n")); - pdb_free_sam(&sam_pass); - return NT_STATUS_UNSUCCESSFUL; - } - - ret = getgroups_user(user_name, &groups, &num_groups); - if (!ret) { - /* this should never happen */ - DEBUG(2,("get_alias_user_groups: getgroups_user failed\n")); - pdb_free_sam(&sam_pass); - return NT_STATUS_UNSUCCESSFUL; - } - - for (i=0;i<num_groups;i++) { - - become_root(); - ret = get_group_from_gid(groups[i], &map); - unbecome_root(); - - if ( !ret ) { - DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)groups[i])); - continue; - } - - /* if it's not an alias, continue */ - if (map.sid_name_use != SID_NAME_ALIAS) { - DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name)); - continue; - } - - sid_copy(&tmp_sid, &map.sid); - sid_split_rid(&tmp_sid, &rid); - - /* if the sid is not in the correct domain, continue */ - if (!sid_equal(&tmp_sid, sid)) { - DEBUG(10,("get_alias_user_groups: not returing %s, not in the domain SID.\n", map.nt_name)); - continue; - } - - /* Don't return winbind groups as they are not local! */ - if (winbind_groups_exist && (groups[i] >= winbind_gid_low) && (groups[i] <= winbind_gid_high)) { - DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name)); - continue; - } - - /* Don't return user private groups... */ - if (Get_Pwnam(map.nt_name) != 0) { - DEBUG(10,("get_alias_user_groups: not returing %s, clashes with user.\n", map.nt_name)); - continue; - } - - new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1)); - if (new_rids==NULL) { - DEBUG(10,("get_alias_user_groups: could not realloc memory\n")); - pdb_free_sam(&sam_pass); - free(groups); - return NT_STATUS_NO_MEMORY; - } - rids=new_rids; - - sid_peek_rid(&map.sid, &(rids[cur_rid])); - cur_rid++; - break; - } - - if(num_groups) - free(groups); - - /* now check for the user's gid (the primary group rid) */ - for (i=0; i<cur_rid && grid!=rids[i]; i++) - ; - - /* the user's gid is already there */ - if (i!=cur_rid) { - DEBUG(10,("get_alias_user_groups: user is already in the list. good.\n")); - goto done; - } - - DEBUG(10,("get_alias_user_groups: looking for gid %d of user %s\n", (int)gid, user_name)); - - if(!get_group_from_gid(gid, &map)) { - DEBUG(0,("get_alias_user_groups: gid of user %s doesn't exist. Check your " - "/etc/passwd and /etc/group files\n", user_name)); - goto done; - } - - /* the primary group isn't an alias */ - if (map.sid_name_use!=SID_NAME_ALIAS) { - DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name)); - goto done; - } - - sid_copy(&tmp_sid, &map.sid); - sid_split_rid(&tmp_sid, &rid); - - /* if the sid is not in the correct domain, continue */ - if (!sid_equal(&tmp_sid, sid)) { - DEBUG(10,("get_alias_user_groups: not returing %s, not in the domain SID.\n", map.nt_name)); - goto done; - } - - /* Don't return winbind groups as they are not local! */ - if (winbind_groups_exist && (gid >= winbind_gid_low) && (gid <= winbind_gid_high)) { - DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name )); - goto done; - } - - /* Don't return user private groups... */ - if (Get_Pwnam(map.nt_name) != 0) { - DEBUG(10,("get_alias_user_groups: not returing %s, clashes with user.\n", map.nt_name )); - goto done; - } - - new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1)); - if (new_rids==NULL) { - DEBUG(10,("get_alias_user_groups: could not realloc memory\n")); - pdb_free_sam(&sam_pass); - return NT_STATUS_NO_MEMORY; - } - rids=new_rids; - - sid_peek_rid(&map.sid, &(rids[cur_rid])); - cur_rid++; - -done: - *prids=rids; - *numgroups=cur_rid; - pdb_free_sam(&sam_pass); - - return NT_STATUS_OK; -} - - -/******************************************************************* - gets a domain user's groups - ********************************************************************/ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SAM_ACCOUNT *sam_pass) { diff --git a/source3/utils/net_groupmap.c b/source3/utils/net_groupmap.c index 3431196b1e..b2d96041dc 100644 --- a/source3/utils/net_groupmap.c +++ b/source3/utils/net_groupmap.c @@ -689,7 +689,7 @@ static int net_groupmap_memberships(int argc, const char **argv) return -1; } - if (!pdb_enum_alias_memberships(&member, &aliases, &num)) { + if (!pdb_enum_alias_memberships(&member, 1, &aliases, &num)) { d_printf("Could not list memberships for sid %s: %s\n", argv[0], nt_errstr(result)); return -1; |