r2865: Add static and remove unused functions that only cload the blame-game
[samba.git] / source3 / groupdb / mapping.c
index 7a07b5c344816bc3879204de654bed5bd772f2f9..d189f447d08967fd128ac10efee58409b00b9f45 100644 (file)
@@ -28,6 +28,13 @@ static TDB_CONTEXT *tdb; /* used for driver files */
 
 #define GROUP_PREFIX "UNIXGROUP/"
 
+/* Alias memberships are stored reverse, as memberships. The performance
+ * critical operation is to determine the aliases a SID is member of, not
+ * listing alias members. So we store a list of alias SIDs a SID is member of
+ * hanging of the member as key.
+ */
+#define MEMBEROF_PREFIX "MEMBEROF/"
+
 PRIVS privs[] = {
        {SE_PRIV_NONE,           "no_privs",                  "No privilege"                    }, /* this one MUST be first */
        {SE_PRIV_ADD_MACHINES,   "SeMachineAccountPrivilege", "Add workstations to the domain"  },
@@ -177,7 +184,7 @@ static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
        int len;
 
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
        
@@ -208,7 +215,7 @@ BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_us
        GROUP_MAP map;
 
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
        
@@ -237,7 +244,7 @@ static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map)
        int ret = 0;
        
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
 
@@ -279,7 +286,7 @@ static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map)
        int ret;
 
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
 
@@ -329,7 +336,7 @@ static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
        int ret;
 
        if(!init_group_mapping()) {
-               DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping"));
+               DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping\n"));
                return(False);
        }
 
@@ -379,7 +386,7 @@ static BOOL group_map_remove(DOM_SID sid)
        fstring string_sid;
        
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
 
@@ -419,7 +426,7 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
        int entries=0;
 
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
 
@@ -489,6 +496,284 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
        return True;
 }
 
+/* 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)
+{
+       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);
+       slprintf(key, sizeof(key), "%s%s", MEMBEROF_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 alias;
+
+               if (!string_to_sid(&alias, string_sid))
+                       continue;
+
+               add_sid_to_array(&alias, sids, num);
+
+               if (sids == NULL)
+                       return NT_STATUS_NO_MEMORY;
+       }
+
+       SAFE_FREE(dbuf.dptr);
+       return NT_STATUS_OK;
+}
+
+static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+{
+       DOM_SID *sids;
+       int i, num;
+
+       /* 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)))
+               return False;
+
+       for (i=0; i<num; i++) {
+               if (sid_compare(alias, &sids[i]) == 0) {
+                       SAFE_FREE(sids);
+                       return True;
+               }
+       }
+       SAFE_FREE(sids);
+       return False;
+}
+
+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\n"));
+               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;
+
+       if (is_aliasmem(alias, member))
+               return NT_STATUS_MEMBER_IN_ALIAS;
+
+       sid_to_string(string_sid, member);
+       slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
+
+       kbuf.dsize = strlen(key)+1;
+       kbuf.dptr = key;
+
+       dbuf = tdb_fetch(tdb, kbuf);
+
+       sid_to_string(string_sid, alias);
+
+       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);
+}
+
+struct aliasmem_closure {
+       const DOM_SID *alias;
+       DOM_SID **sids;
+       int *num;
+};
+
+static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data,
+                           void *state)
+{
+       struct aliasmem_closure *closure = (struct aliasmem_closure *)state;
+       const char *p;
+       fstring alias_string;
+
+       if (strncmp(key.dptr, MEMBEROF_PREFIX,
+                   strlen(MEMBEROF_PREFIX)) != 0)
+               return 0;
+
+       p = data.dptr;
+
+       while (next_token(&p, alias_string, " ", sizeof(alias_string))) {
+
+               DOM_SID alias, member;
+               const char *member_string;
+               
+
+               if (!string_to_sid(&alias, alias_string))
+                       continue;
+
+               if (sid_compare(closure->alias, &alias) != 0)
+                       continue;
+
+               /* Ok, we found the alias we're looking for in the membership
+                * list currently scanned. The key represents the alias
+                * member. Add that. */
+
+               member_string = strchr(key.dptr, '/');
+
+               /* Above we tested for MEMBEROF_PREFIX which includes the
+                * slash. */
+
+               SMB_ASSERT(member_string != NULL);
+               member_string += 1;
+
+               if (!string_to_sid(&member, member_string))
+                       continue;
+               
+               add_sid_to_array(&member, closure->sids, closure->num);
+       }
+
+       return 0;
+}
+
+static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num)
+{
+       GROUP_MAP map;
+       struct aliasmem_closure closure;
+
+       if(!init_group_mapping()) {
+               DEBUG(0,("failed to initialize group mapping\n"));
+               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;
+
+       closure.alias = alias;
+       closure.sids = sids;
+       closure.num = num;
+
+       tdb_traverse(tdb, collect_aliasmem, &closure);
+       return NT_STATUS_OK;
+}
+
+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 = alias_memberships(member, &sids, &num);
+
+       if (!NT_STATUS_IS_OK(result))
+               return result;
+
+       for (i=0; i<num; i++) {
+               if (sid_compare(&sids[i], alias) == 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;
+
+       sid_to_string(sid_string, member);
+       slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, sid_string);
+
+       kbuf.dsize = strlen(key)+1;
+       kbuf.dptr = key;
+
+       if (num == 0)
+               return tdb_delete(tdb, kbuf) == 0 ?
+                       NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+
+       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;
+               }
+       }
+
+       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;
+}
+
 /*
  *
  * High level functions
@@ -504,16 +789,22 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
 BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
 {
        struct group *grp;
-
+       BOOL ret;
+       
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
 
        DEBUG(10, ("get_domain_group_from_sid\n"));
 
        /* if the group is NOT in the database, it CAN NOT be a domain group */
