mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
4 new functions to retrieve single linked list of group and passwd entries
+ a fix to an infinite loop in srv_samr_nt.c caused by misuse of
setgrent/getgrent/endgrent solved by these new functions
(This used to be commit 97dbb54a13
)
This commit is contained in:
parent
415c317bc9
commit
bbf5ea221a
@ -133,7 +133,8 @@ RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \
|
||||
rpc_server/srv_samr.o rpc_server/srv_samr_nt.o rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o \
|
||||
rpc_server/srv_util.o rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o \
|
||||
rpc_server/srv_pipe.o rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o \
|
||||
rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
|
||||
rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o \
|
||||
lib/util_getent.o
|
||||
|
||||
# this includes only the low level parse code, not stuff
|
||||
# that requires knowledge of security contexts
|
||||
|
@ -637,6 +637,8 @@ extern int errno;
|
||||
#include "messages.h"
|
||||
#include "util_list.h"
|
||||
|
||||
#include "util_getent.h"
|
||||
|
||||
#ifndef UBI_BINTREE_H
|
||||
#include "ubi_Cache.h"
|
||||
#endif /* UBI_BINTREE_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
45
source3/include/util_getent.h
Normal file
45
source3/include/util_getent.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 3.0
|
||||
Samba utility functions
|
||||
Copyright (C) Simo Sorce 2001
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* element for a single linked list of group entries */
|
||||
/* replace the use of struct group in some cases */
|
||||
/* used by getgrent_list() */
|
||||
struct sys_grent {
|
||||
char *gr_name;
|
||||
char *gr_passwd;
|
||||
gid_t gr_gid;
|
||||
char **gr_mem;
|
||||
struct sys_grent *next;
|
||||
};
|
||||
|
||||
/* element for a single linked list of passwd entries */
|
||||
/* replace the use of struct passwd in some cases */
|
||||
/* used by getpwent_list() */
|
||||
struct sys_pwent {
|
||||
char *pw_name;
|
||||
char *pw_passwd;
|
||||
uid_t pw_uid;
|
||||
gid_t pw_gid;
|
||||
char *pw_gecos;
|
||||
char *pw_dir;
|
||||
char *pw_shell;
|
||||
struct sys_pwent *next;
|
||||
};
|
185
source3/lib/util_getent.c
Normal file
185
source3/lib/util_getent.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 3.0
|
||||
Samba utility functions
|
||||
Copyright (C) Simo Sorce 2001
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
/****************************************************************
|
||||
Returns a single linked list of group entries.
|
||||
Use grent_free() to free it after use.
|
||||
****************************************************************/
|
||||
struct sys_grent * getgrent_list(void)
|
||||
{
|
||||
struct sys_grent *glist;
|
||||
struct sys_grent *gent;
|
||||
struct group *grp;
|
||||
|
||||
gent = (struct sys_grent *) malloc(sizeof(struct sys_grent));
|
||||
if (gent == NULL) {
|
||||
DEBUG (0, ("Out of memory in getgrent_list!\n"));
|
||||
return NULL;
|
||||
}
|
||||
glist = gent;
|
||||
|
||||
setgrent();
|
||||
grp = getgrent();
|
||||
while (grp != NULL)
|
||||
{
|
||||
int i,num;
|
||||
|
||||
bzero (gent, sizeof(struct sys_grent));
|
||||
if (grp->gr_name) gent->gr_name = strdup(grp->gr_name);
|
||||
if (grp->gr_passwd) gent->gr_passwd = strdup(grp->gr_passwd);
|
||||
gent->gr_gid = grp->gr_gid;
|
||||
|
||||
/* number of strings in gr_mem */
|
||||
for (num = 0; grp->gr_mem[num]; num++);
|
||||
|
||||
/* alloc space for gr_mem string pointers */
|
||||
gent->gr_mem = (char **) malloc(num+1 * sizeof(char *));
|
||||
if (gent->gr_mem == NULL) {
|
||||
DEBUG(0, ("Out of memory in getgrent_list!\n"));
|
||||
endgrent();
|
||||
grent_free(glist);
|
||||
return NULL;
|
||||
}
|
||||
for (i=0; i < num; i++)
|
||||
gent->gr_mem[i] = strdup(grp->gr_mem[i]);
|
||||
gent->gr_mem[num] = NULL;
|
||||
|
||||
grp = getgrent();
|
||||
if (grp)
|
||||
{
|
||||
gent->next = (struct sys_grent *) malloc(sizeof(struct sys_grent));
|
||||
if (gent->next == NULL) {
|
||||
DEBUG(0, ("Out of memory in getgrent_list!\n"));
|
||||
endgrent();
|
||||
grent_free(glist);
|
||||
return NULL;
|
||||
}
|
||||
gent = gent->next;
|
||||
}
|
||||
}
|
||||
|
||||
endgrent();
|
||||
return glist;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Free the single linked list of group entries made by
|
||||
getgrent_list()
|
||||
****************************************************************/
|
||||
void grent_free (struct sys_grent *glist)
|
||||
{
|
||||
while (glist)
|
||||
{
|
||||
char **ary;
|
||||
struct sys_grent *temp;
|
||||
|
||||
if (glist->gr_name) free(glist->gr_name);
|
||||
if (glist->gr_passwd) free(glist->gr_passwd);
|
||||
if (glist->gr_mem)
|
||||
{
|
||||
ary = glist->gr_mem;
|
||||
while (*ary)
|
||||
{
|
||||
free(*ary);
|
||||
ary++;
|
||||
}
|
||||
free(glist->gr_mem);
|
||||
}
|
||||
temp = glist->next;
|
||||
free(glist);
|
||||
glist = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Returns a single linked list of passwd entries.
|
||||
Use pwent_free() to free it after use.
|
||||
****************************************************************/
|
||||
struct sys_pwent * getpwent_list(void)
|
||||
{
|
||||
struct sys_pwent *plist;
|
||||
struct sys_pwent *pent;
|
||||
struct passwd *pwd;
|
||||
|
||||
pent = (struct sys_pwent *) malloc(sizeof(struct sys_pwent));
|
||||
if (pent == NULL) {
|
||||
DEBUG (0, ("Out of memory in getpwent_list!\n"));
|
||||
return NULL;
|
||||
}
|
||||
plist = pent;
|
||||
|
||||
setpwent();
|
||||
pwd = getpwent();
|
||||
while (pwd != NULL)
|
||||
{
|
||||
bzero (pent, sizeof(struct sys_pwent));
|
||||
if (pwd->pw_name) pent->pw_name = strdup(pwd->pw_name);
|
||||
if (pwd->pw_passwd) pent->pw_passwd = strdup(pwd->pw_passwd);
|
||||
pent->pw_uid = pwd->pw_uid;
|
||||
pent->pw_gid = pwd->pw_gid;
|
||||
if (pwd->pw_gecos) pent->pw_name = strdup(pwd->pw_gecos);
|
||||
if (pwd->pw_dir) pent->pw_name = strdup(pwd->pw_dir);
|
||||
if (pwd->pw_shell) pent->pw_name = strdup(pwd->pw_shell);
|
||||
|
||||
|
||||
pwd = getpwent();
|
||||
if (pwd)
|
||||
{
|
||||
pent->next = (struct sys_pwent *) malloc(sizeof(struct sys_pwent));
|
||||
if (pent->next == NULL) {
|
||||
DEBUG(0, ("Out of memory in getgrent_list!\n"));
|
||||
endpwent();
|
||||
pwent_free(plist);
|
||||
return NULL;
|
||||
}
|
||||
pent = pent->next;
|
||||
}
|
||||
}
|
||||
|
||||
endpwent();
|
||||
return plist;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Free the single linked list of passwd entries made by
|
||||
getpwent_list()
|
||||
****************************************************************/
|
||||
void pwent_free (struct sys_pwent *plist)
|
||||
{
|
||||
while (plist)
|
||||
{
|
||||
struct sys_pwent *temp;
|
||||
|
||||
if (plist->pw_name) free(plist->pw_name);
|
||||
if (plist->pw_passwd) free(plist->pw_passwd);
|
||||
if (plist->pw_gecos) free(plist->pw_gecos);
|
||||
if (plist->pw_dir) free(plist->pw_dir);
|
||||
if (plist->pw_shell) free(plist->pw_shell);
|
||||
|
||||
temp = plist->next;
|
||||
free(plist);
|
||||
plist = temp;
|
||||
}
|
||||
}
|
||||
|
@ -803,7 +803,8 @@ static BOOL get_group_alias_entries(DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 sta
|
||||
|
||||
} else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) {
|
||||
char *sep;
|
||||
struct group *grp;
|
||||
struct sys_grent *glist;
|
||||
struct sys_grent *grp;
|
||||
|
||||
sep = lp_winbind_separator();
|
||||
|
||||
@ -811,36 +812,50 @@ static BOOL get_group_alias_entries(DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 sta
|
||||
/* we return the UNIX groups here. This seems to be the right */
|
||||
/* thing to do, since NT member servers return their local */
|
||||
/* groups in the same situation. */
|
||||
setgrent();
|
||||
|
||||
while (num_entries < max_entries && ((grp = getgrent()) != NULL)) {
|
||||
/* use getgrent_list() to retrieve the list of groups to avoid
|
||||
* problems with getgrent possible infinite loop by internal
|
||||
* libc grent structures overwrites by called functions */
|
||||
grp = glist = getgrent_list();
|
||||
if (grp == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
while ((num_entries < max_entries) && (grp != NULL)) {
|
||||
uint32 trid;
|
||||
|
||||
if(!get_group_from_gid(grp->gr_gid, &smap))
|
||||
if(!get_group_from_gid(grp->gr_gid, &smap)) {
|
||||
grp = grp->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (smap.sid_name_use!=SID_NAME_ALIAS)
|
||||
if (smap.sid_name_use!=SID_NAME_ALIAS) {
|
||||
grp = grp->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
sid_split_rid(&smap.sid, &trid);
|
||||
|
||||
/* Don't return winbind groups as they are not local! */
|
||||
if (strchr(smap.nt_name, *sep) != NULL) {
|
||||
DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
|
||||
grp = grp->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Don't return user private groups... */
|
||||
if (Get_Pwnam(smap.nt_name, False) != 0) {
|
||||
DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
|
||||
grp = grp->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
for( i = 0; i < num_entries; i++)
|
||||
if ( (*d_grp)[i].rid == trid ) break;
|
||||
|
||||
if ( i < num_entries )
|
||||
if ( i < num_entries ) {
|
||||
grp = grp->next;
|
||||
continue; /* rid was there, dup! */
|
||||
}
|
||||
|
||||
/* JRA - added this for large group db enumeration... */
|
||||
|
||||
@ -849,19 +864,23 @@ static BOOL get_group_alias_entries(DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 sta
|
||||
not very efficient, but hey...
|
||||
*/
|
||||
start_idx--;
|
||||
grp = grp->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
*d_grp=Realloc(*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
|
||||
if (*d_grp==NULL)
|
||||
if (*d_grp==NULL) {
|
||||
grent_free(glist);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
|
||||
(*d_grp)[num_entries].rid = trid;
|
||||
num_entries++;
|
||||
grp = grp->next;
|
||||
}
|
||||
|
||||
endgrent();
|
||||
grent_free(glist);
|
||||
}
|
||||
|
||||
*p_num_entries = num_entries;
|
||||
|
Loading…
Reference in New Issue
Block a user