summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2004-02-29 16:48:19 +0000
committerVolker Lendecke <vlendec@samba.org>2004-02-29 16:48:19 +0000
commit0d45ad1b0d55546c6a4afcb002acefefc2e2feb0 (patch)
tree34fa0e74191cef6a5070a0e1499c919a43b4f64d
parent4628a2da1e32f397696640452c950e4b55ada9e7 (diff)
downloadsamba-0d45ad1b0d55546c6a4afcb002acefefc2e2feb0.tar.gz
samba-0d45ad1b0d55546c6a4afcb002acefefc2e2feb0.tar.bz2
samba-0d45ad1b0d55546c6a4afcb002acefefc2e2feb0.zip
Apply my experimental aliases support to HEAD. This will be a bit difficult to
merge to 3_0, as the pdb interfaces has changed a bit between the two. This has not been tested too severly (which means it's completely broken ;-), but I want it in for review. Feel free to revert it :-) TODO: make 'net groupmap' a bit more friendly for alias members. Put that stuff into pdb_ldap. Getting the information over to winbind. One plan without linking pdb into winbind would be to fill group_mapping.tdb with the membership information and have that as a cache (or use gencache.tdb?). smbd on a PDC or stand-alone could trigger that itself, the problem is a BDC using LDAP. This needs to do it on a regular basis. The BDC smbd needs to be informed about SAM changes somehow... Volker (This used to be commit 30ef8fe1e85c0ca229b54f3f1595c4330f7191d1)
-rw-r--r--source3/auth/auth_util.c66
-rw-r--r--source3/groupdb/mapping.c282
-rw-r--r--source3/include/passdb.h28
-rw-r--r--source3/passdb/pdb_interface.c121
-rw-r--r--source3/rpc_server/srv_samr_nt.c9
-rw-r--r--source3/utils/net_groupmap.c112
6 files changed, 614 insertions, 4 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 0f945b33cb..912432b98f 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -635,6 +635,70 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
return token;
}
+static void add_gid_to_array_unique(gid_t gid, gid_t **groups, int *ngroups)
+{
+ int i;
+
+ if ((*ngroups) >= groups_max())
+ return;
+
+ for (i=0; i<*ngroups; i++) {
+ if ((*groups)[i] == gid)
+ return;
+ }
+
+ *groups = Realloc(*groups, ((*ngroups)+1) * sizeof(gid_t));
+
+ if (*groups == NULL)
+ return;
+
+ (*groups)[*ngroups] = gid;
+ *ngroups += 1;
+}
+
+static void add_foreign_gids_from_sid(const DOM_SID *sid, gid_t **groups,
+ int *ngroups)
+{
+ DOM_SID *aliases;
+ int j, num_aliases;
+
+ if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases))
+ return;
+
+ for (j=0; j<num_aliases; j++) {
+ gid_t gid;
+
+ if (!NT_STATUS_IS_OK(sid_to_gid(&aliases[j], &gid)))
+ continue;
+
+ add_gid_to_array_unique(gid, groups, ngroups);
+ }
+ SAFE_FREE(aliases);
+}
+
+static void add_foreign_gids(uid_t uid, gid_t gid,
+ gid_t **groups, int *ngroups)
+{
+ int i, dom_groups;
+ DOM_SID sid;
+
+ if (NT_STATUS_IS_OK(uid_to_sid(&sid, uid)))
+ add_foreign_gids_from_sid(&sid, groups, ngroups);
+
+ if (NT_STATUS_IS_OK(gid_to_sid(&sid, gid)))
+ add_foreign_gids_from_sid(&sid, groups, ngroups);
+
+ dom_groups = *ngroups;
+
+ for (i=0; i<dom_groups; i++) {
+
+ if (!NT_STATUS_IS_OK(gid_to_sid(&sid, (*groups)[i])))
+ continue;
+
+ add_foreign_gids_from_sid(&sid, groups, ngroups);
+ }
+}
+
/******************************************************************************
* this function returns the groups (SIDs) of the local SAM the user is in.
* If this samba server is a DC of the domain the user belongs to, it returns
@@ -699,6 +763,8 @@ static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid,
}
}
+ add_foreign_gids(uid, gid, unix_groups, &n_unix_groups);
+
debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
/* now setup the space for storing the SIDS */
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c
index 71ef38e6c8..5eaa4e1386 100644
--- a/source3/groupdb/mapping.c
+++ b/source3/groupdb/mapping.c
@@ -27,6 +27,7 @@ static TDB_CONTEXT *tdb; /* used for driver files */
#define DATABASE_VERSION_V2 2 /* le format. */
#define GROUP_PREFIX "UNIXGROUP/"
+#define ALIASMEM_PREFIX "ALIASMEMBERS/"
PRIVS privs[] = {
{SE_PRIV_NONE, "no_privs", "No privilege" }, /* this one MUST be first */
@@ -489,6 +490,246 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
return True;
}
+static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+{
+ GROUP_MAP map;
+ TDB_DATA kbuf, dbuf;
+ pstring key;
+ fstring string_sid;
+ char *new_memberstring;
+ int result;
+
+ if(!init_group_mapping()) {
+ DEBUG(0,("failed to initialize group mapping"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!get_group_map_from_sid(*alias, &map))
+ return NT_STATUS_NO_SUCH_ALIAS;
+
+ if ( (map.sid_name_use != SID_NAME_ALIAS) &&
+ (map.sid_name_use != SID_NAME_WKN_GRP) )
+ return NT_STATUS_NO_SUCH_ALIAS;
+
+ sid_to_string(string_sid, alias);
+ slprintf(key, sizeof(key), "%s%s", ALIASMEM_PREFIX, string_sid);
+
+ kbuf.dsize = strlen(key)+1;
+ kbuf.dptr = key;
+
+ dbuf = tdb_fetch(tdb, kbuf);
+
+ sid_to_string(string_sid, member);
+
+ if (dbuf.dptr != NULL) {
+ asprintf(&new_memberstring, "%s %s", (char *)(dbuf.dptr),
+ string_sid);
+ } else {
+ new_memberstring = strdup(string_sid);
+ }
+
+ if (new_memberstring == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ SAFE_FREE(dbuf.dptr);
+ dbuf.dsize = strlen(new_memberstring)+1;
+ dbuf.dptr = new_memberstring;
+
+ result = tdb_store(tdb, kbuf, dbuf, 0);
+
+ SAFE_FREE(new_memberstring);
+
+ return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED);
+}
+
+static BOOL add_sid_to_array(DOM_SID sid, DOM_SID **sids, int *num)
+{
+ *sids = Realloc(*sids, ((*num)+1) * sizeof(DOM_SID));
+
+ if (*sids == NULL)
+ return False;
+
+ sid_copy(&((*sids)[*num]), &sid);
+ *num += 1;
+
+ return True;
+}
+
+static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num)
+{
+ GROUP_MAP map;
+ TDB_DATA kbuf, dbuf;
+ pstring key;
+ fstring string_sid;
+ const char *p;
+
+ if(!init_group_mapping()) {
+ DEBUG(0,("failed to initialize group mapping"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!get_group_map_from_sid(*alias, &map))
+ return NT_STATUS_NO_SUCH_ALIAS;
+
+ if ( (map.sid_name_use != SID_NAME_ALIAS) &&
+ (map.sid_name_use != SID_NAME_WKN_GRP) )
+ return NT_STATUS_NO_SUCH_ALIAS;
+
+ *sids = NULL;
+ *num = 0;
+
+ sid_to_string(string_sid, alias);
+ slprintf(key, sizeof(key), "%s%s", ALIASMEM_PREFIX, string_sid);
+
+ kbuf.dsize = strlen(key)+1;
+ kbuf.dptr = key;
+
+ dbuf = tdb_fetch(tdb, kbuf);
+
+ if (dbuf.dptr == NULL) {
+ return NT_STATUS_OK;
+ }
+
+ p = dbuf.dptr;
+
+ while (next_token(&p, string_sid, " ", sizeof(string_sid))) {
+
+ DOM_SID sid;
+
+ if (!string_to_sid(&sid, string_sid))
+ continue;
+
+ if (!add_sid_to_array(sid, sids, num))
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ SAFE_FREE(dbuf.dptr);
+
+ return NT_STATUS_OK;
+}
+
+/* This is racy as hell, but hey, it's only a prototype :-) */
+
+static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+{
+ NTSTATUS result;
+ DOM_SID *sids;
+ int i, num;
+ BOOL found = False;
+ char *member_string;
+ TDB_DATA kbuf, dbuf;
+ pstring key;
+ fstring sid_string;
+
+ result = enum_aliasmem(alias, &sids, &num);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ for (i=0; i<num; i++) {
+ if (sid_compare(&sids[i], member) == 0) {
+ found = True;
+ break;
+ }
+ }
+
+ if (!found) {
+ SAFE_FREE(sids);
+ return NT_STATUS_MEMBER_NOT_IN_ALIAS;
+ }
+
+ if (i < num)
+ sids[i] = sids[num-1];
+
+ num -= 1;
+
+ member_string = strdup("");
+
+ if (member_string == NULL) {
+ SAFE_FREE(sids);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<num; i++) {
+ char *s = member_string;
+
+ sid_to_string(sid_string, &sids[i]);
+ asprintf(&member_string, "%s %s", s, sid_string);
+
+ SAFE_FREE(s);
+ if (member_string == NULL) {
+ SAFE_FREE(sids);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ sid_to_string(sid_string, alias);
+ slprintf(key, sizeof(key), "%s%s", ALIASMEM_PREFIX, sid_string);
+
+ kbuf.dsize = strlen(key)+1;
+ kbuf.dptr = key;
+ dbuf.dsize = strlen(member_string)+1;
+ dbuf.dptr = member_string;
+
+ result = tdb_store(tdb, kbuf, dbuf, 0) == 0 ?
+ NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
+
+ SAFE_FREE(sids);
+ SAFE_FREE(member_string);
+
+ return result;
+}
+
+static BOOL is_foreign_alias_member(const DOM_SID *sid, const DOM_SID *alias)
+{
+ DOM_SID *members;
+ int i, num;
+ BOOL result = False;
+
+ if (!NT_STATUS_IS_OK(enum_aliasmem(alias, &members, &num)))
+ return False;
+
+ for (i=0; i<num; i++) {
+
+ if (sid_compare(&members[i], sid) == 0) {
+ result = True;
+ break;
+ }
+ }
+
+ SAFE_FREE(members);
+ return result;
+}
+
+static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num)
+{
+ GROUP_MAP *maps;
+ int i, num_maps;
+
+ *num = 0;
+ *sids = NULL;
+
+ if (!enum_group_mapping(SID_NAME_WKN_GRP, &maps, &num_maps, False))
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<num_maps; i++) {
+ if (is_foreign_alias_member(sid, &maps[i].sid))
+ add_sid_to_array(maps[i].sid, sids, num);
+ }
+ SAFE_FREE(maps);
+
+ if (!enum_group_mapping(SID_NAME_ALIAS, &maps, &num_maps, False))
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<num_maps; i++) {
+ if (is_foreign_alias_member(sid, &maps[i].sid))
+ add_sid_to_array(maps[i].sid, sids, num);
+ }
+ SAFE_FREE(maps);
+
+ return NT_STATUS_OK;
+}
+
/*
*
* High level functions
@@ -568,7 +809,8 @@ BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
if ( !ret )
return False;
- if ( (map->sid_name_use != SID_NAME_ALIAS)
+ if ( ( (map->sid_name_use != SID_NAME_ALIAS) &&
+ (map->sid_name_use != SID_NAME_WKN_GRP) )
|| (map->gid == -1)
|| (getgrgid(map->gid) == NULL) )
{
@@ -704,6 +946,9 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids)
int i=0;
char *gr;
DOM_SID *s;
+ DOM_SID sid;
+ DOM_SID *members;
+ int num_members;
struct sys_pwent *userlist;
struct sys_pwent *user;
@@ -803,6 +1048,15 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids)
DEBUG(10, ("got primary groups, members: [%d]\n", *num_sids));
winbind_on();
+
+ if ( NT_STATUS_IS_OK(gid_to_sid(&sid, gid)) &&
+ NT_STATUS_IS_OK(enum_aliasmem(&sid, &members, &num_members)) ) {
+
+ for (i=0; i<num_members; i++) {
+ add_sid_to_array(members[i], sids, num_sids);
+ }
+ }
+
return True;
}
@@ -1029,6 +1283,32 @@ NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
+NTSTATUS pdb_default_add_aliasmem(struct pdb_methods *methods,
+ const DOM_SID *alias, const DOM_SID *member)
+{
+ return add_aliasmem(alias, member);
+}
+
+NTSTATUS pdb_default_del_aliasmem(struct pdb_methods *methods,
+ const DOM_SID *alias, const DOM_SID *member)
+{
+ return del_aliasmem(alias, member);
+}
+
+NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods,
+ const DOM_SID *alias, DOM_SID **members,
+ int *num_members)
+{
+ return enum_aliasmem(alias, members, num_members);
+}
+
+NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
+ const DOM_SID *sid,
+ DOM_SID **aliases, int *num)
+{
+ return alias_memberships(sid, aliases, num);
+}
+
/**********************************************************************
no ops for passdb backends that don't implement group mapping
*********************************************************************/
diff --git a/source3/include/passdb.h b/source3/include/passdb.h
index 6489704fdd..668bbcc2de 100644
--- a/source3/include/passdb.h
+++ b/source3/include/passdb.h
@@ -310,6 +310,23 @@ typedef struct pdb_context
GROUP_MAP **rmap, int *num_entries,
BOOL unix_only);
+ NTSTATUS (*pdb_add_aliasmem)(struct pdb_context *context,
+ const DOM_SID *alias,
+ const DOM_SID *member);
+
+ NTSTATUS (*pdb_del_aliasmem)(struct pdb_context *context,
+ const DOM_SID *alias,
+ const DOM_SID *member);
+
+ NTSTATUS (*pdb_enum_aliasmem)(struct pdb_context *context,
+ const DOM_SID *alias,
+ DOM_SID **members, int *num_members);
+
+ NTSTATUS (*pdb_enum_alias_memberships)(struct pdb_context *context,
+ const DOM_SID *alias,
+ DOM_SID **aliases,
+ int *num);
+
/* group functions */
NTSTATUS (*pdb_get_group_info_by_sid)(struct pdb_context *context, GROUP_INFO *info, const DOM_SID *group);
@@ -399,6 +416,17 @@ typedef struct pdb_methods
GROUP_MAP **rmap, int *num_entries,
BOOL unix_only);
+ NTSTATUS (*add_aliasmem)(struct pdb_methods *methods,
+ const DOM_SID *alias, const DOM_SID *member);
+ NTSTATUS (*del_aliasmem)(struct pdb_methods *methods,
+ const DOM_SID *alias, const DOM_SID *member);
+ NTSTATUS (*enum_aliasmem)(struct pdb_methods *methods,
+ const DOM_SID *alias, DOM_SID **members,
+ int *num_members);
+ NTSTATUS (*enum_alias_memberships)(struct pdb_methods *methods,
+ const DOM_SID *sid,
+ DOM_SID **aliases, int *num);
+
/* group functions */
NTSTATUS (*get_group_info_by_sid)(struct pdb_methods *methods, GROUP_INFO *info, const DOM_SID *group);
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 581fac364a..83aebf654a 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -426,6 +426,67 @@ static NTSTATUS context_enum_group_mapping(struct pdb_context *context,
num_entries, unix_only);
}
+static NTSTATUS context_add_aliasmem(struct pdb_context *context,
+ const DOM_SID *alias,
+ const DOM_SID *member)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return ret;
+ }
+
+ return context->pdb_methods->add_aliasmem(context->pdb_methods,
+ alias, member);
+}
+
+static NTSTATUS context_del_aliasmem(struct pdb_context *context,
+ const DOM_SID *alias,
+ const DOM_SID *member)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return ret;
+ }
+
+ return context->pdb_methods->del_aliasmem(context->pdb_methods,
+ alias, member);
+}
+
+static NTSTATUS context_enum_aliasmem(struct pdb_context *context,
+ const DOM_SID *alias, DOM_SID **members,
+ int *num)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return ret;
+ }
+
+ return context->pdb_methods->enum_aliasmem(context->pdb_methods,
+ alias, members, num);
+}
+
+static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
+ const DOM_SID *sid,
+ DOM_SID **aliases, int *num)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return ret;
+ }
+
+ return context->pdb_methods->
+ enum_alias_memberships(context->pdb_methods, sid, aliases,
+ num);
+}
+
static NTSTATUS context_gettrustpwent(struct pdb_context *context,
SAM_TRUST_PASSWD *trust)
{
@@ -641,6 +702,10 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
(*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry;
(*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry;
(*context)->pdb_enum_group_mapping = context_enum_group_mapping;
+ (*context)->pdb_add_aliasmem = context_add_aliasmem;
+ (*context)->pdb_del_aliasmem = context_del_aliasmem;
+ (*context)->pdb_enum_aliasmem = context_enum_aliasmem;
+ (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
(*context)->pdb_gettrustpwent = context_gettrustpwent;
(*context)->pdb_gettrustpwsid = context_gettrustpwsid;
(*context)->pdb_add_trust_passwd = context_add_trust_passwd;
@@ -955,6 +1020,58 @@ BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
rmap, num_entries, unix_only));
}
+BOOL pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return NT_STATUS_IS_OK(pdb_context->
+ pdb_add_aliasmem(pdb_context, alias, member));
+}
+
+BOOL pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return NT_STATUS_IS_OK(pdb_context->
+ pdb_add_aliasmem(pdb_context, alias, member));
+}
+
+BOOL pdb_enum_aliasmem(const DOM_SID *alias,
+ DOM_SID **members, int *num_members)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return NT_STATUS_IS_OK(pdb_context->
+ pdb_enum_aliasmem(pdb_context, alias,
+ members, num_members));
+}
+
+BOOL pdb_enum_alias_memberships(const DOM_SID *sid,
+ DOM_SID **aliases, int *num)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return NT_STATUS_IS_OK(pdb_context->
+ pdb_enum_alias_memberships(pdb_context, sid,
+ aliases, num));
+}
+
/***************************************************************
Initialize the static context (at smbd startup etc).
@@ -1065,6 +1182,10 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
(*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
(*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
(*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
+ (*methods)->add_aliasmem = pdb_default_add_aliasmem;
+ (*methods)->del_aliasmem = pdb_default_del_aliasmem;
+ (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
+ (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
(*methods)->gettrustpwent = pdb_default_gettrustpwent;
(*methods)->gettrustpwsid = pdb_default_gettrustpwsid;
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index a817627127..b50d44d9e3 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -3381,7 +3381,8 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD
if (check != True) {
pdb_free_sam(&sam_user);
- return NT_STATUS_NO_SUCH_USER;
+ return pdb_add_aliasmem(&alias_sid, &q_u->sid.sid) ?
+ NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/* check a real user exist before we run the script to add a user to a group */
@@ -3457,7 +3458,8 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
return NT_STATUS_NO_SUCH_ALIAS;
}
- if( !get_local_group_from_sid(&alias_sid, &map))
+ if( !get_local_group_from_sid(&alias_sid, &map) &&
+ !get_builtin_group_from_sid(&alias_sid, &map) )
return NT_STATUS_NO_SUCH_ALIAS;
if ((grp=getgrgid(map.gid)) == NULL)
@@ -3471,7 +3473,8 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_SUCH_USER;
+ return pdb_del_aliasmem(&alias_sid, &q_u->sid.sid) ?
+ NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/* if the user is not in the group */
diff --git a/source3/utils/net_groupmap.c b/source3/utils/net_groupmap.c
index 2b487ef17b..48406f72b8 100644
--- a/source3/utils/net_groupmap.c
+++ b/source3/utils/net_groupmap.c
@@ -608,6 +608,104 @@ static int net_groupmap_cleanup(int argc, const char **argv)
return 0;
}
+static int net_groupmap_addmem(int argc, const char **argv)
+{
+ DOM_SID alias, member;
+ NTSTATUS result;
+
+ if ( (argc != 2) ||
+ !string_to_sid(&alias, argv[0]) ||
+ !string_to_sid(&member, argv[1]) ) {
+ d_printf("Usage: net groupmap addmem alias-sid member-sid\n");
+ return -1;
+ }
+
+ if (!pdb_add_aliasmem(&alias, &member)) {
+ d_printf("Could not add sid %s to alias %s: %s\n",
+ argv[1], argv[0], nt_errstr(result));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int net_groupmap_delmem(int argc, const char **argv)
+{
+ DOM_SID alias, member;
+ NTSTATUS result;
+
+ if ( (argc != 2) ||
+ !string_to_sid(&alias, argv[0]) ||
+ !string_to_sid(&member, argv[1]) ) {
+ d_printf("Usage: net groupmap delmem alias-sid member-sid\n");
+ return -1;
+ }
+
+ if (!pdb_del_aliasmem(&alias, &member)) {
+ d_printf("Could not delete sid %s from alias %s: %s\n",
+ argv[1], argv[0], nt_errstr(result));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int net_groupmap_listmem(int argc, const char **argv)
+{
+ DOM_SID alias;
+ DOM_SID *members;
+ int i, num;
+ NTSTATUS result;
+
+ if ( (argc != 1) ||
+ !string_to_sid(&alias, argv[0]) ) {
+ d_printf("Usage: net groupmap listmem alias-sid\n");
+ return -1;
+ }
+
+ if (!pdb_enum_aliasmem(&alias, &members, &num)) {
+ d_printf("Could not list members for sid %s: %s\n",
+ argv[0], nt_errstr(result));
+ return -1;
+ }
+
+ for (i = 0; i < num; i++) {
+ printf("%s\n", sid_string_static(&(members[i])));
+ }
+
+ SAFE_FREE(members);
+
+ return 0;
+}
+
+static int net_groupmap_memberships(int argc, const char **argv)
+{
+ DOM_SID member;
+ DOM_SID *aliases;
+ int i, num;
+ NTSTATUS result;
+
+ if ( (argc != 1) ||
+ !string_to_sid(&member, argv[0]) ) {
+ d_printf("Usage: net groupmap memberof sid\n");
+ return -1;
+ }
+
+ if (!pdb_enum_alias_memberships(&member, &aliases, &num)) {
+ d_printf("Could not list memberships for sid %s: %s\n",
+ argv[0], nt_errstr(result));
+ return -1;
+ }
+
+ for (i = 0; i < num; i++) {
+ printf("%s\n", sid_string_static(&(aliases[i])));
+ }
+
+ SAFE_FREE(aliases);
+
+ return 0;
+}
+
int net_help_groupmap(int argc, const char **argv)
{
d_printf("net groupmap add"\
@@ -616,6 +714,14 @@ int net_help_groupmap(int argc, const char **argv)
"\n Update a group mapping\n");
d_printf("net groupmap delete"\
"\n Remove a group mapping\n");
+ d_printf("net groupmap addmember"\
+ "\n Add a foreign alias member\n");
+ d_printf("net groupmap delmember"\
+ "\n Delete a foreign alias member\n");
+ d_printf("net groupmap listmembers"\
+ "\n List foreign group members\n");
+ d_printf("net groupmap memberships"\
+ "\n List foreign group memberships\n");
d_printf("net groupmap list"\
"\n List current group map\n");
d_printf("net groupmap set"\
@@ -638,16 +744,22 @@ int net_groupmap(int argc, const char **argv)
{"delete", net_groupmap_delete},
{"set", net_groupmap_set},
{"cleanup", net_groupmap_cleanup},
+ {"addmem", net_groupmap_addmem},
+ {"delmem", net_groupmap_delmem},
+ {"listmem", net_groupmap_listmem},
+ {"memberships", net_groupmap_memberships},
{"list", net_groupmap_list},
{"help", net_help_groupmap},
{NULL, NULL}
};
/* we shouldn't have silly checks like this */
+#if 0
if (getuid() != 0) {
d_printf("You must be root to edit group mappings.\nExiting...\n");
return -1;
}
+#endif
if ( argc )
return net_run_function(argc, argv, func, net_help_groupmap);