/*
- * Unix SMB/Netbios implementation.
- * Version 1.9.
+ * Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
/*
* A list of the rids of well known BUILTIN and Domain users
* and groups.
NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, uint32 **prids, DOM_SID *q_sid)
{
SAM_ACCOUNT *sam_pass=NULL;
- char *sep;
- struct sys_grent *glist;
- struct sys_grent *grp;
- int i, num, cur_rid=0;
- gid_t *gid;
+ int i, cur_rid=0;
+ gid_t gid;
+ gid_t *groups = NULL;
+ int num_groups;
GROUP_MAP map;
DOM_SID tmp_sid;
fstring user_name;
fstring str_domsid, str_qsid;
uint32 rid,grid;
uint32 *rids=NULL, *new_rids=NULL;
+ gid_t winbind_gid_low, winbind_gid_high;
BOOL ret;
+ BOOL winbind_groups_exist;
/*
* this code is far from perfect.
*prids=NULL;
*numgroups=0;
- sep = lp_winbind_separator();
+ winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
DEBUG(10,("get_alias_user_groups: looking if SID %s is a member of groups in the SID domain %s\n",
sid_to_string(str_qsid, q_sid), sid_to_string(str_domsid, sid)));
- sid_peek_rid(q_sid, &rid);
-
pdb_init_sam(&sam_pass);
become_root();
- ret = pdb_getsampwrid(sam_pass, rid);
+ ret = pdb_getsampwsid(sam_pass, q_sid);
unbecome_root();
if (ret == False) {
pdb_free_sam(&sam_pass);
fstrcpy(user_name, pdb_get_username(sam_pass));
grid=pdb_get_group_rid(sam_pass);
gid=pdb_get_gid(sam_pass);
-
- grp = glist = getgrent_list();
- if (grp == NULL) {
+
+ become_root();
+ /* on some systems this must run as root */
+ num_groups = getgroups_user(user_name, &groups);
+ unbecome_root();
+ if (num_groups == -1) {
+ /* this should never happen */
+ DEBUG(2,("get_alias_user_groups: getgroups_user failed\n"));
pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_MEMORY;
+ return NT_STATUS_UNSUCCESSFUL;
}
-
- for (; grp != NULL; grp = grp->next) {
- if(!get_group_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)) {
- DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)grp->gr_gid));
+
+ for (i=0;i<num_groups;i++) {
+ if(!get_group_from_gid(groups[i], &map, MAPPING_WITHOUT_PRIV)) {
+ DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)groups[i]));
continue;
}
}
/* Don't return winbind groups as they are not local! */
- if (strchr_m(map.nt_name, *sep) != NULL) {
+ if (winbind_groups_exist && (groups[i] >= winbind_gid_low) && (groups[i] <= winbind_gid_high)) {
DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name));
continue;
}
continue;
}
- /* the group is fine, we can check if there is the user we're looking for */
- DEBUG(10,("get_alias_user_groups: checking if the user is a member of %s.\n", map.nt_name));
-
- for(num=0; grp->gr_mem[num]!=NULL; num++) {
- if(strcmp(grp->gr_mem[num], user_name)==0) {
- /* we found the user, add the group to the list */
-
- new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1));
- if (new_rids==NULL) {
- DEBUG(10,("get_alias_user_groups: could not realloc memory\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
-
- sid_peek_rid(&map.sid, &(rids[cur_rid]));
- DEBUG(10,("get_alias_user_groups: user found in group %s\n", map.nt_name));
- cur_rid++;
- break;
- }
+ new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1));
+ if (new_rids==NULL) {
+ DEBUG(10,("get_alias_user_groups: could not realloc memory\n"));
+ pdb_free_sam(&sam_pass);
+ free(groups);
+ return NT_STATUS_NO_MEMORY;
}
+ rids=new_rids;
+
+ sid_peek_rid(&map.sid, &(rids[cur_rid]));
+ cur_rid++;
+ break;
}
- grent_free(glist);
+ free(groups);
/* now check for the user's gid (the primary group rid) */
for (i=0; i<cur_rid && grid!=rids[i]; i++)
goto done;
}
- DEBUG(10,("get_alias_user_groups: looking for gid %d of user %s\n", (int)*gid, user_name));
+ DEBUG(10,("get_alias_user_groups: looking for gid %d of user %s\n", (int)gid, user_name));
- if(!get_group_from_gid(*gid, &map, MAPPING_WITHOUT_PRIV)) {
+ if(!get_group_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) {
DEBUG(0,("get_alias_user_groups: gid of user %s doesn't exist. Check your /etc/passwd and /etc/group files\n", user_name));
goto done;
}
}
/* Don't return winbind groups as they are not local! */
- if (strchr_m(map.nt_name, *sep) != NULL) {
+ if (winbind_groups_exist && (gid >= winbind_gid_low) && (gid <= winbind_gid_high)) {
DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name ));
goto done;
}
uint32 grid;
uint32 tmp_rid;
- *numgroups=0;
+ *numgroups= 0;
fstrcpy(user_name, pdb_get_username(sam_pass));
grid=pdb_get_group_rid(sam_pass);
DEBUG(10,("get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name));
/* first get the list of the domain groups */
- if (!enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV))
+ if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV))
return False;
DEBUG(10,("get_domain_user_groups: there are %d mapped groups\n", num_entries));
DEBUG(0,("get_domain_user_groups: primary gid of user [%s] is not a Domain group !\n", user_name));
DEBUGADD(0,("get_domain_user_groups: You should fix it, NT doesn't like that\n"));
+
done:
*pgids=gids;
*numgroups=cur_gid;
return True;
}
+/*******************************************************************
+ gets a domain user's groups from their already-calculated NT_USER_TOKEN
+ ********************************************************************/
+NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
+ const NT_USER_TOKEN *nt_token,
+ int *numgroups, DOM_GID **pgids)
+{
+ DOM_GID *gids;
+ int i;
+
+ gids = (DOM_GID *)talloc(mem_ctx, sizeof(*gids) * nt_token->num_sids);
+
+ if (!gids) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *numgroups=0;
+
+ for (i=PRIMARY_GROUP_SID_INDEX; i < nt_token->num_sids; i++) {
+ if (sid_compare_domain(domain_sid, &nt_token->user_sids[i])==0) {
+ sid_peek_rid(&nt_token->user_sids[i], &(gids[*numgroups].g_rid));
+ gids[*numgroups].attr=7;
+ (*numgroups)++;
+ }
+ }
+ *pgids = gids;
+ return NT_STATUS_OK;
+}
+
/*******************************************************************
Look up a local (domain) rid and return a name and type.
********************************************************************/
return NT_STATUS_NONE_MAPPED;
}
+
+#if 0 /*Nobody uses this function just now*/
/*******************************************************************
Look up a local user rid and return a name and type.
********************************************************************/
return NT_STATUS_NONE_MAPPED;
}
+#endif
+
/*******************************************************************
Look up a local (domain) group name and return a rid
********************************************************************/
NTSTATUS local_lookup_group_rid(char *group_name, uint32 *rid)
{
- char *grp_name;
+ const char *grp_name;
int i = -1; /* start do loop at -1 */
do /* find, if it exists, a group rid for the group name*/
/*******************************************************************
Look up a local (BUILTIN) alias name and return a rid
********************************************************************/
-NTSTATUS local_lookup_alias_rid(char *alias_name, uint32 *rid)
+NTSTATUS local_lookup_alias_rid(const char *alias_name, uint32 *rid)
{
- char *als_name;
+ const char *als_name;
int i = -1; /* start do loop at -1 */
do /* find, if it exists, a alias rid for the alias name*/