summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2021-12-07 18:13:46 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2021-12-07 18:13:46 +0000
commitc5c9541f4f46bd442862285a0bf12b421744453e (patch)
tree205c39ae1ded804b221a58a2ad2f086d69ece2a0
parent6080004ea3ce2ddc258cb314bf4fc35c11c37b09 (diff)
The ypproto buffer (which supports + lines in master.passwd) was correct
length for maximum amount of strings, but forgot about the struct passwd taken from the start, and it isn't clear if the missing non-string elements cover for that shortage. It would require misconfiguration by root to exceed the buffer. As well, the strings don't need to be aligned, and thus sys/param.h isn't needed for ALIGN() ok millert
-rw-r--r--lib/libc/gen/getpwent.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c
index 78039999f6e..435a9c45c42 100644
--- a/lib/libc/gen/getpwent.c
+++ b/lib/libc/gen/getpwent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getpwent.c,v 1.63 2019/07/02 15:54:05 deraadt Exp $ */
+/* $OpenBSD: getpwent.c,v 1.64 2021/12/07 18:13:45 deraadt Exp $ */
/*
* Copyright (c) 2008 Theo de Raadt
* Copyright (c) 1988, 1993
@@ -30,7 +30,7 @@
* SUCH DAMAGE.
*/
-#include <sys/param.h> /* ALIGN */
+#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <db.h>
@@ -90,13 +90,11 @@ static enum _ypmode __ypmode;
static char *__ypcurrent;
static int __ypcurrentlen;
static int __yp_pw_flags;
-static struct passwd *__ypproto;
static int __getpwent_has_yppw = -1;
static struct _ypexclude *__ypexhead;
static int __has_yppw(void);
static int __has_ypmaster(void);
-static void __ypproto_set(struct passwd *, long long *, int, int *);
static int __ypparse(struct passwd *pw, char *s, int);
#define LOOKUP_BYNAME 0
@@ -110,21 +108,19 @@ static struct passwd *__yppwlookup(int, char *, uid_t, struct passwd *,
#define PASSWD_BYUID \
(__has_ypmaster() ? "master.passwd.byuid" : "passwd.byuid")
-static void
-__ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
-{
- char *ptr;
+static struct passwd *__ypproto;
- /* make this the new prototype */
- ptr = (char *)buf;
+static void __ypproto_set(struct passwd *, struct pw_storage *, int, int *);
- /* first allocate the struct. */
- __ypproto = (struct passwd *)ptr;
- ptr += sizeof(struct passwd);
+static void
+__ypproto_set(struct passwd *pw, struct pw_storage *buf, int flags,
+ int *yp_pw_flagsp)
+{
+ char *ptr = buf->pwbuf;
+ __ypproto = &buf->pw;
/* name */
if (pw->pw_name && (pw->pw_name)[0]) {
- ptr = (char *)ALIGN(ptr);
bcopy(pw->pw_name, ptr, strlen(pw->pw_name) + 1);
__ypproto->pw_name = ptr;
ptr += (strlen(pw->pw_name) + 1);
@@ -133,7 +129,6 @@ __ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
/* password */
if (pw->pw_passwd && (pw->pw_passwd)[0]) {
- ptr = (char *)ALIGN(ptr);
bcopy(pw->pw_passwd, ptr, strlen(pw->pw_passwd) + 1);
__ypproto->pw_passwd = ptr;
ptr += (strlen(pw->pw_passwd) + 1);
@@ -154,7 +149,6 @@ __ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
/* gecos */
if (pw->pw_gecos && (pw->pw_gecos)[0]) {
- ptr = (char *)ALIGN(ptr);
bcopy(pw->pw_gecos, ptr, strlen(pw->pw_gecos) + 1);
__ypproto->pw_gecos = ptr;
ptr += (strlen(pw->pw_gecos) + 1);
@@ -163,7 +157,6 @@ __ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
/* dir */
if (pw->pw_dir && (pw->pw_dir)[0]) {
- ptr = (char *)ALIGN(ptr);
bcopy(pw->pw_dir, ptr, strlen(pw->pw_dir) + 1);
__ypproto->pw_dir = ptr;
ptr += (strlen(pw->pw_dir) + 1);
@@ -172,7 +165,6 @@ __ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
/* shell */
if (pw->pw_shell && (pw->pw_shell)[0]) {
- ptr = (char *)ALIGN(ptr);
bcopy(pw->pw_shell, ptr, strlen(pw->pw_shell) + 1);
__ypproto->pw_shell = ptr;
ptr += (strlen(pw->pw_shell) + 1);
@@ -438,7 +430,7 @@ again:
key.size = 1 + sizeof(_pw_keynum);
if (__hashpw(&key, pwbuf, buflen, pw, &_pw_flags)) {
#ifdef YP
- static long long __yppbuf[_PW_BUF_LEN / sizeof(long long)];
+ static struct pw_storage __yppbuf;
const char *user, *host, *dom;
/* if we don't have YP at all, don't bother. */
@@ -459,7 +451,7 @@ again:
break;
}
- __ypproto_set(pw, __yppbuf, _pw_flags,
+ __ypproto_set(pw, &__yppbuf, _pw_flags,
&__yp_pw_flags);
goto again;
} else if (pw->pw_name[0] == '-') {
@@ -577,7 +569,7 @@ __yppwlookup(int lookup, char *name, uid_t uid, struct passwd *pw,
{
char bf[1 + _PW_NAME_LEN], *ypcurrent = NULL, *map = NULL;
int yp_pw_flags = 0, ypcurrentlen, r, s = -1, pw_keynum;
- static long long yppbuf[_PW_BUF_LEN / sizeof(long long)];
+ static struct pw_storage __yppbuf;
struct _ypexclude *ypexhead = NULL;
const char *host, *user, *dom;
DBT key;
@@ -595,7 +587,7 @@ __yppwlookup(int lookup, char *name, uid_t uid, struct passwd *pw,
if (_yp_check(&__ypdomain) == 0)
continue;
}
- __ypproto_set(pw, yppbuf, *flagsp, &yp_pw_flags);
+ __ypproto_set(pw, &__yppbuf, *flagsp, &yp_pw_flags);
if (!map) {
if (lookup == LOOKUP_BYNAME) {
if ((name = strdup(name)) == NULL) {