| 1 | /* vi: ts=8 sts=4 sw=4 |
| 2 | * |
| 3 | This file is part of the KDE project, module kdesu. |
| 4 | SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <g.t.jansen@stud.tue.nl> |
| 5 | |
| 6 | secure.cpp: Peer credentials for a UNIX socket. |
| 7 | */ |
| 8 | |
| 9 | #include "secure.h" |
| 10 | |
| 11 | #include <config-kdesud.h> |
| 12 | #include <ksud_debug.h> |
| 13 | |
| 14 | #include <cerrno> |
| 15 | #include <fcntl.h> |
| 16 | #include <stdio.h> |
| 17 | #include <string.h> |
| 18 | #include <unistd.h> |
| 19 | |
| 20 | #include <sys/stat.h> |
| 21 | |
| 22 | // FIXME: This is just here to make it compile (since ksock* was removed from kdelibs). |
| 23 | // It would be better to fix it more globally. (Caleb Tennis) |
| 24 | typedef unsigned ksocklen_t; |
| 25 | |
| 26 | /*! |
| 27 | * Under Linux, Socket_security is supported. |
| 28 | */ |
| 29 | |
| 30 | #if HAVE_GETPEEREID |
| 31 | |
| 32 | SocketSecurity::SocketSecurity(int sockfd) |
| 33 | : pid(-1) |
| 34 | , gid(-1) |
| 35 | , uid(-1) |
| 36 | { |
| 37 | uid_t euid; |
| 38 | gid_t egid; |
| 39 | if (getpeereid(sockfd, &euid, &egid) == 0) { |
| 40 | uid = euid; |
| 41 | gid = egid; |
| 42 | pid = -1; |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | #elif HAVE_GETPEERUCRED |
| 47 | |
| 48 | #include <ucred.h> |
| 49 | |
| 50 | SocketSecurity::SocketSecurity(int sockfd) |
| 51 | : pid(-1) |
| 52 | , gid(-1) |
| 53 | , uid(-1) |
| 54 | { |
| 55 | ucred_t *ucred = 0; |
| 56 | |
| 57 | if (getpeerucred(sockfd, &ucred) == 0) { |
| 58 | uid = ucred_geteuid(ucred); |
| 59 | gid = ucred_getrgid(ucred); |
| 60 | pid = -1; |
| 61 | ucred_free(ucred); |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | #elif defined(SO_PEERCRED) |
| 66 | |
| 67 | SocketSecurity::SocketSecurity(int sockfd) |
| 68 | : pid(-1) |
| 69 | , gid(-1) |
| 70 | , uid(-1) |
| 71 | { |
| 72 | ucred cred; |
| 73 | ksocklen_t len = sizeof(struct ucred); |
| 74 | if (getsockopt(fd: sockfd, SOL_SOCKET, SO_PEERCRED, optval: &cred, optlen: &len) < 0) { |
| 75 | qCCritical(KSUD_LOG) << "getsockopt(SO_PEERCRED) " << strerror(errno); |
| 76 | return; |
| 77 | } |
| 78 | pid = cred.pid; |
| 79 | gid = cred.gid; |
| 80 | uid = cred.uid; |
| 81 | } |
| 82 | |
| 83 | #else |
| 84 | #ifdef __GNUC__ |
| 85 | #warning SocketSecurity support for your platform not implemented/available! |
| 86 | #endif |
| 87 | /*! |
| 88 | * The default version does nothing. |
| 89 | */ |
| 90 | |
| 91 | SocketSecurity::SocketSecurity(int sockfd) |
| 92 | : pid(-1) |
| 93 | , gid(-1) |
| 94 | , uid(-1) |
| 95 | { |
| 96 | static bool warned_him = false; |
| 97 | |
| 98 | if (!warned_him) { |
| 99 | qCWarning(KSUD_LOG) << "Using void socket security. Please add support for your" ; |
| 100 | qCWarning(KSUD_LOG) << "platform to src/kdesud/secure.cpp" ; |
| 101 | warned_him = true; |
| 102 | } |
| 103 | |
| 104 | // This passes the test made in handler.cpp |
| 105 | uid = getuid(); |
| 106 | } |
| 107 | |
| 108 | #endif |
| 109 | |