getpeereid.diff
text/x-diff
Filename: getpeereid.diff
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/libpq/auth.c | 2 | 6 |
| src/include/port.h | 3 | 0 |
| src/interfaces/libpq/fe-connect.c | 1 | 6 |
| src/port/Makefile | 1 | 0 |
| src/port/pggetpeereid.c | 80 | 0 |
*** a/src/backend/libpq/auth.c
--- b/src/backend/libpq/auth.c
***************
*** 17,28 ****
#include <sys/param.h>
#include <sys/socket.h>
- #ifdef HAVE_UCRED_H
- #include <ucred.h>
- #endif
- #ifdef HAVE_SYS_UCRED_H
- #include <sys/ucred.h>
- #endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
--- 17,22 ----
***************
*** 1757,1839 **** auth_peer(hbaPort *port)
{
char ident_user[IDENT_USERNAME_MAX + 1];
uid_t uid = 0;
struct passwd *pass;
! #if defined(HAVE_GETPEEREID)
! /* Most BSDen, including OS X: use getpeereid() */
! gid_t gid;
!
! errno = 0;
! if (getpeereid(port->sock, &uid, &gid) != 0)
{
- /* We didn't get a valid credentials struct. */
ereport(LOG,
(errcode_for_socket_access(),
errmsg("could not get peer credentials: %m")));
return STATUS_ERROR;
}
- #elif defined(SO_PEERCRED)
- /* Linux: use getsockopt(SO_PEERCRED) */
- struct ucred peercred;
- ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
-
- errno = 0;
- if (getsockopt(port->sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
- so_len != sizeof(peercred))
- {
- /* We didn't get a valid credentials struct. */
- ereport(LOG,
- (errcode_for_socket_access(),
- errmsg("could not get peer credentials: %m")));
- return STATUS_ERROR;
- }
- uid = peercred.uid;
- #elif defined(LOCAL_PEERCRED)
- /* Debian with FreeBSD kernel: use getsockopt(LOCAL_PEERCRED) */
- struct xucred peercred;
- ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
-
- errno = 0;
- if (getsockopt(port->sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 ||
- so_len != sizeof(peercred) ||
- peercred.cr_version != XUCRED_VERSION)
- {
- /* We didn't get a valid credentials struct. */
- ereport(LOG,
- (errcode_for_socket_access(),
- errmsg("could not get peer credentials: %m")));
- return STATUS_ERROR;
- }
- uid = peercred.cr_uid;
- #elif defined(HAVE_GETPEERUCRED)
- /* Solaris: use getpeerucred() */
- ucred_t *ucred;
-
- ucred = NULL; /* must be initialized to NULL */
- if (getpeerucred(port->sock, &ucred) == -1)
- {
- ereport(LOG,
- (errcode_for_socket_access(),
- errmsg("could not get peer credentials: %m")));
- return STATUS_ERROR;
- }
-
- if ((uid = ucred_geteuid(ucred)) == -1)
- {
- ereport(LOG,
- (errcode_for_socket_access(),
- errmsg("could not get effective UID from peer credentials: %m")));
- return STATUS_ERROR;
- }
-
- ucred_free(ucred);
- #else
- ereport(LOG,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("Peer authentication is not supported on local connections on this platform")));
-
- return STATUS_ERROR;
- #endif
pass = getpwuid(uid);
--- 1751,1766 ----
{
char ident_user[IDENT_USERNAME_MAX + 1];
uid_t uid = 0;
+ gid_t gid = 0;
struct passwd *pass;
! if (pgGetpeereid(port->sock, &uid, &gid) != 0)
{
ereport(LOG,
(errcode_for_socket_access(),
errmsg("could not get peer credentials: %m")));
return STATUS_ERROR;
}
pass = getpwuid(uid);
*** a/src/include/port.h
--- b/src/include/port.h
***************
*** 470,473 **** extern int pg_check_dir(const char *dir);
--- 470,476 ----
/* port/pgmkdirp.c */
extern int pg_mkdir_p(char *path, int omode);
+ /* port/pggetpeereid.c */
+ extern int pgGetpeereid(int sock, uid_t *uid, gid_t *gid);
+
#endif /* PG_PORT_H */
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
***************
*** 21,32 ****
#include <ctype.h>
#include <time.h>
#include <unistd.h>
- #ifdef HAVE_UCRED_H
- #include <ucred.h>
- #endif
- #ifdef HAVE_SYS_UCRED_H
- #include <sys/ucred.h>
- #endif
#include "libpq-fe.h"
#include "libpq-int.h"
--- 21,26 ----
***************
*** 1866,1928 **** keep_going: /* We will come back to here until there is
if (conn->requirepeer && conn->requirepeer[0] &&
IS_AF_UNIX(conn->raddr.addr.ss_family))
{
- #if defined(HAVE_GETPEEREID) || defined(SO_PEERCRED) || defined(LOCAL_PEERCRED) || defined(HAVE_GETPEERUCRED)
char pwdbuf[BUFSIZ];
struct passwd pass_buf;
struct passwd *pass;
uid_t uid;
-
- #if defined(HAVE_GETPEEREID)
- /* Most BSDen, including OS X: use getpeereid() */
gid_t gid;
- errno = 0;
- if (getpeereid(conn->sock, &uid, &gid) != 0)
- {
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not get peer credentials: %s\n"),
- pqStrerror(errno, sebuf, sizeof(sebuf)));
- goto error_return;
- }
- #elif defined(SO_PEERCRED)
- /* Linux: use getsockopt(SO_PEERCRED) */
- struct ucred peercred;
- ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
-
- errno = 0;
- if (getsockopt(conn->sock, SOL_SOCKET, SO_PEERCRED,
- &peercred, &so_len) != 0 ||
- so_len != sizeof(peercred))
- {
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not get peer credentials: %s\n"),
- pqStrerror(errno, sebuf, sizeof(sebuf)));
- goto error_return;
- }
- uid = peercred.uid;
- #elif defined(LOCAL_PEERCRED)
- /* Debian with FreeBSD kernel: use LOCAL_PEERCRED */
- struct xucred peercred;
- ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
-
- errno = 0;
- if (getsockopt(conn->sock, 0, LOCAL_PEERCRED,
- &peercred, &so_len) != 0 ||
- so_len != sizeof(peercred) ||
- peercred.cr_version != XUCRED_VERSION)
- {
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not get peer credentials: %s\n"),
- pqStrerror(errno, sebuf, sizeof(sebuf)));
- goto error_return;
- }
- uid = peercred.cr_uid;
- #elif defined(HAVE_GETPEERUCRED)
- /* Solaris: use getpeerucred() */
- ucred_t *ucred;
! ucred = NULL; /* must be initialized to NULL */
! if (getpeerucred(conn->sock, &ucred) == -1)
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get peer credentials: %s\n"),
--- 1860,1873 ----
if (conn->requirepeer && conn->requirepeer[0] &&
IS_AF_UNIX(conn->raddr.addr.ss_family))
{
char pwdbuf[BUFSIZ];
struct passwd pass_buf;
struct passwd *pass;
uid_t uid;
gid_t gid;
! if (pgGetpeereid(conn->sock, &uid, &gid) != 0)
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get peer credentials: %s\n"),
***************
*** 1930,1948 **** keep_going: /* We will come back to here until there is
goto error_return;
}
- if ((uid = ucred_geteuid(ucred)) == -1)
- {
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not get effective UID from peer credentials: %s\n"),
- pqStrerror(errno, sebuf, sizeof(sebuf)));
- ucred_free(ucred);
- goto error_return;
- }
- ucred_free(ucred);
- #else
- #error missing implementation method for requirepeer
- #endif
-
pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
if (pass == NULL)
--- 1875,1880 ----
***************
*** 1960,1970 **** keep_going: /* We will come back to here until there is
conn->requirepeer, pass->pw_name);
goto error_return;
}
- #else /* can't support requirepeer */
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("requirepeer parameter is not supported on this platform\n"));
- goto error_return;
- #endif
}
#ifdef USE_SSL
--- 1892,1897 ----
*** a/src/port/Makefile
--- b/src/port/Makefile
***************
*** 31,37 **** override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS)
LIBS += $(PTHREAD_LIBS)
OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o inet_net_ntop.o noblock.o \
! path.o pgcheckdir.o pgmkdirp.o pgsleep.o pgstrcasecmp.o \
qsort.o qsort_arg.o sprompt.o thread.o
# foo_srv.o and foo.o are both built from foo.c, but only foo.o has -DFRONTEND
--- 31,37 ----
LIBS += $(PTHREAD_LIBS)
OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o inet_net_ntop.o noblock.o \
! path.o pgcheckdir.o pggetpeereid.o pgmkdirp.o pgsleep.o pgstrcasecmp.o \
qsort.o qsort_arg.o sprompt.o thread.o
# foo_srv.o and foo.o are both built from foo.c, but only foo.o has -DFRONTEND
*** /dev/null
--- b/src/port/pggetpeereid.c
***************
*** 0 ****
--- 1,80 ----
+ /*-------------------------------------------------------------------------
+ *
+ * pggetpeereid.c
+ * get peer userid for UNIX socket
+ *
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * src/port/pggetpeereid.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ #include "c.h"
+
+ #include <sys/param.h>
+ #include <sys/socket.h>
+ #include <unistd.h>
+ #ifdef HAVE_SYS_UN_H
+ #include <sys/un.h>
+ #endif
+ #ifdef HAVE_UCRED_H
+ #include <ucred.h>
+ #endif
+ #ifdef HAVE_SYS_UCRED_H
+ #include <sys/ucred.h>
+ #endif
+
+ int pgGetpeereid(int sock, uid_t *uid, gid_t *gid)
+ {
+ #if defined(HAVE_GETPEEREID)
+ /* Most BSDen, including OS X: use getpeereid() */
+ errno = 0;
+ return getpeereid(sock, uid, gid);
+ #elif defined(SO_PEERCRED)
+ /* Linux: use getsockopt(SO_PEERCRED) */
+ struct ucred peercred;
+ ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
+
+ errno = 0;
+ if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
+ so_len != sizeof(peercred))
+ return -1;
+ *uid = peercred.uid;
+ *gid = peercred.gid;
+ return 0;
+ #elif defined(LOCAL_PEERCRED)
+ /* Debian with FreeBSD kernel: use LOCAL_PEERCRED */
+ struct xucred peercred;
+ ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
+
+ errno = 0;
+ if (getsockopt(conn->sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 ||
+ so_len != sizeof(peercred) ||
+ peercred.cr_version != XUCRED_VERSION)
+ return -1;
+ *uid = peercred.cr_uid;
+ *gid = peercred.cr_gid;
+ return 0;
+ #elif defined(HAVE_GETPEERUCRED)
+ /* Solaris: use getpeerucred() */
+ ucred_t *ucred;
+
+ errno = 0;
+ ucred = NULL; /* must be initialized to NULL */
+ if (getpeerucred(sock, &ucred) == -1)
+ return -1;
+
+ *uid = ucred_geteuid(ucred);
+ *gid = ucred_getegid(ucred);
+ ucred_free(ucred);
+ if (*uid == (pid_t)(-1) || *gid == (gid_t)(-1))
+ return -1;
+ return 0;
+ #else
+ errno = ENOSYS;
+ return -1;
+ #endif
+ }