mirror of
https://github.com/samba-team/samba.git
synced 2025-12-05 12:23:50 +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 commit is contained in:
@@ -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_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_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_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
|
# this includes only the low level parse code, not stuff
|
||||||
# that requires knowledge of security contexts
|
# that requires knowledge of security contexts
|
||||||
|
|||||||
@@ -637,6 +637,8 @@ extern int errno;
|
|||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "util_list.h"
|
#include "util_list.h"
|
||||||
|
|
||||||
|
#include "util_getent.h"
|
||||||
|
|
||||||
#ifndef UBI_BINTREE_H
|
#ifndef UBI_BINTREE_H
|
||||||
#include "ubi_Cache.h"
|
#include "ubi_Cache.h"
|
||||||
#endif /* UBI_BINTREE_H */
|
#endif /* UBI_BINTREE_H */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
45
source/include/util_getent.h
Normal file
45
source/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
source/lib/util_getent.c
Normal file
185
source/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()) {
|
} else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) {
|
||||||
char *sep;
|
char *sep;
|
||||||
struct group *grp;
|
struct sys_grent *glist;
|
||||||
|
struct sys_grent *grp;
|
||||||
|
|
||||||
sep = lp_winbind_separator();
|
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 */
|
/* we return the UNIX groups here. This seems to be the right */
|
||||||
/* thing to do, since NT member servers return their local */
|
/* thing to do, since NT member servers return their local */
|
||||||
/* groups in the same situation. */
|
/* 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;
|
uint32 trid;
|
||||||
|
|
||||||
if(!get_group_from_gid(grp->gr_gid, &smap))
|
if(!get_group_from_gid(grp->gr_gid, &smap)) {
|
||||||
|
grp = grp->next;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (smap.sid_name_use!=SID_NAME_ALIAS)
|
if (smap.sid_name_use!=SID_NAME_ALIAS) {
|
||||||
|
grp = grp->next;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
sid_split_rid(&smap.sid, &trid);
|
sid_split_rid(&smap.sid, &trid);
|
||||||
|
|
||||||
/* Don't return winbind groups as they are not local! */
|
/* Don't return winbind groups as they are not local! */
|
||||||
if (strchr(smap.nt_name, *sep) != NULL) {
|
if (strchr(smap.nt_name, *sep) != NULL) {
|
||||||
DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
|
DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
|
||||||
|
grp = grp->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't return user private groups... */
|
/* Don't return user private groups... */
|
||||||
if (Get_Pwnam(smap.nt_name, False) != 0) {
|
if (Get_Pwnam(smap.nt_name, False) != 0) {
|
||||||
DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
|
DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
|
||||||
|
grp = grp->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i = 0; i < num_entries; i++)
|
for( i = 0; i < num_entries; i++)
|
||||||
if ( (*d_grp)[i].rid == trid ) break;
|
if ( (*d_grp)[i].rid == trid ) break;
|
||||||
|
|
||||||
if ( i < num_entries )
|
if ( i < num_entries ) {
|
||||||
|
grp = grp->next;
|
||||||
continue; /* rid was there, dup! */
|
continue; /* rid was there, dup! */
|
||||||
|
}
|
||||||
|
|
||||||
/* JRA - added this for large group db enumeration... */
|
/* 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...
|
not very efficient, but hey...
|
||||||
*/
|
*/
|
||||||
start_idx--;
|
start_idx--;
|
||||||
|
grp = grp->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
*d_grp=Realloc(*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
|
*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;
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
|
fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
|
||||||
(*d_grp)[num_entries].rid = trid;
|
(*d_grp)[num_entries].rid = trid;
|
||||||
num_entries++;
|
num_entries++;
|
||||||
|
grp = grp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
endgrent();
|
grent_free(glist);
|
||||||
}
|
}
|
||||||
|
|
||||||
*p_num_entries = num_entries;
|
*p_num_entries = num_entries;
|
||||||
|
|||||||
Reference in New Issue
Block a user