diff options
author | Volker Lendecke <vlendec@samba.org> | 2004-02-29 16:48:19 +0000 |
---|---|---|
committer | Volker Lendecke <vlendec@samba.org> | 2004-02-29 16:48:19 +0000 |
commit | 0d45ad1b0d55546c6a4afcb002acefefc2e2feb0 (patch) | |
tree | 34fa0e74191cef6a5070a0e1499c919a43b4f64d | |
parent | 4628a2da1e32f397696640452c950e4b55ada9e7 (diff) | |
download | samba-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.c | 66 | ||||
-rw-r--r-- | source3/groupdb/mapping.c | 282 | ||||
-rw-r--r-- | source3/include/passdb.h | 28 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 121 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 9 | ||||
-rw-r--r-- | source3/utils/net_groupmap.c | 112 |
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); |