1
0
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:
Simo Sorce 2001-05-29 07:34:01 +00:00
parent 415c317bc9
commit bbf5ea221a
6 changed files with 835 additions and 574 deletions

View File

@ -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

View File

@ -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

View 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
View 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;
}
}

View File

@ -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;