mirror of
https://github.com/samba-team/samba.git
synced 2025-12-13 16:23:50 +03:00
cache unix groups so that two-level getgrent calls don't occur.
This commit is contained in:
@@ -27,6 +27,13 @@ extern int DEBUGLEVEL;
|
||||
extern DOM_SID global_sam_sid;
|
||||
extern fstring global_sam_name;
|
||||
|
||||
struct unix_entries
|
||||
{
|
||||
struct group *grps;
|
||||
int num_grps;
|
||||
int grp_idx;
|
||||
};
|
||||
|
||||
/***************************************************************
|
||||
Start to enumerate the alspasswd list. Returns a void pointer
|
||||
to ensure no modification outside this module.
|
||||
@@ -34,8 +41,23 @@ extern fstring global_sam_name;
|
||||
|
||||
static void *startalsunixpwent(BOOL update)
|
||||
{
|
||||
setgrent();
|
||||
return (void*)(-1);
|
||||
struct unix_entries *grps;
|
||||
grps = (struct unix_entries*)malloc(sizeof(struct unix_entries));
|
||||
|
||||
if (grps == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!get_unix_grps(&grps->num_grps, &grps->grps))
|
||||
{
|
||||
free(grps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grps->grp_idx = 0;
|
||||
|
||||
return (void*)grps;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@@ -44,7 +66,13 @@ static void *startalsunixpwent(BOOL update)
|
||||
|
||||
static void endalsunixpwent(void *vp)
|
||||
{
|
||||
endgrent();
|
||||
struct unix_entries *grps = (struct unix_entries *)vp;
|
||||
|
||||
if (grps != NULL)
|
||||
{
|
||||
free_unix_grps(grps->num_grps, grps->grps);
|
||||
free(vp);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -142,7 +170,8 @@ static LOCAL_GRP *getalsunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
|
||||
{
|
||||
/* Static buffers we will return. */
|
||||
static LOCAL_GRP gp_buf;
|
||||
struct group *unix_grp;
|
||||
struct group *unix_grp = NULL;
|
||||
struct unix_entries *grps = (struct unix_entries *)vp;
|
||||
|
||||
if (lp_server_role() == ROLE_DOMAIN_NONE)
|
||||
{
|
||||
@@ -156,11 +185,18 @@ static LOCAL_GRP *getalsunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
|
||||
|
||||
aldb_init_als(&gp_buf);
|
||||
|
||||
/* get array of unix names + gids. this function does NOT
|
||||
get a copy of the unix group members
|
||||
*/
|
||||
|
||||
/* cycle through unix groups */
|
||||
while ((unix_grp = getgrent()) != NULL)
|
||||
for (; grps->grp_idx < grps->num_grps; grps->grp_idx++)
|
||||
{
|
||||
DOM_NAME_MAP gmep;
|
||||
fstring sid_str;
|
||||
|
||||
unix_grp = &grps->grps[grps->grp_idx];
|
||||
|
||||
DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
|
||||
unix_grp->gr_name));
|
||||
|
||||
@@ -185,10 +221,11 @@ static LOCAL_GRP *getalsunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
|
||||
}
|
||||
|
||||
fstrcpy(gp_buf.name, gmep.nt_name);
|
||||
grps->grp_idx++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unix_grp == NULL)
|
||||
if (unix_grp == NULL || grps->grp_idx >= grps->num_grps)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -200,6 +237,7 @@ static LOCAL_GRP *getalsunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
|
||||
(*mem) = NULL;
|
||||
(*num_mem) = 0;
|
||||
|
||||
unix_grp = getgrgid(unix_grp->gr_gid);
|
||||
get_unixalias_members(unix_grp, num_mem, mem);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
struct unix_entries
|
||||
{
|
||||
struct group *grps;
|
||||
int num_grps;
|
||||
int grp_idx;
|
||||
};
|
||||
|
||||
extern DOM_SID global_sid_S_1_5_20;
|
||||
extern DOM_SID global_sam_sid;
|
||||
@@ -35,8 +41,23 @@ extern fstring global_sam_name;
|
||||
|
||||
static void *startbltunixpwent(BOOL update)
|
||||
{
|
||||
setgrent();
|
||||
return (void*)(-1);
|
||||
struct unix_entries *grps;
|
||||
grps = (struct unix_entries*)malloc(sizeof(struct unix_entries));
|
||||
|
||||
if (grps == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!get_unix_grps(&grps->num_grps, &grps->grps))
|
||||
{
|
||||
free(grps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grps->grp_idx = 0;
|
||||
|
||||
return (void*)grps;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@@ -45,7 +66,13 @@ static void *startbltunixpwent(BOOL update)
|
||||
|
||||
static void endbltunixpwent(void *vp)
|
||||
{
|
||||
endgrent();
|
||||
struct unix_entries *grps = (struct unix_entries *)vp;
|
||||
|
||||
if (grps != NULL)
|
||||
{
|
||||
free_unix_grps(grps->num_grps, grps->grps);
|
||||
free(vp);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -143,12 +170,18 @@ static LOCAL_GRP *getbltunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
|
||||
{
|
||||
/* Static buffers we will return. */
|
||||
static LOCAL_GRP gp_buf;
|
||||
struct group *unix_grp;
|
||||
struct group *unix_grp = NULL;
|
||||
struct unix_entries *grps = (struct unix_entries *)vp;
|
||||
|
||||
if (grps == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lp_server_role() == ROLE_DOMAIN_NONE)
|
||||
{
|
||||
/*
|
||||
* no domain role, no domain builtin aliases (or domain groups,
|
||||
* no domain role, no domain aliases (or domain groups,
|
||||
* but that's dealt with by groupdb...).
|
||||
*/
|
||||
|
||||
@@ -157,12 +190,19 @@ static LOCAL_GRP *getbltunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
|
||||
|
||||
bidb_init_blt(&gp_buf);
|
||||
|
||||
/* get array of unix names + gids. this function does NOT
|
||||
get a copy of the unix group members
|
||||
*/
|
||||
|
||||
/* cycle through unix groups */
|
||||
while ((unix_grp = getgrent()) != NULL)
|
||||
for (; grps->grp_idx < grps->num_grps; grps->grp_idx++)
|
||||
{
|
||||
DOM_NAME_MAP gmep;
|
||||
fstring sid_str;
|
||||
DEBUG(10,("getbltunixpwent: enum unix group entry %s\n",
|
||||
|
||||
unix_grp = &grps->grps[grps->grp_idx];
|
||||
|
||||
DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
|
||||
unix_grp->gr_name));
|
||||
|
||||
if (!lookupsmbgrpgid(unix_grp->gr_gid, &gmep))
|
||||
@@ -180,33 +220,35 @@ static LOCAL_GRP *getbltunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
|
||||
}
|
||||
|
||||
sid_split_rid(&gmep.sid, &gp_buf.rid);
|
||||
if (!sid_equal(&global_sid_S_1_5_20, &gmep.sid))
|
||||
if (!sid_equal(&global_sam_sid, &gmep.sid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fstrcpy(gp_buf.name, gmep.nt_name);
|
||||
grps->grp_idx++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unix_grp == NULL)
|
||||
if (unix_grp == NULL || grps->grp_idx >= grps->num_grps)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the user's domain builtin aliases. there are a maximum of 32 */
|
||||
/* get the user's domain aliases. there are a maximum of 32 */
|
||||
|
||||
if (mem != NULL && num_mem != NULL)
|
||||
{
|
||||
(*mem) = NULL;
|
||||
(*num_mem) = 0;
|
||||
|
||||
unix_grp = getgrgid(unix_grp->gr_gid);
|
||||
get_unixbuiltin_members(unix_grp, num_mem, mem);
|
||||
}
|
||||
|
||||
{
|
||||
pstring linebuf;
|
||||
make_builtin_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
|
||||
make_alias_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
|
||||
DEBUG(10,("line: '%s'\n", linebuf));
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,32 @@ extern DOM_SID global_sam_sid;
|
||||
to ensure no modification outside this module.
|
||||
****************************************************************/
|
||||
|
||||
struct unix_entries
|
||||
{
|
||||
struct group *grps;
|
||||
int num_grps;
|
||||
int grp_idx;
|
||||
};
|
||||
|
||||
static void *startgrpunixpwent(BOOL update)
|
||||
{
|
||||
setgrent();
|
||||
return (void*)(-1);
|
||||
struct unix_entries *grps;
|
||||
grps = (struct unix_entries*)malloc(sizeof(struct unix_entries));
|
||||
|
||||
if (grps == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!get_unix_grps(&grps->num_grps, &grps->grps))
|
||||
{
|
||||
free(grps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grps->grp_idx = 0;
|
||||
|
||||
return (void*)grps;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@@ -43,7 +65,13 @@ static void *startgrpunixpwent(BOOL update)
|
||||
|
||||
static void endgrpunixpwent(void *vp)
|
||||
{
|
||||
endgrent();
|
||||
struct unix_entries *grps = (struct unix_entries *)vp;
|
||||
|
||||
if (grps != NULL)
|
||||
{
|
||||
free_unix_grps(grps->num_grps, grps->grps);
|
||||
free(vp);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -142,7 +170,13 @@ static DOMAIN_GRP *getgrpunixpwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_m
|
||||
{
|
||||
/* Static buffers we will return. */
|
||||
static DOMAIN_GRP gp_buf;
|
||||
struct group *unix_grp;
|
||||
struct group *unix_grp = NULL;
|
||||
struct unix_entries *grps = (struct unix_entries *)vp;
|
||||
|
||||
if (grps == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lp_server_role() == ROLE_DOMAIN_NONE ||
|
||||
lp_server_role() == ROLE_DOMAIN_MEMBER)
|
||||
@@ -161,10 +195,17 @@ static DOMAIN_GRP *getgrpunixpwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_m
|
||||
fstrcpy(gp_buf.comment, "");
|
||||
gp_buf.attr = 0x07;
|
||||
|
||||
/* get array of unix names + gids. this function does NOT
|
||||
get a copy of the unix group members
|
||||
*/
|
||||
|
||||
/* cycle through unix groups */
|
||||
while ((unix_grp = getgrent()) != NULL)
|
||||
for (; grps->grp_idx < grps->num_grps; grps->grp_idx++)
|
||||
{
|
||||
DOM_NAME_MAP gmep;
|
||||
|
||||
unix_grp = &grps->grps[grps->grp_idx];
|
||||
|
||||
DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
|
||||
unix_grp->gr_name));
|
||||
|
||||
@@ -186,10 +227,11 @@ static DOMAIN_GRP *getgrpunixpwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_m
|
||||
}
|
||||
|
||||
fstrcpy(gp_buf.name, gmep.nt_name);
|
||||
grps->grp_idx++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unix_grp == NULL)
|
||||
if (unix_grp == NULL || grps->grp_idx >= grps->num_grps)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -201,6 +243,7 @@ static DOMAIN_GRP *getgrpunixpwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_m
|
||||
(*mem) = NULL;
|
||||
(*num_mem) = 0;
|
||||
|
||||
unix_grp = getgrgid(unix_grp->gr_gid);
|
||||
get_unixgroup_members(unix_grp, num_mem, mem);
|
||||
}
|
||||
|
||||
|
||||
@@ -432,6 +432,8 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
|
||||
struct hostent *Get_Hostbyname(const char *name);
|
||||
BOOL process_exists(int pid);
|
||||
int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
|
||||
BOOL get_unix_grps(int *p_ngroups, struct group **p_groups);
|
||||
void free_unix_grps(int ngroups, struct group *p_groups);
|
||||
char *uidtoname(uid_t uid);
|
||||
char *gidtoname(gid_t gid);
|
||||
BOOL nametogid(const char *name, gid_t *gid);
|
||||
@@ -2068,7 +2070,6 @@ void make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char *product_type,
|
||||
void reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth);
|
||||
void make_reg_r_info(REG_R_INFO *r_r,
|
||||
uint32 level, char *os_type,
|
||||
uint32 unknown_0, uint32 unknown_1,
|
||||
uint32 status);
|
||||
void reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth);
|
||||
void make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
|
||||
@@ -2186,7 +2187,7 @@ void make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
|
||||
uint16 acb_mask, uint16 unk_1, uint32 size);
|
||||
void samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth);
|
||||
void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
|
||||
uint32 unk_0,
|
||||
uint32 next_idx,
|
||||
uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status);
|
||||
void samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth);
|
||||
void make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
|
||||
|
||||
@@ -168,6 +168,7 @@ Corrections by richard.kettlewell@kewill.com
|
||||
struct group *g;
|
||||
char *gr;
|
||||
|
||||
setgrent();
|
||||
grouplst[0] = id;
|
||||
i = 1;
|
||||
while (i < NGROUPS_MAX &&
|
||||
|
||||
@@ -2384,6 +2384,77 @@ int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_g
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get all unix groups. copying group members is hideous on memory, so it's
|
||||
NOT done here. however, names of unix groups _are_ string-allocated so
|
||||
free_unix_grps() must be called.
|
||||
****************************************************************************/
|
||||
BOOL get_unix_grps(int *p_ngroups, struct group **p_groups)
|
||||
{
|
||||
struct group *grp;
|
||||
|
||||
DEBUG(10,("get_unix_grps\n"));
|
||||
|
||||
if (p_ngroups == NULL || *p_groups == NULL)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
(*p_ngroups) = 0;
|
||||
(*p_groups) = NULL;
|
||||
|
||||
setgrent();
|
||||
|
||||
while ((grp = getgrent()) != NULL)
|
||||
{
|
||||
struct group *copy_grp;
|
||||
|
||||
(*p_groups) = (struct group*)Realloc((*p_groups), (size_t)((*p_ngroups)+1) * sizeof(struct group));
|
||||
if ((*p_groups) == NULL)
|
||||
{
|
||||
(*p_ngroups) = 0;
|
||||
endgrent();
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
copy_grp = &(*p_groups)[*p_ngroups];
|
||||
memcpy(copy_grp, grp, sizeof(*grp));
|
||||
copy_grp->gr_name = strdup(copy_grp->gr_name);
|
||||
copy_grp->gr_mem = NULL;
|
||||
|
||||
(*p_ngroups)++;
|
||||
}
|
||||
|
||||
endgrent();
|
||||
|
||||
DEBUG(10,("get_unix_grps: %d groups\n", (*p_ngroups)));
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
free memory associated with unix groups.
|
||||
****************************************************************************/
|
||||
void free_unix_grps(int ngroups, struct group *p_groups)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (p_groups == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ngroups; i++)
|
||||
{
|
||||
if (p_groups[i].gr_name != NULL)
|
||||
{
|
||||
free(p_groups[i].gr_name);
|
||||
}
|
||||
}
|
||||
|
||||
free(p_groups);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
turn a uid into a user name
|
||||
********************************************************************/
|
||||
|
||||
@@ -766,7 +766,6 @@ creates a structure.
|
||||
********************************************************************/
|
||||
void make_reg_r_info(REG_R_INFO *r_r,
|
||||
uint32 level, char *os_type,
|
||||
uint32 unknown_0, uint32 unknown_1,
|
||||
uint32 status)
|
||||
{
|
||||
uint8 buf[512];
|
||||
@@ -779,10 +778,10 @@ void make_reg_r_info(REG_R_INFO *r_r,
|
||||
make_buffer2(&(r_r->uni_type), buf, len*2);
|
||||
|
||||
r_r->ptr2 = 1;
|
||||
r_r->unknown_0 = unknown_0;
|
||||
r_r->unknown_0 = len*2;
|
||||
|
||||
r_r->ptr3 = 1;
|
||||
r_r->unknown_1 = unknown_1;
|
||||
r_r->unknown_1 = len*2;
|
||||
|
||||
r_r->status = status;
|
||||
}
|
||||
|
||||
@@ -1232,7 +1232,7 @@ void make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
|
||||
{
|
||||
if (r_u == NULL) return;
|
||||
|
||||
DEBUG(5,("make_samr_r_query_dispinfo\n"));
|
||||
DEBUG(5,("make_samr_r_query_dispinfo: level %d\n", switch_level));
|
||||
|
||||
if (status == 0x0)
|
||||
{
|
||||
@@ -1910,7 +1910,7 @@ void make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u,
|
||||
|
||||
if (status == 0x0)
|
||||
{
|
||||
r_u->ptr = (num_entries != 0) ? 1 : 0;
|
||||
r_u->ptr = 1;
|
||||
r_u->num_entries = num_entries;
|
||||
|
||||
r_u->ptr_attrs = attr != NULL ? 1 : 0;
|
||||
|
||||
@@ -194,7 +194,7 @@ static void reg_reply_info(REG_Q_INFO *q_u,
|
||||
{
|
||||
}
|
||||
|
||||
make_reg_r_info(&r_u, 1, "LanmanNT", 0x12, 0x12, status);
|
||||
make_reg_r_info(&r_u, 1, "LanmanNT", status);
|
||||
|
||||
/* store the response in the SMB stream */
|
||||
reg_io_r_info("", &r_u, rdata, 0);
|
||||
|
||||
Reference in New Issue
Block a user