listen, client: enable SO_PASSCRED, get client's uid
Enable authentication over unix sockets. Store the client's uid in the client struct.
This commit is contained in:
parent
fa56ff3d52
commit
4a7ad5b618
13
src/client.c
13
src/client.c
@ -72,8 +72,13 @@ struct client {
|
|||||||
char buffer[CLIENT_MAX_BUFFER_LENGTH];
|
char buffer[CLIENT_MAX_BUFFER_LENGTH];
|
||||||
size_t bufferLength;
|
size_t bufferLength;
|
||||||
size_t bufferPos;
|
size_t bufferPos;
|
||||||
|
|
||||||
int fd; /* file descriptor; -1 if expired */
|
int fd; /* file descriptor; -1 if expired */
|
||||||
int permission;
|
int permission;
|
||||||
|
|
||||||
|
/** the uid of the client process, or -1 if unknown */
|
||||||
|
int uid;
|
||||||
|
|
||||||
time_t lastTime;
|
time_t lastTime;
|
||||||
struct strnode *cmd_list; /* for when in list mode */
|
struct strnode *cmd_list; /* for when in list mode */
|
||||||
struct strnode *cmd_list_tail; /* for when in list mode */
|
struct strnode *cmd_list_tail; /* for when in list mode */
|
||||||
@ -147,6 +152,11 @@ int client_is_expired(const struct client *client)
|
|||||||
return client->fd < 0;
|
return client->fd < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int client_get_uid(const struct client *client)
|
||||||
|
{
|
||||||
|
return client->uid;
|
||||||
|
}
|
||||||
|
|
||||||
int client_get_permission(const struct client *client)
|
int client_get_permission(const struct client *client)
|
||||||
{
|
{
|
||||||
return client->permission;
|
return client->permission;
|
||||||
@ -323,7 +333,7 @@ sockaddr_to_tmp_string(const struct sockaddr *addr)
|
|||||||
return hostname;
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_new(int fd, const struct sockaddr *addr)
|
void client_new(int fd, const struct sockaddr *addr, int uid)
|
||||||
{
|
{
|
||||||
struct client *client;
|
struct client *client;
|
||||||
|
|
||||||
@ -337,6 +347,7 @@ void client_new(int fd, const struct sockaddr *addr)
|
|||||||
list_add(&client->siblings, &clients);
|
list_add(&client->siblings, &clients);
|
||||||
++num_clients;
|
++num_clients;
|
||||||
client_init(client, fd);
|
client_init(client, fd);
|
||||||
|
client->uid = uid;
|
||||||
SECURE("client %i: opened from %s\n", client->num,
|
SECURE("client %i: opened from %s\n", client->num,
|
||||||
sockaddr_to_tmp_string(addr));
|
sockaddr_to_tmp_string(addr));
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,16 @@ void client_manager_deinit(void);
|
|||||||
int client_manager_io(void);
|
int client_manager_io(void);
|
||||||
void client_manager_expire(void);
|
void client_manager_expire(void);
|
||||||
|
|
||||||
void client_new(int fd, const struct sockaddr *addr);
|
void client_new(int fd, const struct sockaddr *addr, int uid);
|
||||||
|
|
||||||
int client_is_expired(const struct client *client);
|
int client_is_expired(const struct client *client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the uid of the client process, or a negative value if the
|
||||||
|
* uid is unknown
|
||||||
|
*/
|
||||||
|
int client_get_uid(const struct client *client);
|
||||||
|
|
||||||
int client_get_permission(const struct client *client);
|
int client_get_permission(const struct client *client);
|
||||||
|
|
||||||
void client_set_permission(struct client *client, int permission);
|
void client_set_permission(struct client *client, int permission);
|
||||||
|
23
src/listen.c
23
src/listen.c
@ -74,6 +74,7 @@ static int establishListen(int pf, const struct sockaddr *addrp,
|
|||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
int allowReuse = ALLOW_REUSE;
|
int allowReuse = ALLOW_REUSE;
|
||||||
|
int passcred = 1;
|
||||||
|
|
||||||
if ((sock = socket(pf, SOCK_STREAM, 0)) < 0)
|
if ((sock = socket(pf, SOCK_STREAM, 0)) < 0)
|
||||||
FATAL("socket < 0\n");
|
FATAL("socket < 0\n");
|
||||||
@ -96,6 +97,10 @@ static int establishListen(int pf, const struct sockaddr *addrp,
|
|||||||
if (listen(sock, 5) < 0)
|
if (listen(sock, 5) < 0)
|
||||||
FATAL("problems listen'ing: %s\n", strerror(errno));
|
FATAL("problems listen'ing: %s\n", strerror(errno));
|
||||||
|
|
||||||
|
#if defined(HAVE_UN) && defined(SO_PASSCRED)
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &passcred, sizeof(passcred));
|
||||||
|
#endif
|
||||||
|
|
||||||
numberOfListenSockets++;
|
numberOfListenSockets++;
|
||||||
listenSockets =
|
listenSockets =
|
||||||
xrealloc(listenSockets, sizeof(int) * numberOfListenSockets);
|
xrealloc(listenSockets, sizeof(int) * numberOfListenSockets);
|
||||||
@ -258,6 +263,22 @@ void freeAllListenSockets(void)
|
|||||||
listenSockets = NULL;
|
listenSockets = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_remote_uid(int fd)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_UN) && defined(SO_PEERCRED)
|
||||||
|
struct ucred cred;
|
||||||
|
socklen_t len = sizeof (cred);
|
||||||
|
|
||||||
|
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return cred.uid;
|
||||||
|
#else
|
||||||
|
(void)fd;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void getConnections(fd_set * fds)
|
void getConnections(fd_set * fds)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -269,7 +290,7 @@ void getConnections(fd_set * fds)
|
|||||||
if (FD_ISSET(listenSockets[i], fds)) {
|
if (FD_ISSET(listenSockets[i], fds)) {
|
||||||
if ((fd = accept(listenSockets[i], &sockAddr, &socklen))
|
if ((fd = accept(listenSockets[i], &sockAddr, &socklen))
|
||||||
>= 0) {
|
>= 0) {
|
||||||
client_new(fd, &sockAddr);
|
client_new(fd, &sockAddr, get_remote_uid(fd));
|
||||||
} else if (fd < 0
|
} else if (fd < 0
|
||||||
&& (errno != EAGAIN && errno != EINTR)) {
|
&& (errno != EAGAIN && errno != EINTR)) {
|
||||||
ERROR("Problems accept()'ing\n");
|
ERROR("Problems accept()'ing\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user