audiod: Move UID check from audiod_command.c to audiod.c.
authorAndre Noll <maan@tuebingen.mpg.de>
Mon, 20 Jun 2016 21:20:59 +0000 (23:20 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 7 Aug 2016 12:03:44 +0000 (14:03 +0200)
check_perms() is the only reason for the gengetopt config pointer
being public and for passing the whitelist pointer to handle_connect()
in audiod_command.c. The code get less convoluted by moving the
permission check to audiod.c where both the conf pointer and the
uid_whitelist are defined.

This introduces the new public function uid_is_whitelisted() in
audiod.c which replaces check_perms(). This allows to

* pass only the UID to the check function,
* drop the whitelist pointer argument from handle_connect(),
* make the conf pointer in audiod.c static.

The patch also reorders the function declarations in audiod.h a bit
to separate the functions defined in audiod.c from those defined
in audiod_command.c.

audiod.c
audiod.h
audiod_command.c

index 2f9d5da..75073ec 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -164,7 +164,7 @@ int audiod_status = AUDIOD_ON;
  * the gengetopt args_info struct that holds information on all command line
  * arguments
  */
-struct audiod_args_info conf;
+static struct audiod_args_info conf;
 
 static char *socket_name;
 static struct audio_format_info afi[NUM_AUDIO_FORMATS];
@@ -1123,7 +1123,7 @@ static int command_post_select(struct sched *s, void *context)
        for (i = 0; i < 2; i++) {
                if (ct->fd[i] < 0)
                        continue;
-               ret = handle_connect(ct->fd[i], &s->rfds, uid_whitelist);
+               ret = handle_connect(ct->fd[i], &s->rfds);
                if (ret < 0) {
                        PARA_ERROR_LOG("%s\n", para_strerror(-ret));
                        if (ret == -E_AUDIOD_TERM) {
@@ -1448,6 +1448,29 @@ __noreturn static void print_help_and_die(void)
        exit(0);
 }
 
+/**
+ * Lookup the given UID in the whitelist.
+ *
+ * The whitelist is the array of arguments to the --user-allow opion. If the
+ * option was not given, the array is empty, in which case the check succeeds.
+ *
+ * \param uid User ID to look up.
+ *
+ * \return True if --user-allow was not given, or if uid matches an element of
+ * the whitelist.
+ */
+bool uid_is_whitelisted(uid_t uid)
+{
+       int i;
+
+       if (!conf.user_allow_given)
+               return true;
+       for (i = 0; i < conf.user_allow_given; i++)
+               if (uid == uid_whitelist[i])
+                       return true;
+       return false;
+}
+
 /**
  * the main function of para_audiod
  *
index b9cfb25..7073c6d 100644 (file)
--- a/audiod.h
+++ b/audiod.h
@@ -22,15 +22,17 @@ extern const char *audio_formats[];
  */
 enum audiod_status_info {AUDIOD_OFF, AUDIOD_ON, AUDIOD_STANDBY};
 
-extern struct audiod_args_info conf;
 extern int audiod_status;
 
-int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist);
-void audiod_status_dump(bool force);
+/* defined in audiod.c */
+struct btr_node *audiod_get_btr_root(void);
 __malloc char *audiod_get_decoder_flags(void);
+void clear_and_dump_items(void);
 char *get_time_string(void);
-struct btr_node *audiod_get_btr_root(void);
+bool uid_is_whitelisted(uid_t uid);
 
-void stat_client_write_item(int item_num);
-void clear_and_dump_items(void);
+/* defined in audiod_command.c */
+void audiod_status_dump(bool force);
 void close_stat_clients(void);
+int handle_connect(int accept_fd, fd_set *rfds);
+void stat_client_write_item(int item_num);
index 278e6ef..3a39027 100644 (file)
@@ -404,24 +404,11 @@ static int com_version(int fd, int argc, char **argv)
        return ret < 0? ret : 0;
 }
 
-static int check_perms(uid_t uid, uid_t *whitelist)
-{
-       int i;
-
-       if (!conf.user_allow_given)
-               return 1;
-       for (i = 0; i < conf.user_allow_given; i++)
-               if (uid == whitelist[i])
-                       return 1;
-       return -E_UCRED_PERM;
-}
-
 /**
  * Handle arriving connections on the local socket.
  *
  * \param accept_fd The fd to accept connections on.
  * \param rfds If \a accept_fd is not set in \a rfds, do nothing.
- * \param uid_whitelist Array of UIDs which are allowed to connect.
  *
  * This is called in each iteration of the select loop. If there is an incoming
  * connection on \a accept_fd, this function reads the command sent by the peer,
@@ -434,7 +421,7 @@ static int check_perms(uid_t uid, uid_t *whitelist)
  *
  * \sa para_accept(), recv_cred_buffer()
  * */
-int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist)
+int handle_connect(int accept_fd, fd_set *rfds)
 {
        int i, argc, ret, clifd;
        char buf[MAXLINE], **argv = NULL;
@@ -448,9 +435,9 @@ int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist)
        if (ret < 0)
                goto out;
        uid = ret;
-       PARA_INFO_LOG("connection from user %i, buf: %s\n", ret, buf);
-       ret = check_perms(uid, uid_whitelist);
-       if (ret < 0)
+       PARA_INFO_LOG("connection from UID %d, buf: %s\n", ret, buf);
+       ret = -E_UCRED_PERM;
+       if (!uid_is_whitelisted(uid))
                goto out;
        ret = create_argv(buf, "\n", &argv);
        if (ret <= 0)