diff options
author | CVS Import User <samba-bugs@samba.org> | 2004-04-04 11:27:30 +0000 |
---|---|---|
committer | CVS Import User <samba-bugs@samba.org> | 2004-04-04 11:27:30 +0000 |
commit | f8db8e0ae8fa16894a5eb6367ca325e530ff506b (patch) | |
tree | 753894e0b091990464ef5ce274cb149e4fd9cf0d /source/groupdb | |
parent | 139b1658ca30692835c1a7203c7cd003e587ac12 (diff) | |
download | samba-f8db8e0ae8fa16894a5eb6367ca325e530ff506b.tar.gz samba-f8db8e0ae8fa16894a5eb6367ca325e530ff506b.tar.xz samba-f8db8e0ae8fa16894a5eb6367ca325e530ff506b.zip |
r4: merge in the SAMBA_3_0 branch from cvs
to checkout try this:
svn co svn+ssh://svn.samba.org/home/svn/samba/branches/SAMBA_3_0 samba-3_0-work
metze
Diffstat (limited to 'source/groupdb')
-rw-r--r-- | source/groupdb/mapping.c | 633 |
1 files changed, 137 insertions, 496 deletions
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c index d476f5cac13..d10a7decb7e 100644 --- a/source/groupdb/mapping.c +++ b/source/groupdb/mapping.c @@ -28,12 +28,16 @@ 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" }, + {SE_PRIV_SEC_PRIV, "SeSecurityPrivilege", "Manage the audit logs" }, + {SE_PRIV_TAKE_OWNER, "SeTakeOwnershipPrivilege", "Take ownership of file" }, + {SE_PRIV_ADD_USERS, "SaAddUsers", "Add users to the domain - Samba" }, + {SE_PRIV_PRINT_OPERATOR, "SaPrintOp", "Add or remove printers - Samba" }, + {SE_PRIV_ALL, "SaAllPrivs", "all privileges" } +}; + /**************************************************************************** dump the mapping group mapping to a text file @@ -368,7 +372,7 @@ static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map) Remove a group mapping entry. ****************************************************************************/ -static BOOL group_map_remove(const DOM_SID *sid) +static BOOL group_map_remove(DOM_SID sid) { TDB_DATA kbuf, dbuf; pstring key; @@ -381,7 +385,7 @@ static BOOL group_map_remove(const DOM_SID *sid) /* the key is the SID, retrieving is direct */ - sid_to_string(string_sid, sid); + sid_to_string(string_sid, &sid); slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); kbuf.dptr = key; @@ -485,284 +489,6 @@ 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 @@ -842,8 +568,7 @@ BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map) if ( !ret ) return False; - if ( ( (map->sid_name_use != SID_NAME_ALIAS) && - (map->sid_name_use != SID_NAME_WKN_GRP) ) + if ( (map->sid_name_use != SID_NAME_ALIAS) || (map->gid == -1) || (getgrgid(map->gid) == NULL) ) { @@ -958,6 +683,129 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) return True; } + + + +/**************************************************************************** + Get the member users of a group and + all the users who have that group as primary. + + give back an array of SIDS + return the grand number of users + + + TODO: sort the list and remove duplicate. JFM. + +****************************************************************************/ + +BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) +{ + struct group *grp; + int i=0; + char *gr; + DOM_SID *s; + + struct sys_pwent *userlist; + struct sys_pwent *user; + + if(!init_group_mapping()) { + DEBUG(0,("failed to initialize group mapping\n")); + return(False); + } + + *num_sids = 0; + *sids=NULL; + + if ( (grp=getgrgid(gid)) == NULL) + return False; + + gr = grp->gr_mem[0]; + DEBUG(10, ("getting members\n")); + + while (gr && (*gr != (char)'\0')) { + SAM_ACCOUNT *group_member_acct = NULL; + BOOL found_user; + s = Realloc((*sids), sizeof(**sids)*(*num_sids+1)); + if (!s) { + DEBUG(0,("get_uid_list_of_group: unable to enlarge SID list!\n")); + return False; + } + else (*sids) = s; + + if (!NT_STATUS_IS_OK(pdb_init_sam(&group_member_acct))) { + continue; + } + + become_root(); + found_user = pdb_getsampwnam(group_member_acct, gr); + unbecome_root(); + + if (found_user) { + sid_copy(&(*sids)[*num_sids], pdb_get_user_sid(group_member_acct)); + (*num_sids)++; + } + + pdb_free_sam(&group_member_acct); + + gr = grp->gr_mem[++i]; + } + DEBUG(10, ("got [%d] members\n", *num_sids)); + + winbind_off(); + + user = userlist = getpwent_list(); + + while (user != NULL) { + + SAM_ACCOUNT *group_member_acct = NULL; + BOOL found_user; + + if (user->pw_gid != gid) { + user = user->next; + continue; + } + + s = Realloc((*sids), sizeof(**sids)*(*num_sids+1)); + if (!s) { + DEBUG(0,("get_sid_list_of_group: unable to enlarge " + "SID list!\n")); + pwent_free(userlist); + winbind_on(); + return False; + } + else (*sids) = s; + + if (!NT_STATUS_IS_OK(pdb_init_sam(&group_member_acct))) { + continue; + } + + become_root(); + found_user = pdb_getsampwnam(group_member_acct, user->pw_name); + unbecome_root(); + + if (found_user) { + sid_copy(&(*sids)[*num_sids], + pdb_get_user_sid(group_member_acct)); + (*num_sids)++; + } else { + DEBUG(4,("get_sid_list_of_group: User %s [uid == %lu] " + "has no samba account\n", + user->pw_name, (unsigned long)user->pw_uid)); + if (algorithmic_uid_to_sid(&(*sids)[*num_sids], + user->pw_uid)) + (*num_sids)++; + } + pdb_free_sam(&group_member_acct); + + user = user->next; + } + pwent_free(userlist); + DEBUG(10, ("got primary groups, members: [%d]\n", *num_sids)); + + winbind_on(); + return True; +} + /**************************************************************************** Create a UNIX group on demand. ****************************************************************************/ @@ -1168,7 +1016,7 @@ NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods, NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods, DOM_SID sid) { - return group_map_remove(&sid) ? + return group_map_remove(sid) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } @@ -1181,178 +1029,6 @@ 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 *********************************************************************/ @@ -1401,38 +1077,3 @@ NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods, return NT_STATUS_UNSUCCESSFUL; } -/**************************************************************************** - These need to be redirected through pdb_interface.c -****************************************************************************/ -BOOL pdb_get_dom_grp_info(const DOM_SID *sid, struct acct_info *info) -{ - GROUP_MAP map; - BOOL res; - - become_root(); - res = get_domain_group_from_sid(*sid, &map); - unbecome_root(); - - if (!res) - return False; - - fstrcpy(info->acct_name, map.nt_name); - fstrcpy(info->acct_desc, map.comment); - sid_peek_rid(sid, &info->rid); - return True; -} - -BOOL pdb_set_dom_grp_info(const DOM_SID *sid, const struct acct_info *info) -{ - GROUP_MAP map; - - if (!get_domain_group_from_sid(*sid, &map)) - return False; - - fstrcpy(map.nt_name, info->acct_name); - fstrcpy(map.comment, info->acct_desc); - - return pdb_update_group_mapping_entry(&map); -} - - |