* (c) 2017 Martin Mares <mj@ucw.cz>
*/
+#undef LOCAL_DEBUG
+
#include <ucw/lib.h>
#include <ucw/conf.h>
#include <ucw/log.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
#include "subauthd.h"
+// Configuration
static char *socket_path = "subauthd.socket";
static uint max_connections = ~0U;
+clist zone_list;
+char *database_name = "subauthd.db";
+char *temp_key_file;
static struct main_file listen_socket;
static uint num_connections;
static void client_close(struct client *c)
{
- msg(L_INFO, "Closing connection");
+ DBG("Closing connection");
file_del(&c->socket);
timer_del(&c->timer);
close(c->socket.fd);
json_delete(c->json);
- xfree(c);
+ mp_delete(c->pool); // This includes the connection structure
num_connections--;
}
TRANS_END;
int len = fbbuf_count_written(&fb);
- msg(L_INFO, "Sending reply of %d bytes", len);
+ DBG("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");
+ DBG("Postponed send");
c->socket.write_handler = socket_write_handler;
file_chg(&c->socket);
}
}
else
{
- msg(L_INFO, "Reply sent");
+ DBG("Reply sent");
c->socket.read_handler = socket_read_handler;
c->socket.write_handler = NULL;
file_chg(&c->socket);
}
TRANS_CATCH(x)
{
- cmd_error(c, "Parse error");
+ json_object_set(c->reply, "error", json_new_string_ref(c->json, "Parse error"));
send_reply(c);
return;
}
TRANS_END;
- cmd_error(c, "OK");
+ cmd_dispatch(c);
send_reply(c);
}
return HOOK_RETRY;
}
- msg(L_INFO, "Got message from UID %d", (int) cred->uid);
+ DBG("Got message from UID %d", (int) cred->uid);
c->uid = cred->uid;
fi->read_handler = NULL;
}
num_connections++;
- msg(L_INFO, "Accepted connection");
+ DBG("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));
+ struct mempool *mp = mp_new(4096);
+ struct client *c = mp_alloc_zero(mp, sizeof(*c));
+ c->pool = mp;
c->json = json_new();
c->socket.fd = new_sk;
if (listen(sk, 64) < 0)
die("listen(): %m");
- int one;
+ int one = 1;
if (setsockopt(sk, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
die("setsockopt(SO_PASSCRED): %m");
listen_socket.read_handler = listen_read_handler;
file_add(&listen_socket);
+ if (chmod(socket_path, 0666) < 0)
+ die("Cannot chmod socket: %m");
+
msg(L_INFO, "Listening on %s", socket_path);
}
+static char *zone_commit(void *z_)
+{
+ struct auth_zone *z = z_;
+ if (!z->name)
+ return "A zone must have a name";
+ return NULL;
+}
+
+static struct cf_section zone_config = {
+ CF_TYPE(struct auth_zone),
+ CF_COMMIT(zone_commit),
+ CF_ITEMS {
+ CF_STRING("Name", PTR_TO(struct auth_zone, name)),
+ CF_STRING("Description", PTR_TO(struct auth_zone, desc)),
+ CF_UINT("AutoCreateAcct", PTR_TO(struct auth_zone, auto_create_acct)),
+ CF_UINT("AllowPasswd", PTR_TO(struct auth_zone, allow_passwd)),
+ CF_UINT("AllowTokens", PTR_TO(struct auth_zone, allow_tokens)),
+ CF_UINT("MaxTempValidity", PTR_TO(struct auth_zone, max_temp_validity)),
+ CF_END
+ }
+};
+
static struct cf_section daemon_config = {
CF_ITEMS {
CF_STRING("SocketPath", &socket_path),
CF_UINT("MaxConnections", &max_connections),
+ CF_LIST("Zone", &zone_list, &zone_config),
+ CF_STRING("Database", &database_name),
+ CF_STRING("TempKeyFile", &temp_key_file),
CF_END
}
};
int main(int argc UNUSED, char **argv)
{
+ umask(0077);
+
cf_def_file = CONFIG_DIR "/subauthd";
cf_declare_section("SubauthD", &daemon_config, 0);
opt_parse(&options, argv+1);
+ auth_init();
+ temp_init();
main_init();
init_socket();