2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-04 16:25:25 +00:00

Refactor code to open passwd/group file and add setpassent/setgroupent.

This makes the "stayopen" semantics match the system passwd/group
functions.  The getpwent/getgrent functions now open the database
if it is not already open.
This commit is contained in:
Todd C. Miller
2022-11-22 08:45:14 -07:00
parent 4d7823e518
commit 1c9c7bd34a
3 changed files with 90 additions and 75 deletions

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2005,2008,2010-2015 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2005,2008,2010-2015,2022 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -47,6 +47,7 @@ static int gr_stayopen;
void mysetgrfile(const char *); void mysetgrfile(const char *);
void mysetgrent(void); void mysetgrent(void);
void myendgrent(void); void myendgrent(void);
int mysetgroupent(int);
struct group *mygetgrent(void); struct group *mygetgrent(void);
struct group *mygetgrnam(const char *); struct group *mygetgrnam(const char *);
struct group *mygetgrgid(gid_t); struct group *mygetgrgid(gid_t);
@@ -59,8 +60,8 @@ mysetgrfile(const char *file)
myendgrent(); myendgrent();
} }
void static int
mysetgrent(void) open_group(int reset)
{ {
if (grf == NULL) { if (grf == NULL) {
grf = fopen(grfile, "r"); grf = fopen(grfile, "r");
@@ -70,10 +71,27 @@ mysetgrent(void)
grf = NULL; grf = NULL;
} }
} }
} else { if (grf == NULL)
return 0;
} else if (reset) {
rewind(grf); rewind(grf);
} }
gr_stayopen = 1; return 1;
}
int
mysetgroupent(int stayopen)
{
if (!open_group(1))
return 0;
gr_stayopen = stayopen;
return 1;
}
void
mysetgrent(void)
{
mysetgroupent(0);
} }
void void
@@ -97,6 +115,9 @@ mygetgrent(void)
const char *errstr; const char *errstr;
int n; int n;
if (!open_group(0))
return NULL;
next_entry: next_entry:
if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL) if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
return NULL; return NULL;
@@ -140,16 +161,8 @@ mygetgrnam(const char *name)
{ {
struct group *gr; struct group *gr;
if (grf == NULL) { if (!open_group(1))
if ((grf = fopen(grfile, "r")) == NULL) return NULL;
return NULL;
if (fcntl(fileno(grf), F_SETFD, FD_CLOEXEC) == -1) {
fclose(grf);
return NULL;
}
} else {
rewind(grf);
}
while ((gr = mygetgrent()) != NULL) { while ((gr = mygetgrent()) != NULL) {
if (strcmp(gr->gr_name, name) == 0) if (strcmp(gr->gr_name, name) == 0)
break; break;
@@ -166,16 +179,8 @@ mygetgrgid(gid_t gid)
{ {
struct group *gr; struct group *gr;
if (grf == NULL) { if (!open_group(1))
if ((grf = fopen(grfile, "r")) == NULL) return NULL;
return NULL;
if (fcntl(fileno(grf), F_SETFD, FD_CLOEXEC) == -1) {
fclose(grf);
return NULL;
}
} else {
rewind(grf);
}
while ((gr = mygetgrent()) != NULL) { while ((gr = mygetgrent()) != NULL) {
if (gr->gr_gid == gid) if (gr->gr_gid == gid)
break; break;

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2005, 2008, 2010-2015 * Copyright (c) 2005, 2008, 2010-2015, 2022
* Todd C. Miller <Todd.Miller@sudo.ws> * Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@@ -67,8 +67,8 @@ testsudoers_setpwfile(const char *file)
testsudoers_endpwent(); testsudoers_endpwent();
} }
void static int
testsudoers_setpwent(void) open_passwd(int reset)
{ {
if (pwf == NULL) { if (pwf == NULL) {
pwf = fopen(pwfile, "r"); pwf = fopen(pwfile, "r");
@@ -78,10 +78,27 @@ testsudoers_setpwent(void)
pwf = NULL; pwf = NULL;
} }
} }
} else { if (pwf == NULL)
return 0;
} else if (reset) {
rewind(pwf); rewind(pwf);
} }
pw_stayopen = 1; return 1;
}
int
testsudoers_setpassent(int stayopen)
{
if (!open_passwd(1))
return 0;
pw_stayopen = stayopen;
return 1;
}
void
testsudoers_setpwent(void)
{
testsudoers_setpassent(0);
} }
void void
@@ -104,6 +121,9 @@ testsudoers_getpwent(void)
char *cp, *colon; char *cp, *colon;
const char *errstr; const char *errstr;
if (!open_passwd(0))
return NULL;
next_entry: next_entry:
if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL) if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
return NULL; return NULL;
@@ -151,16 +171,8 @@ testsudoers_getpwnam(const char *name)
{ {
struct passwd *pw; struct passwd *pw;
if (pwf == NULL) { if (!open_passwd(1))
if ((pwf = fopen(pwfile, "r")) == NULL) return NULL;
return NULL;
if (fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC) == -1) {
fclose(pwf);
return NULL;
}
} else {
rewind(pwf);
}
while ((pw = testsudoers_getpwent()) != NULL) { while ((pw = testsudoers_getpwent()) != NULL) {
if (strcmp(pw->pw_name, name) == 0) if (strcmp(pw->pw_name, name) == 0)
break; break;
@@ -177,16 +189,8 @@ testsudoers_getpwuid(uid_t uid)
{ {
struct passwd *pw; struct passwd *pw;
if (pwf == NULL) { if (!open_passwd(1))
if ((pwf = fopen(pwfile, "r")) == NULL) return NULL;
return NULL;
if (fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC) == -1) {
fclose(pwf);
return NULL;
}
} else {
rewind(pwf);
}
while ((pw = testsudoers_getpwent()) != NULL) { while ((pw = testsudoers_getpwent()) != NULL) {
if (pw->pw_uid == uid) if (pw->pw_uid == uid)
break; break;
@@ -203,11 +207,11 @@ testsudoers_setgrfile(const char *file)
{ {
grfile = file; grfile = file;
if (grf != NULL) if (grf != NULL)
endgrent(); testsudoers_endgrent();
} }
void static int
testsudoers_setgrent(void) open_group(int reset)
{ {
if (grf == NULL) { if (grf == NULL) {
grf = fopen(grfile, "r"); grf = fopen(grfile, "r");
@@ -217,10 +221,27 @@ testsudoers_setgrent(void)
grf = NULL; grf = NULL;
} }
} }
} else { if (grf == NULL)
return 0;
} else if (reset) {
rewind(grf); rewind(grf);
} }
gr_stayopen = 1; return 1;
}
int
testsudoers_setgroupent(int stayopen)
{
if (!open_group(1))
return 0;
gr_stayopen = stayopen;
return 1;
}
void
testsudoers_setgrent(void)
{
testsudoers_setgroupent(0);
} }
void void
@@ -244,6 +265,9 @@ testsudoers_getgrent(void)
const char *errstr; const char *errstr;
int n; int n;
if (!open_group(0))
return NULL;
next_entry: next_entry:
if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL) if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
return NULL; return NULL;
@@ -287,16 +311,8 @@ testsudoers_getgrnam(const char *name)
{ {
struct group *gr; struct group *gr;
if (grf == NULL) { if (!open_group(1))
if ((grf = fopen(grfile, "r")) == NULL) return NULL;
return NULL;
if (fcntl(fileno(grf), F_SETFD, FD_CLOEXEC) == -1) {
fclose(grf);
grf = NULL;
}
} else {
rewind(grf);
}
while ((gr = testsudoers_getgrent()) != NULL) { while ((gr = testsudoers_getgrent()) != NULL) {
if (strcmp(gr->gr_name, name) == 0) if (strcmp(gr->gr_name, name) == 0)
break; break;
@@ -313,16 +329,8 @@ testsudoers_getgrgid(gid_t gid)
{ {
struct group *gr; struct group *gr;
if (grf == NULL) { if (!open_group(1))
if ((grf = fopen(grfile, "r")) == NULL) return NULL;
return NULL;
if (fcntl(fileno(grf), F_SETFD, FD_CLOEXEC) == -1) {
fclose(grf);
grf = NULL;
}
} else {
rewind(grf);
}
while ((gr = testsudoers_getgrent()) != NULL) { while ((gr = testsudoers_getgrent()) != NULL) {
if (gr->gr_gid == gid) if (gr->gr_gid == gid)
break; break;

View File

@@ -30,6 +30,7 @@
void testsudoers_setgrfile(const char *); void testsudoers_setgrfile(const char *);
void testsudoers_setgrent(void); void testsudoers_setgrent(void);
void testsudoers_endgrent(void); void testsudoers_endgrent(void);
int testsudoers_setgroupent(int);
struct group *testsudoers_getgrent(void); struct group *testsudoers_getgrent(void);
struct group *testsudoers_getgrnam(const char *); struct group *testsudoers_getgrnam(const char *);
struct group *testsudoers_getgrgid(gid_t); struct group *testsudoers_getgrgid(gid_t);
@@ -37,6 +38,7 @@ struct group *testsudoers_getgrgid(gid_t);
void testsudoers_setpwfile(const char *); void testsudoers_setpwfile(const char *);
void testsudoers_setpwent(void); void testsudoers_setpwent(void);
void testsudoers_endpwent(void); void testsudoers_endpwent(void);
int testsudoers_setpassent(int);
struct passwd *testsudoers_getpwent(void); struct passwd *testsudoers_getpwent(void);
struct passwd *testsudoers_getpwnam(const char *); struct passwd *testsudoers_getpwnam(const char *);
struct passwd *testsudoers_getpwuid(uid_t); struct passwd *testsudoers_getpwuid(uid_t);