/* buffer for pgaddr string conversions (with port) */
#define PGADDR_BUF (INET6_ADDRSTRLEN + 10)
+struct sockaddr_ucreds {
+ struct sockaddr_in sin;
+ uid_t uid;
+ pid_t pid;
+};
+
/*
* AF_INET,AF_INET6 are stored as-is,
- * AF_UNIX uses sockaddr_in port.
+ * AF_UNIX uses sockaddr_in port + uid/pid.
*/
union PgAddr {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
+ struct sockaddr_ucreds scred;
};
static inline bool pga_is_unix(const PgAddr *a) { return a->sa.sa_family == AF_UNIX; }
else
linkbuf[0] = 0;
- backend_pid = be32dec(sk->cancel_key);
+ /* get pid over unix socket */
+ if (pga_is_unix(&sk->remote_addr))
+ backend_pid = sk->remote_addr.scred.pid;
+ else
+ backend_pid = 0;
+ /* if that failed, get it from cancel key */
+ if (is_server_socket(sk) && backend_pid == 0)
+ backend_pid = be32dec(sk->cancel_key);
pktbuf_write_DataRow(buf, debug ? SKF_DBG : SKF_STD,
is_server_socket(sk) ? "S" :"C",
log_noise("new fd from accept=%d", fd);
if (is_unix) {
- uid_t uid;
- gid_t gid;
- log_noise("getuid(): %d", (int)getuid());
- if (getpeereid(fd, &uid, &gid) >= 0)
- log_noise("unix peer uid: %d", (int)uid);
- else
- log_warning("unix peer uid failed: %s", strerror(errno));
-
client = accept_client(fd, true);
} else {
client = accept_client(fd, false);
db = sock->pool ? sock->pool->db->name : "(nodb)";
user = sock->auth_user ? sock->auth_user->name : "(nouser)";
if (pga_is_unix(&sock->remote_addr)) {
- host = "unix";
+ unsigned long pid = sock->remote_addr.scred.pid;
+ if (pid) {
+ snprintf(host6, sizeof(host6), "unix(%lu)", pid);
+ host = host6;
+ } else {
+ host = "unix";
+ }
} else {
host = pga_ntop(&sock->remote_addr, host6, sizeof(host6));
}
int err;
if (is_unix) {
+ uid_t uid = 0;
+ gid_t gid = 0;
+ pid_t pid = 0;
pga_set(dst, AF_UNIX, cf_listen_port);
+ if (getpeercreds(fd, &uid, &gid, &pid) >= 0) {
+ log_noise("unix peer uid: %d", (int)uid);
+ } else {
+ log_warning("unix peer uid failed: %s", strerror(errno));
+ }
+ dst->scred.uid = uid;
+ dst->scred.pid = pid;
} else {
err = getpeername(fd, (struct sockaddr *)dst, &len);
if (err < 0) {
if (is_unix) {
pga_set(dst, AF_UNIX, cf_listen_port);
+ dst->scred.uid = geteuid();
+ dst->scred.pid = getpid();
} else {
err = getsockname(fd, (struct sockaddr *)dst, &len);
if (err < 0) {