Apply my experimental aliases support to HEAD. This will be a bit difficult to
authorVolker Lendecke <vlendec@samba.org>
Sun, 29 Feb 2004 16:48:19 +0000 (16:48 +0000)
committerVolker Lendecke <vlendec@samba.org>
Sun, 29 Feb 2004 16:48:19 +0000 (16:48 +0000)
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)

source3/auth/auth_util.c
source3/groupdb/mapping.c
source3/include/passdb.h
source3/passdb/pdb_interface.c
source3/rpc_server/srv_samr_nt.c
source3/utils/net_groupmap.c

index 0f945b33cb3be9cf458cf2d31ae0c8eb997f50a1..912432b98f89a2608167f6a01972b5718bcefb35 100644 (file)
@@ -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 */
index 71ef38e6c8ab3ee5ec8f9995c39f2dfca5c1d0f5..5eaa4e1386fe402ba92d95dcb9eac29a91855abe 100644 (file)
@@ -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
  *********************************************************************/
index 6489704fdd8656d21d7632673135bd64f37f565d..668bbcc2de68625d47020b3860782f80e91a102a 100644 (file)
@@ -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);
index 581fac364adb16a97a1f434847a1a950694b99e1..83aebf654ad2500bfb2565578e31f9464a7fa450 100644 (file)
@@ -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;
index a8176271278770eddedefd072f51ac01d064a488..b50d44d9e363b2ed941cac237621dfb351dcd5e7 100644 (file)
@@ -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 */
index 2b487ef17b4cb825644f5d1e3a99e3dc08942d59..48406f72b88ca60c7f19447bee86e687e359d07a 100644 (file)
@@ -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);