CFLAGS+=$(LIBUCW_CFLAGS) $(LIBUCW_JSON_CFLAGS)
LIBS+=$(LIBUCW_LIBS) $(LIBUCW_JSON_LIBS)
-# Programs we want to compile
-PROGS+=$(o)/subauthd $(o)/subauth
-
-# And how they are created
-$(o)/subauthd: $(o)/subauthd.o
-$(o)/subauth: $(o)/subauth.o
-
-# Configuration files
-CONFIGS+=subauthd
+include $(s)/server/Makefile
+include $(s)/client/Makefile
# And finally the default rules of the build system
include $(BUILDSYS)/Makebottom
--- /dev/null
+DIRS+=client
+
+PROGS+=$(o)/client/subauth
+
+$(o)/client/subauth: $(o)/client/subauth.o
--- /dev/null
+/*
+ * Sub-authentication Client
+ *
+ * (c) 2017 Martin Mares <mj@ucw.cz>
+ */
+
+#include <ucw/lib.h>
+#include <ucw/opt.h>
+#include <ucw-json/json.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "autoconf.h"
+
+static char *socket_path = INSTALL_RUN_DIR "/subauthd.socket";
+
+static const struct opt_section options = {
+ OPT_ITEMS {
+ OPT_HELP("A client to the sub-authentication daemon."),
+ OPT_HELP("Usage: subauth [options]"),
+ OPT_HELP(""),
+ OPT_HELP("Options:"),
+ OPT_HELP_OPTION,
+ OPT_END
+ }
+};
+
+int main(int argc UNUSED, char **argv)
+{
+ opt_parse(&options, argv+1);
+
+ int sk = socket(PF_UNIX, SOCK_SEQPACKET, 0);
+ if (sk < 0)
+ die("socket(PF_UNIX, SOCK_SEQPACKET): %m");
+
+ struct sockaddr_un sun;
+ sun.sun_family = AF_UNIX;
+ if (strlen(socket_path) >= sizeof(sun.sun_path))
+ die("Socket path too long");
+ strcpy(sun.sun_path, socket_path);
+
+ if (connect(sk, (struct sockaddr *) &sun, sizeof(sun)) < 0)
+ die("Cannot connect to %s: %m", socket_path);
+
+ struct fastbuf *out = bfdopen(1, 4096);
+
+ struct json_context *js = json_new();
+ struct json_node *rq = json_new_object(js);
+
+ bprintf(out, ">>> Request:\n");
+ json_write(js, out, rq);
+ bflush(out);
+
+ struct fastbuf *rq_fb = fbgrow_create(4096);
+ json_write(js, rq_fb, rq);
+ byte *rq_buf;
+ uint rq_len = fbgrow_get_buf(rq_fb, &rq_buf);
+ if (send(sk, rq_buf, rq_len, 0) < 0)
+ die("Cannot send request: %m");
+ bclose(rq_fb);
+
+ byte rp_buf[4096]; // FIXME
+ int rp_len = recv(sk, rp_buf, sizeof(rp_buf), 0);
+ if (rp_len < 0)
+ die("Cannot receive reply: %m");
+
+ puts("Parsing reply");
+ struct fastbuf rp_fb;
+ fbbuf_init_read(&rp_fb, rp_buf, rp_len, 0);
+ struct json_node *rp = json_parse(js, &rp_fb);
+ bprintf(out, "<<< Reply:\n");
+ json_write(js, out, rp);
+ bflush(out);
+
+ return 0;
+}
our($srcdir, $libdir);
BEGIN {
# Find the sources
- my $pkgfile = "subauthd.c";
+ my $pkgfile = "server/subauthd.c";
if (!defined ($srcdir = $ENV{"SRCDIR"})) {
if (-f $pkgfile) {
$srcdir=".";
--- /dev/null
+DIRS+=server
+
+PROGS+=$(o)/server/subauthd
+CONFIGS+=subauthd
+
+$(o)/server/subauthd: $(addprefix $(o)/server/, subauthd.o cmd.o)
--- /dev/null
+/*
+ * Sub-authentication Daemon: Commands
+ *
+ * (c) 2017 Martin Mares <mj@ucw.cz>
+ */
+
+#include <ucw/lib.h>
+
+#include "subauthd.h"
+
+void cmd_error(struct client *c, const char *err)
+{
+ json_object_set(c->reply, "error", json_new_string(c->json, err));
+}
+
+
--- /dev/null
+/*
+ * Sub-authentication Daemon
+ *
+ * (c) 2017 Martin Mares <mj@ucw.cz>
+ */
+
+#include <ucw/lib.h>
+#include <ucw/conf.h>
+#include <ucw/log.h>
+#include <ucw/opt.h>
+#include <ucw/trans.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "subauthd.h"
+
+static char *socket_path = "subauthd.socket";
+static uint max_connections = ~0U;
+
+static struct main_file listen_socket;
+static uint num_connections;
+
+static byte packet_buffer[MAX_PACKET_SIZE];
+static byte oob_data_buffer[MAX_OOB_DATA_SIZE];
+
+static int socket_read_handler(struct main_file *fi);
+static int socket_write_handler(struct main_file *fi);
+
+static void client_close(struct client *c)
+{
+ msg(L_INFO, "Closing connection");
+ file_del(&c->socket);
+ timer_del(&c->timer);
+ close(c->socket.fd);
+ json_delete(c->json);
+ xfree(c);
+ num_connections--;
+}
+
+static void socket_timeout_handler(struct main_timer *tm)
+{
+ struct client *c = tm->data;
+ msg(L_INFO, "Client timeout");
+ client_close(c);
+}
+
+static void try_send_reply(struct client *c)
+{
+ struct fastbuf fb;
+ fbbuf_init_write(&fb, packet_buffer, MAX_PACKET_SIZE);
+
+ TRANS_TRY
+ {
+ json_write(c->json, &fb, c->reply);
+ }
+ TRANS_CATCH(x)
+ {
+ msg(L_ERROR, "Unable to construct reply, it is probably too long");
+ fbbuf_init_write(&fb, packet_buffer, MAX_PACKET_SIZE);
+ bputs(&fb, "{ \"error\": \"Reply too long\" }\n");
+ }
+ TRANS_END;
+
+ int len = fbbuf_count_written(&fb);
+ msg(L_INFO, "Sending reply of %d bytes", len);
+ if (send(c->socket.fd, packet_buffer, len, 0) < 0)
+ {
+ if (errno == EAGAIN || errno == EINTR)
+ {
+ msg(L_INFO, "Postponed send");
+ c->socket.write_handler = socket_write_handler;
+ file_chg(&c->socket);
+ }
+ msg(L_ERROR, "Client write error: %m");
+ client_close(c);
+ }
+ else
+ {
+ msg(L_INFO, "Reply sent");
+ c->socket.read_handler = socket_read_handler;
+ c->socket.write_handler = NULL;
+ file_chg(&c->socket);
+ timer_add_rel(&c->timer, SOCKET_TIMEOUT);
+ }
+}
+
+static void send_reply(struct client *c)
+{
+ timer_add_rel(&c->timer, SOCKET_TIMEOUT);
+ try_send_reply(c);
+}
+
+static void received_packet(struct client *c, byte *pkt, int len)
+{
+ json_reset(c->json);
+
+ struct fastbuf fb;
+ fbbuf_init_read(&fb, pkt, len, 0);
+
+ c->reply = json_new_object(c->json);
+
+ TRANS_TRY
+ {
+ c->request = json_parse(c->json, &fb);
+ }
+ TRANS_CATCH(x)
+ {
+ cmd_error(c, "Parse error");
+ send_reply(c);
+ return;
+ }
+ TRANS_END;
+
+ cmd_error(c, "OK");
+ send_reply(c);
+}
+
+static int socket_write_handler(struct main_file *fi)
+{
+ struct client *c = fi->data;
+ try_send_reply(c);
+ return HOOK_IDLE;
+}
+
+static int socket_read_handler(struct main_file *fi)
+{
+ struct client *c = fi->data;
+
+ struct iovec iov = {
+ .iov_base = packet_buffer,
+ .iov_len = MAX_PACKET_SIZE,
+ };
+
+ struct msghdr mh = {
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = oob_data_buffer,
+ .msg_controllen = MAX_OOB_DATA_SIZE,
+ };
+
+ ssize_t len = recvmsg(fi->fd, &mh, 0);
+ if (len < 0)
+ {
+ if (errno != EAGAIN && errno != EINTR)
+ msg(L_ERROR, "Socket read: %m");
+ return HOOK_IDLE;
+ }
+
+ if (!len)
+ {
+ client_close(c);
+ return HOOK_IDLE;
+ }
+
+ struct ucred *cred = NULL;
+ for (struct cmsghdr *cm = CMSG_FIRSTHDR(&mh); cm; cm = CMSG_NXTHDR(&mh, cm))
+ {
+ if (cm->cmsg_level == SOL_SOCKET)
+ {
+ if (cm->cmsg_type == SCM_RIGHTS)
+ {
+ // We are not interested in receiving file descriptor, but despite
+ // that they could be attached to the message. If it happens, simply
+ // close them.
+ int *fdptr = (int *) CMSG_DATA(cm);
+ int nfd = cm->cmsg_len / sizeof(int);
+ for (int i=0; i<nfd; i++)
+ close(fdptr[i]);
+ }
+ else if (cm->cmsg_type == SCM_CREDENTIALS)
+ {
+ ASSERT(cm->cmsg_len >= sizeof(cred));
+ cred = (struct ucred *) CMSG_DATA(cm);
+ }
+ }
+ }
+
+ if (!cred)
+ {
+ msg(L_ERROR, "Dropping message with no credentials");
+ return HOOK_RETRY;
+ }
+
+ msg(L_INFO, "Got message from UID %d", (int) cred->uid);
+ c->uid = cred->uid;
+
+ fi->read_handler = NULL;
+ file_chg(fi);
+
+ received_packet(c, packet_buffer, len);
+ return HOOK_RETRY;
+}
+
+static int listen_read_handler(struct main_file *fi)
+{
+ struct sockaddr_un client;
+ socklen_t addr_len = sizeof(client);
+
+ int new_sk = accept(fi->fd, &client, &addr_len);
+ if (new_sk < 0)
+ {
+ if (errno != EAGAIN && errno != EINTR)
+ msg(L_ERROR, "Socket accept: %m");
+ return HOOK_IDLE;
+ }
+
+ if (num_connections >= max_connections)
+ {
+ msg(L_WARN, "Too many connections (you might need to increase MaxConnections)");
+ close(new_sk);
+ return HOOK_IDLE;
+ }
+ num_connections++;
+
+ msg(L_INFO, "Accepted connection");
+
+ if (fcntl(new_sk, F_SETFL, fcntl(new_sk, F_GETFL) | O_NONBLOCK) < 0)
+ die("Cannot set O_NONBLOCK: %m");
+
+ struct client *c = xmalloc_zero(sizeof(*c));
+ c->json = json_new();
+
+ c->socket.fd = new_sk;
+ c->socket.read_handler = socket_read_handler;
+ c->socket.data = c;
+ file_add(&c->socket);
+
+ c->timer.handler = socket_timeout_handler;
+ c->timer.data = c;
+ timer_add_rel(&c->timer, SOCKET_TIMEOUT);
+
+ return HOOK_RETRY;
+}
+
+static void init_socket(void)
+{
+ int sk = socket(PF_UNIX, SOCK_SEQPACKET, 0);
+ if (sk < 0)
+ die("socket(PF_UNIX, SOCK_SEQPACKET): %m");
+
+ if (fcntl(sk, F_SETFL, fcntl(sk, F_GETFL) | O_NONBLOCK) < 0)
+ die("Cannot set O_NONBLOCK: %m");
+
+ struct sockaddr_un sun;
+ sun.sun_family = AF_UNIX;
+ if (strlen(socket_path) >= sizeof(sun.sun_path))
+ die("SocketPath too long");
+ strcpy(sun.sun_path, socket_path);
+
+ if (unlink(socket_path) < 0 && errno != ENOENT)
+ die("Cannot unlink old socket %s: %m", socket_path);
+
+ if (bind(sk, (struct sockaddr *) &sun, sizeof(sun)) < 0)
+ die("Cannot bind to %s: %m", socket_path);
+
+ if (listen(sk, 64) < 0)
+ die("listen(): %m");
+
+ int one;
+ if (setsockopt(sk, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
+ die("setsockopt(SO_PASSCRED): %m");
+
+ listen_socket.fd = sk;
+ listen_socket.read_handler = listen_read_handler;
+ file_add(&listen_socket);
+
+ msg(L_INFO, "Listening on %s", socket_path);
+}
+
+static struct cf_section daemon_config = {
+ CF_ITEMS {
+ CF_STRING("SocketPath", &socket_path),
+ CF_UINT("MaxConnections", &max_connections),
+ CF_END
+ }
+};
+
+static const struct opt_section options = {
+ OPT_ITEMS {
+ OPT_HELP("A sub-authentication daemon."),
+ OPT_HELP("Usage: subauthd [options]"),
+ OPT_HELP(""),
+ OPT_HELP("Options:"),
+ OPT_HELP_OPTION,
+ OPT_CONF_OPTIONS,
+ OPT_END
+ }
+};
+
+int main(int argc UNUSED, char **argv)
+{
+ cf_def_file = CONFIG_DIR "/subauthd";
+ cf_declare_section("SubauthD", &daemon_config, 0);
+ opt_parse(&options, argv+1);
+
+ main_init();
+ init_socket();
+
+ main_loop();
+ return 0;
+}
--- /dev/null
+/*
+ * Sub-authentication Daemon
+ *
+ * (c) 2017 Martin Mares <mj@ucw.cz>
+ */
+
+#include "autoconf.h"
+
+#include <ucw/mainloop.h>
+#include <ucw-json/json.h>
+
+#define SOCKET_TIMEOUT 60000 // in ms
+#define MAX_PACKET_SIZE 16384
+#define MAX_OOB_DATA_SIZE 4096
+
+struct client {
+ struct main_file socket;
+ struct main_timer timer;
+ int uid;
+ struct json_context *json;
+ struct json_node *request;
+ struct json_node *reply;
+};
+
+/* cmd.c */
+
+void cmd_error(struct client *c, const char *err);
+++ /dev/null
-/*
- * Sub-authentication Client
- *
- * (c) 2017 Martin Mares <mj@ucw.cz>
- */
-
-#include <ucw/lib.h>
-#include <ucw/opt.h>
-#include <ucw-json/json.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include "autoconf.h"
-
-static char *socket_path = INSTALL_RUN_DIR "/subauthd.socket";
-
-static const struct opt_section options = {
- OPT_ITEMS {
- OPT_HELP("A client to the sub-authentication daemon."),
- OPT_HELP("Usage: subauth [options]"),
- OPT_HELP(""),
- OPT_HELP("Options:"),
- OPT_HELP_OPTION,
- OPT_END
- }
-};
-
-int main(int argc UNUSED, char **argv)
-{
- opt_parse(&options, argv+1);
-
- int sk = socket(PF_UNIX, SOCK_SEQPACKET, 0);
- if (sk < 0)
- die("socket(PF_UNIX, SOCK_SEQPACKET): %m");
-
- struct sockaddr_un sun;
- sun.sun_family = AF_UNIX;
- if (strlen(socket_path) >= sizeof(sun.sun_path))
- die("Socket path too long");
- strcpy(sun.sun_path, socket_path);
-
- if (connect(sk, (struct sockaddr *) &sun, sizeof(sun)) < 0)
- die("Cannot connect to %s: %m", socket_path);
-
- struct fastbuf *out = bfdopen(1, 4096);
-
- struct json_context *js = json_new();
- struct json_node *rq = json_new_object(js);
-
- bprintf(out, ">>> Request:\n");
- json_write(js, out, rq);
- bflush(out);
-
- struct fastbuf *rq_fb = fbgrow_create(4096);
- json_write(js, rq_fb, rq);
- byte *rq_buf;
- uint rq_len = fbgrow_get_buf(rq_fb, &rq_buf);
- if (send(sk, rq_buf, rq_len, 0) < 0)
- die("Cannot send request: %m");
- bclose(rq_fb);
-
- byte rp_buf[4096]; // FIXME
- int rp_len = recv(sk, rp_buf, sizeof(rp_buf), 0);
- if (rp_len < 0)
- die("Cannot receive reply: %m");
-
- puts("Parsing reply");
- struct fastbuf rp_fb;
- fbbuf_init_read(&rp_fb, rp_buf, rp_len, 0);
- struct json_node *rp = json_parse(js, &rp_fb);
- bprintf(out, "<<< Reply:\n");
- json_write(js, out, rp);
- bflush(out);
-
- return 0;
-}
+++ /dev/null
-/*
- * Sub-authentication Daemon
- *
- * (c) 2017 Martin Mares <mj@ucw.cz>
- */
-
-#include <ucw/lib.h>
-#include <ucw/conf.h>
-#include <ucw/log.h>
-#include <ucw/mainloop.h>
-#include <ucw/opt.h>
-#include <ucw/trans.h>
-#include <ucw-json/json.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include "autoconf.h"
-
-static char *socket_path = "subauthd.socket";
-static uint max_connections = ~0U;
-
-static struct main_file listen_socket;
-static uint num_connections;
-
-#define SOCKET_TIMEOUT 60000 // in ms
-#define MAX_PACKET_SIZE 16384
-#define MAX_OOB_DATA_SIZE 4096
-
-struct client {
- struct main_file socket;
- struct main_timer timer;
- int uid;
- struct json_context *json;
- struct json_node *request;
- struct json_node *reply;
-};
-
-static byte packet_buffer[MAX_PACKET_SIZE];
-static byte oob_data_buffer[MAX_OOB_DATA_SIZE];
-
-static int socket_read_handler(struct main_file *fi);
-static int socket_write_handler(struct main_file *fi);
-
-static void client_close(struct client *c)
-{
- msg(L_INFO, "Closing connection");
- file_del(&c->socket);
- timer_del(&c->timer);
- close(c->socket.fd);
- json_delete(c->json);
- xfree(c);
- num_connections--;
-}
-
-static void cmd_error(struct client *c, const char *err)
-{
- json_object_set(c->reply, "error", json_new_string(c->json, err));
-}
-
-static void socket_timeout_handler(struct main_timer *tm)
-{
- struct client *c = tm->data;
-
- msg(L_INFO, "Client timeout");
-
- client_close(c);
-}
-
-static void try_send_reply(struct client *c)
-{
- struct fastbuf fb;
- fbbuf_init_write(&fb, packet_buffer, MAX_PACKET_SIZE);
-
- TRANS_TRY
- {
- json_write(c->json, &fb, c->reply);
- }
- TRANS_CATCH(x)
- {
- msg(L_ERROR, "Unable to construct reply, it is probably too long");
- fbbuf_init_write(&fb, packet_buffer, MAX_PACKET_SIZE);
- bputs(&fb, "{ \"error\": \"Reply too long\" }\n");
- }
- TRANS_END;
-
- int len = fbbuf_count_written(&fb);
- msg(L_INFO, "Sending reply of %d bytes", len);
- if (send(c->socket.fd, packet_buffer, len, 0) < 0)
- {
- if (errno == EAGAIN || errno == EINTR)
- {
- msg(L_INFO, "Postponed send");
- c->socket.write_handler = socket_write_handler;
- file_chg(&c->socket);
- }
- msg(L_ERROR, "Client write error: %m");
- client_close(c);
- }
- else
- {
- msg(L_INFO, "Reply sent");
- c->socket.read_handler = socket_read_handler;
- c->socket.write_handler = NULL;
- file_chg(&c->socket);
- timer_add_rel(&c->timer, SOCKET_TIMEOUT);
- }
-}
-
-static void send_reply(struct client *c)
-{
- timer_add_rel(&c->timer, SOCKET_TIMEOUT);
- try_send_reply(c);
-}
-
-static void received_packet(struct client *c, byte *pkt, int len)
-{
- json_reset(c->json);
-
- struct fastbuf fb;
- fbbuf_init_read(&fb, pkt, len, 0);
-
- c->reply = json_new_object(c->json);
-
- TRANS_TRY
- {
- c->request = json_parse(c->json, &fb);
- }
- TRANS_CATCH(x)
- {
- cmd_error(c, "Parse error");
- send_reply(c);
- return;
- }
- TRANS_END;
-
- cmd_error(c, "OK");
- send_reply(c);
-}
-
-static int socket_write_handler(struct main_file *fi)
-{
- struct client *c = fi->data;
- try_send_reply(c);
- return HOOK_IDLE;
-}
-
-static int socket_read_handler(struct main_file *fi)
-{
- struct client *c = fi->data;
-
- struct iovec iov = {
- .iov_base = packet_buffer,
- .iov_len = MAX_PACKET_SIZE,
- };
-
- struct msghdr mh = {
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = oob_data_buffer,
- .msg_controllen = MAX_OOB_DATA_SIZE,
- };
-
- ssize_t len = recvmsg(fi->fd, &mh, 0);
- if (len < 0)
- {
- if (errno != EAGAIN && errno != EINTR)
- msg(L_ERROR, "Socket read: %m");
- return HOOK_IDLE;
- }
-
- if (!len)
- {
- client_close(c);
- return HOOK_IDLE;
- }
-
- struct ucred *cred = NULL;
- for (struct cmsghdr *cm = CMSG_FIRSTHDR(&mh); cm; cm = CMSG_NXTHDR(&mh, cm))
- {
- if (cm->cmsg_level == SOL_SOCKET)
- {
- if (cm->cmsg_type == SCM_RIGHTS)
- {
- // We are not interested in receiving file descriptor, but despite
- // that they could be attached to the message. If it happens, simply
- // close them.
- int *fdptr = (int *) CMSG_DATA(cm);
- int nfd = cm->cmsg_len / sizeof(int);
- for (int i=0; i<nfd; i++)
- close(fdptr[i]);
- }
- else if (cm->cmsg_type == SCM_CREDENTIALS)
- {
- ASSERT(cm->cmsg_len >= sizeof(cred));
- cred = (struct ucred *) CMSG_DATA(cm);
- }
- }
- }
-
- if (!cred)
- {
- msg(L_ERROR, "Dropping message with no credentials");
- return HOOK_RETRY;
- }
-
- msg(L_INFO, "Got message from UID %d", (int) cred->uid);
- c->uid = cred->uid;
-
- fi->read_handler = NULL;
- file_chg(fi);
-
- received_packet(c, packet_buffer, len);
- return HOOK_RETRY;
-}
-
-static int listen_read_handler(struct main_file *fi)
-{
- struct sockaddr_un client;
- socklen_t addr_len = sizeof(client);
-
- int new_sk = accept(fi->fd, &client, &addr_len);
- if (new_sk < 0)
- {
- if (errno != EAGAIN && errno != EINTR)
- msg(L_ERROR, "Socket accept: %m");
- return HOOK_IDLE;
- }
-
- if (num_connections >= max_connections)
- {
- msg(L_WARN, "Too many connections (you might need to increase MaxConnections)");
- close(new_sk);
- return HOOK_IDLE;
- }
- num_connections++;
-
- msg(L_INFO, "Accepted connection");
-
- if (fcntl(new_sk, F_SETFL, fcntl(new_sk, F_GETFL) | O_NONBLOCK) < 0)
- die("Cannot set O_NONBLOCK: %m");
-
- struct client *c = xmalloc_zero(sizeof(*c));
- c->json = json_new();
-
- c->socket.fd = new_sk;
- c->socket.read_handler = socket_read_handler;
- c->socket.data = c;
- file_add(&c->socket);
-
- c->timer.handler = socket_timeout_handler;
- c->timer.data = c;
- timer_add_rel(&c->timer, SOCKET_TIMEOUT);
-
- return HOOK_RETRY;
-}
-
-static void init_socket(void)
-{
- int sk = socket(PF_UNIX, SOCK_SEQPACKET, 0);
- if (sk < 0)
- die("socket(PF_UNIX, SOCK_SEQPACKET): %m");
-
- if (fcntl(sk, F_SETFL, fcntl(sk, F_GETFL) | O_NONBLOCK) < 0)
- die("Cannot set O_NONBLOCK: %m");
-
- struct sockaddr_un sun;
- sun.sun_family = AF_UNIX;
- if (strlen(socket_path) >= sizeof(sun.sun_path))
- die("SocketPath too long");
- strcpy(sun.sun_path, socket_path);
-
- if (unlink(socket_path) < 0 && errno != ENOENT)
- die("Cannot unlink old socket %s: %m", socket_path);
-
- if (bind(sk, (struct sockaddr *) &sun, sizeof(sun)) < 0)
- die("Cannot bind to %s: %m", socket_path);
-
- if (listen(sk, 64) < 0)
- die("listen(): %m");
-
- int one;
- if (setsockopt(sk, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
- die("setsockopt(SO_PASSCRED): %m");
-
- listen_socket.fd = sk;
- listen_socket.read_handler = listen_read_handler;
- file_add(&listen_socket);
-
- msg(L_INFO, "Listening on %s", socket_path);
-}
-
-static struct cf_section daemon_config = {
- CF_ITEMS {
- CF_STRING("SocketPath", &socket_path),
- CF_UINT("MaxConnections", &max_connections),
- CF_END
- }
-};
-
-static const struct opt_section options = {
- OPT_ITEMS {
- OPT_HELP("A sub-authentication daemon."),
- OPT_HELP("Usage: subauthd [options]"),
- OPT_HELP(""),
- OPT_HELP("Options:"),
- OPT_HELP_OPTION,
- OPT_CONF_OPTIONS,
- OPT_END
- }
-};
-
-int main(int argc UNUSED, char **argv)
-{
- cf_def_file = CONFIG_DIR "/subauthd";
- cf_declare_section("SubauthD", &daemon_config, 0);
- opt_parse(&options, argv+1);
-
- main_init();
- init_socket();
-
- main_loop();
- return 0;
-}