preparations for user list in memory
[paraslash.git] / server.c
index 9688c6c..2b59714 100644 (file)
--- a/server.c
+++ b/server.c
@@ -42,6 +42,7 @@
 #include "string.h"
 #include "ipc.h"
 #include "fd.h"
+#include "crypt.h"
 
 /** define the array of error lists needed by para_server */
 INIT_SERVER_ERRLISTS;
@@ -58,6 +59,7 @@ struct misc_meta_data *mmd;
 */
 struct server_args_info conf;
 char *user_list = NULL;
+struct list_head _user_list;
 extern void dccp_send_init(struct sender *);
 extern void http_send_init(struct sender *);
 extern void ortp_send_init(struct sender *);
@@ -274,6 +276,102 @@ static void setup_signal_handling(void)
        }
 }
 
+/*
+ * lookup user in user_list file. Fills in a user struct containing
+ * filename of the user's public key as well as the permissions of that user.
+ * Returns 1 on success, 0 if user does not exist and < 0 on errors.
+ */
+static void populate_user_list(void) {
+       FILE *file_ptr = NULL;
+       char *char_ptr;
+       char line[MAXLINE];
+       /* keyword, user, key, perms */
+       char w[MAXLINE], n[MAXLINE], k[MAXLINE], p[MAXLINE], tmp[4][MAXLINE];
+       int num, ret;
+
+       file_ptr = fopen(user_list, "r");
+       ret = -E_USERLIST;
+       if (!file_ptr)
+               goto out;
+       for (;;) {
+               struct _user *u;
+               ret = para_fgets(line, MAXLINE, file_ptr);
+               if (ret < 0)
+                       PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+               if (ret <= 0)
+                       break;
+               if (sscanf(line,"%200s %200s %200s %200s", w, n, k, p) < 3)
+                       continue;
+               if (strcmp(w, "user"))
+                       continue;
+               PARA_DEBUG_LOG("found entry for %s\n", n);
+               u = para_malloc(sizeof(struct _user));
+               u->name = para_strdup(n);
+               u->rsa = para_malloc(sizeof(RSA));
+               ret = get_rsa_key(k, &u->rsa, 0 /* public */);
+               if (ret < 0)
+                       break;
+               u->perms = 0;
+               char_ptr = p;
+               num = sscanf(char_ptr, "%200[A-Z_],%200[A-Z_],%200[A-Z_],%200[A-Z_]",
+                       tmp[0], tmp[1], tmp[2], tmp[3]);
+               PARA_DEBUG_LOG("found %i perm entries\n", num);
+               u->perms = 0;
+               while (num > 0) {
+                       num--;
+                       if (!strcmp(tmp[num], "AFS_READ"))
+                               u->perms |= AFS_READ;
+                       else if (!strcmp(tmp[num], "AFS_WRITE"))
+                               u->perms |= AFS_WRITE;
+                       else if (!strcmp(tmp[num], "DB_READ"))
+                               u->perms |= DB_READ;
+                       else if (!strcmp(tmp[num], "DB_WRITE"))
+                               u->perms |= DB_WRITE;
+                       else /* unknown permission */
+                               PARA_WARNING_LOG("unknown permission: %s\n",
+                                       tmp[num]);
+               }
+               para_list_add(&u->node, &_user_list);
+       }
+out:
+       if (file_ptr)
+               fclose(file_ptr);
+       if (ret >= 0)
+               return;
+       PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+       exit(EXIT_FAILURE);
+}
+
+static void init_user_list(void)
+{
+       struct _user *u, *tmp;
+       static int initialized;
+
+       if (initialized) {
+               list_for_each_entry_safe(u, tmp, &_user_list, node) {
+                       list_del(&u->node);
+                       free(u->name);
+                       free(u->rsa);
+                       free(u);
+               }
+       } else
+               INIT_LIST_HEAD(&_user_list);
+       initialized = 1;
+       populate_user_list();
+}
+
+int _get_user(struct _user *user)
+{
+       struct _user *u;
+       list_for_each_entry(u, &_user_list, node) {
+               if (strcmp(u->name, user->name))
+                       continue;
+               *user = *u;
+               return 1;
+       }
+       return 0;
+}
+
 static void init_selector(void)
 {
        int i, ret;
@@ -353,6 +451,7 @@ static unsigned do_inits(int argc, char **argv)
        log_welcome("para_server", conf.loglevel_arg);
        shm_init(); /* init mmd struct */
        server_uptime(UPTIME_SET); /* reset server uptime */
+       init_user_list();
        /* become daemon */
        if (conf.daemon_given)
                daemon_init();