-       if(!pdb_getgrsid(map, sid))
+       
+       become_root();
+       ret = pdb_getgrsid(map, sid);
+       unbecome_root();
+       
+       if ( !ret ) 
                return False;
 
        DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n"));
@@ -545,34 +836,42 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
 
 /* get a local (alias) group from it's SID */
 
-BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map)
+BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
 {
-       struct group *grp;
-
+       BOOL ret;
+       
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
 
        /* The group is in the mapping table */
-       if(pdb_getgrsid(map, sid)) {
-               if (map->sid_name_use!=SID_NAME_ALIAS) {
-                       return False;
-               }
+       become_root();
+       ret = pdb_getgrsid(map, *sid);
+       unbecome_root();
+       
+       if ( !ret )
+               return False;
                
-               if (map->gid==-1) {
-                       return False;
-               }
-
-               if ( (grp=getgrgid(map->gid)) == NULL) {
-                       return False;
-               }
-       } else {
+       if ( ( (map->sid_name_use != SID_NAME_ALIAS) &&
+              (map->sid_name_use != SID_NAME_WKN_GRP) )
+               || (map->gid == -1)
+               || (getgrgid(map->gid) == NULL) ) 
+       {
+               return False;
+       }               
+                       
+#if 1  /* JERRY */
+       /* local groups only exist in the group mapping DB so this 
+          is not necessary */
+          
+       else {
                /* the group isn't in the mapping table.
                 * make one based on the unix information */
                uint32 alias_rid;
+               struct group *grp;
 
-               sid_peek_rid(&sid, &alias_rid);
+               sid_peek_rid(sid, &alias_rid);
                map->gid=pdb_group_rid_to_gid(alias_rid);
                
                grp = getgrgid(map->gid);
@@ -586,24 +885,31 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map)
                fstrcpy(map->nt_name, grp->gr_name);
                fstrcpy(map->comment, "Local Unix Group");
 
-               sid_copy(&map->sid, &sid);
+               sid_copy(&map->sid, sid);
        }
+#endif
 
        return True;
 }
 
 /* get a builtin group from it's SID */
 
-BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map)
+BOOL get_builtin_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
 {
        struct group *grp;
+       BOOL ret;
+       
 
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
 
-       if(!pdb_getgrsid(map, sid))
+       become_root();
+       ret = pdb_getgrsid(map, *sid);
+       unbecome_root();
+       
+       if ( !ret )
                return False;
 
        if (map->sid_name_use!=SID_NAME_WKN_GRP) {
@@ -629,108 +935,28 @@ Returns a GROUP_MAP struct based on the gid.
 BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
 {
        struct group *grp;
+       BOOL ret;
 
        if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
+               DEBUG(0,("failed to initialize group mapping\n"));
                return(False);
        }
 
        if ( (grp=getgrgid(gid)) == NULL)
                return False;
 
-       /*
-        * make a group map from scratch if doesn't exist.
-        */
-       if (!pdb_getgrgid(map, gid)) {
-               map->gid=gid;
-               map->sid_name_use=SID_NAME_ALIAS;
-
-               /* interim solution until we have a last RID allocated */
-
-               sid_copy(&map->sid, get_global_sam_sid());
-               sid_append_rid(&map->sid, pdb_gid_to_group_rid(gid));
-
-               fstrcpy(map->nt_name, grp->gr_name);
-               fstrcpy(map->comment, "Local Unix Group");
+       become_root();
+       ret = pdb_getgrgid(map, gid);
+       unbecome_root();
+       
+       if ( !ret ) {
+               return False;
        }
        
        return True;
 }
 
 
-
-
-/****************************************************************************
- Get the member users of a group and
- all the users who have that group as primary.
-            
- give back an array of uid
- return the grand number of users
-
-
- TODO: sort the list and remove duplicate. JFM.
-
-****************************************************************************/
-        
-BOOL get_uid_list_of_group(gid_t gid, uid_t **uid, int *num_uids)
-{
-       struct group *grp;
-       struct passwd *pwd;
-       int i=0;
-       char *gr;
-       uid_t *u;
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       *num_uids = 0;
-       *uid=NULL;
-       
-       if ( (grp=getgrgid(gid)) == NULL)
-               return False;
-
-       gr = grp->gr_mem[0];
-       DEBUG(10, ("getting members\n"));
-        
-       while (gr && (*gr != (char)'\0')) {
-               u = Realloc((*uid), sizeof(uid_t)*(*num_uids+1));
-               if (!u) {
-                       DEBUG(0,("get_uid_list_of_group: unable to enlarge uid list!\n"));
-                       return False;
-               }
-               else (*uid) = u;
-
-               if( (pwd=getpwnam_alloc(gr)) !=NULL) {
-                       (*uid)[*num_uids]=pwd->pw_uid;
-                       (*num_uids)++;
-                       passwd_free(&pwd);
-               }
-               gr = grp->gr_mem[++i];
-       }
-       DEBUG(10, ("got [%d] members\n", *num_uids));
-
-       setpwent();
-       while ((pwd=getpwent()) != NULL) {
-               if (pwd->pw_gid==gid) {
-                       u = Realloc((*uid), sizeof(uid_t)*(*num_uids+1));
-                       if (!u) {
-                               DEBUG(0,("get_uid_list_of_group: unable to enlarge uid list!\n"));
-                               return False;
-                       }
-                       else (*uid) = u;
-                       (*uid)[*num_uids]=pwd->pw_uid;
-
-                       (*num_uids)++;
-               }
-       }
-       endpwent();
-       DEBUG(10, ("got primary groups, members: [%d]\n", *num_uids));
-
-        return True;
-}
-
 /****************************************************************************
  Create a UNIX group on demand.
 ****************************************************************************/
@@ -763,11 +989,9 @@ int smb_create_group(char *unix_group, gid_t *new_gid)
                        
                        close(fd);
                }
-       }
 
