]> granicus.if.org Git - pgbouncer/commitdiff
Standardise UNIX socket UID lookup to getpeeruid()
authorMarko Kreen <markokr@gmail.com>
Fri, 13 Apr 2007 12:45:54 +0000 (12:45 +0000)
committerMarko Kreen <markokr@gmail.com>
Fri, 13 Apr 2007 12:45:54 +0000 (12:45 +0000)
Where it does not exists use SO_PEERCRED or getpeerucred().

configure.ac
src/admin.c
src/pooler.c
src/util.c
src/util.h

index 652c0c458704905412ea221a490c06fae5ad9ef5..7cfdef1c8171bd6ee50ecad5b6eeec9922e423a9 100644 (file)
@@ -51,7 +51,7 @@ AC_TYPE_UINT64_T
 AC_SYS_LARGEFILE
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(strlcpy strlcat)
+AC_CHECK_FUNCS(strlcpy strlcat getpeereid getpeerucred)
 AC_SEARCH_LIBS(crypt, crypt, [], AC_MSG_ERROR([crypt not found]))
 
 dnl Find libevent
index 323c4677a7fad72c877d0a0ec21acc869301d5db..cbb5c61d09e66f1177460ba9513fca607d00ed5a 100644 (file)
@@ -807,8 +807,9 @@ bool admin_handle_client(PgSocket *admin, MBuf *pkt, int pkt_type, int pkt_len)
  */
 bool admin_pre_login(PgSocket *client)
 {
-       uid_t peer_uid = 0;
-       bool res;
+       uid_t peer_uid = -1;
+       gid_t peer_gid = -1;
+       int res;
        const char *username = client->auth_user->name;
 
        client->admin_user = 0;
@@ -816,8 +817,8 @@ bool admin_pre_login(PgSocket *client)
 
        /* tag same uid as special */
        if (client->addr.is_unix) {
-               res = get_unix_peer_uid(sbuf_socket(&client->sbuf), &peer_uid);
-               if (res && peer_uid == getuid()
+               res = getpeereid(sbuf_socket(&client->sbuf), &peer_uid, &peer_gid);
+               if (res >= 0 && peer_uid == getuid()
                        && strcmp("pgbouncer", username) == 0)
                {
                        client->own_user = 1;
index 2f26e4943c0eb4a9605b985bae011894e70ff579..753d4b066a135a8e67fa7568c3ae2fc0175f7a87 100644 (file)
@@ -199,11 +199,12 @@ pool_accept(int sock, short flags, void *is_unix)
                log_debug("P: new unix client");
                {
                        uid_t uid;
+                       gid_t gid;
                        log_noise("getuid(): %d", (int)getuid());
-                       if (get_unix_peer_uid(fd, &uid))
+                       if (getpeereid(fd, &uid, &gid) >= 0)
                                log_noise("unix peer uid: %d", (int)uid);
                        else
-                               log_noise("unix peer uid failed");
+                               log_warning("unix peer uid failed: %s", strerror(errno));
                }
                accept_client(fd, NULL, true);
        } else {
index 9b9225df6e42be12d612f7318e404e1aa92536b4..04116dacddf8c2b601d827a13c7595884d6bfaa3 100644 (file)
@@ -403,32 +403,36 @@ void reset_time_cache(void)
 }
 
 /*
- * get other side's uid.
+ * Get other side's uid for UNIX socket.
+ *
+ * Standardise on getpeereid() from BSDs.
  */
-bool get_unix_peer_uid(int fd, uid_t *uid_p)
+#ifndef HAVE_GETPEEREID
+int getpeereid(int fd, uid_t *uid_p, gid_t *gid_p)
 {
-       int res = -1;
 #ifdef SO_PEERCRED
        struct ucred cred;
        socklen_t len = sizeof(cred);
-       res = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len);
-       if (res >= 0)
+       if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) >= 0) {
                *uid_p = cred.uid;
-       else
-               log_error("getsockopt(SO_PEERCRED): %s", strerror(errno));
+               *gid_p = cred.gid;
+               return 0;
+       }
 #else /* !SO_PEERCRED */
-#ifdef LOCAL_PEERCRED
-       struct xucred cred;
-       socklen_t len = sizeof(cred);
-       res = getsockopt(fd, AF_UNIX, LOCAL_PEERCRED, &cred, &len);
-       if (res >= 0)
-               *uid_p = cred.cr_uid;
-       else
-               log_error("getsockopt(LOCAL_PEERCRED): %s", strerror(errno));
-#endif /* !LOCAL_PEERCRED */
+#ifdef HAVE_GETPEERUCRED
+       ucred_t *cred = NULL;
+       if (getpeerucred(fd, &cred) >= 0) {
+               *uid_p = ucred_geteuid(cred);
+               *gid_p = ucred_getegid(cred);
+               ucred_free(cred);
+               if (*uid_p >= 0 && *gid_p >= 0)
+                       return 0;
+       }
+#endif /* HAVE_GETPEERUCRED */
 #endif /* !SO_PEERCRED */
-       return (res >= 0);
+       return -1;
 }
+#endif /* !HAVE_GETPEEREID */
 
 void socket_set_nonblocking(int fd, int val)
 {
index fee4d6656a682ebd152b732b6d91c089847c1a6b..dbefcf33da8be7380c9e0aa195e9accd8b6ef028 100644 (file)
@@ -105,7 +105,10 @@ size_t strlcat(char *dst, const char *src, size_t n);
 /*
  * socket option handling
  */
-bool get_unix_peer_uid(int fd, uid_t *uid_p);
+#ifndef HAVE_GETPEEREID
+int getpeereid(int fd, uid_t *uid_p, gid_t *gid_p);
+#endif
+
 void socket_set_nonblocking(int fd, int val);
 void tune_socket(int sock, bool is_unix);