-       /* Try winbindd */
+       } else if ( winbind_create_group( unix_group, NULL ) ) {
 
-       if ( winbind_create_group( unix_group, NULL ) ) {
                DEBUG(3,("smb_create_group: winbindd created the group (%s)\n",
                        unix_group));
                ret = 0;
@@ -956,6 +1180,178 @@ NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
                NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
+NTSTATUS pdb_default_find_alias(struct pdb_methods *methods,
+                               const char *name, DOM_SID *sid)
+{
+       GROUP_MAP map;
+
+       if (!pdb_getgrnam(&map, name))
+               return NT_STATUS_NO_SUCH_ALIAS;
+
+       if ((map.sid_name_use != SID_NAME_WKN_GRP) &&
+           (map.sid_name_use != SID_NAME_ALIAS))
+               return NT_STATUS_OBJECT_TYPE_MISMATCH;
+
+       sid_copy(sid, &map.sid);
+       return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
+                                 const char *name, uint32 *rid)
+{
+       DOM_SID sid;
+       enum SID_NAME_USE type;
+       uint32 new_rid;
+       gid_t gid;
+
+       GROUP_MAP map;
+
+       if (lookup_name(get_global_sam_name(), name, &sid, &type))
+               return NT_STATUS_ALIAS_EXISTS;
+
+       if (!winbind_allocate_rid(&new_rid))
+               return NT_STATUS_ACCESS_DENIED;
+
+       sid_copy(&sid, get_global_sam_sid());
+       sid_append_rid(&sid, new_rid);
+
+       /* Here we allocate the gid */
+       if (!winbind_sid_to_gid(&gid, &sid)) {
+               DEBUG(0, ("Could not get gid for new RID\n"));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       map.gid = gid;
+       sid_copy(&map.sid, &sid);
+       map.sid_name_use = SID_NAME_ALIAS;
+       fstrcpy(map.nt_name, name);
+       fstrcpy(map.comment, "");
+
+       if (!pdb_add_group_mapping_entry(&map)) {
+               DEBUG(0, ("Could not add group mapping entry for alias %s\n",
+                         name));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       *rid = new_rid;
+
+       return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
+                                 const DOM_SID *sid)
+{
+       return pdb_delete_group_mapping_entry(*sid) ?
+               NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
+}
+
+NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods,
+                                 const DOM_SID *sid,
+                                 uint32 start_idx, uint32 max_entries,
+                                 uint32 *num_aliases,
+                                 struct acct_info **info)
+{
+       extern DOM_SID global_sid_Builtin;
+
+       GROUP_MAP *map;
+       int i, num_maps;
+       enum SID_NAME_USE type = SID_NAME_UNKNOWN;
+
+       if (sid_compare(sid, get_global_sam_sid()) == 0)
+               type = SID_NAME_ALIAS;
+
+       if (sid_compare(sid, &global_sid_Builtin) == 0)
+               type = SID_NAME_WKN_GRP;
+
+       if (!pdb_enum_group_mapping(type, &map, &num_maps, False) ||
+           (num_maps == 0)) {
+               *num_aliases = 0;
+               *info = NULL;
+               goto done;
+       }
+
+       if (start_idx > num_maps) {
+               *num_aliases = 0;
+               *info = NULL;
+               goto done;
+       }
+
+       *num_aliases = num_maps - start_idx;
+
+       if (*num_aliases > max_entries)
+               *num_aliases = max_entries;
+
+       *info = malloc(sizeof(struct acct_info) * (*num_aliases));
+
+       for (i=0; i<*num_aliases; i++) {
+               fstrcpy((*info)[i].acct_name, map[i+start_idx].nt_name);
+               fstrcpy((*info)[i].acct_desc, map[i+start_idx].comment);
+               sid_peek_rid(&map[i].sid, &(*info)[i+start_idx].rid);
+       }
+
+ done:
+       SAFE_FREE(map);
+       return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,
+                                  const DOM_SID *sid,
+                                  struct acct_info *info)
+{
+       GROUP_MAP map;
+
+       if (!pdb_getgrsid(&map, *sid))
+               return NT_STATUS_NO_SUCH_ALIAS;
+
+       fstrcpy(info->acct_name, map.nt_name);
+       fstrcpy(info->acct_desc, map.comment);
+       sid_peek_rid(&map.sid, &info->rid);
+       return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods,
+                                  const DOM_SID *sid,
+                                  struct acct_info *info)
+{
+       GROUP_MAP map;
+
+       if (!pdb_getgrsid(&map, *sid))
+               return NT_STATUS_NO_SUCH_ALIAS;
+
+       fstrcpy(map.comment, info->acct_desc);
+
+       if (!pdb_update_group_mapping_entry(&map))
+               return NT_STATUS_ACCESS_DENIED;
+
+       return NT_STATUS_OK;
+}
+
+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
  *********************************************************************/