Hi,

today i got some problems with the dmix pcm plugin, i start one
mpg123 as root and later i want to start as normal user alsaplayer
to test something. I got permission denied error, because the socket
is only writable from the user who has created it. I have made a
little patch which implements a new config entry for the socket
permissions. For example:

pcm.softmix {
        type dmix
        ipc_key 1024
        ipc_perm 666
...
}

If you are interested in i could do this for all pcm plugins which
creates a socket, also i could implement another entry like
ipc_group = "audio"; no problem i think with getgrgid(); Another
thing which is changed now; the default file permissions if no
ipc_perm entry in the config file exists, is 0644, i think there
is no need to have 755 for the socket :)

--Maik
diff -Nur alsa-lib-1.0.0rc2/src/pcm/pcm_direct.c 
alsa-lib-1.0.0rc2-dmix-ipc-perm/src/pcm/pcm_direct.c
--- alsa-lib-1.0.0rc2/src/pcm/pcm_direct.c      2003-10-17 15:53:06.000000000 +0200
+++ alsa-lib-1.0.0rc2-dmix-ipc-perm/src/pcm/pcm_direct.c        2003-12-07 
02:58:36.000000000 +0100
@@ -157,7 +157,7 @@
        return 0;
 }
 
-static int make_local_socket(const char *filename, int server)
+static int make_local_socket(const char *filename, int server, mode_t ipc_perm)
 {
        size_t l = strlen(filename);
        size_t size = offsetof(struct sockaddr_un, sun_path) + l;
@@ -181,6 +181,12 @@
                        int result = -errno;
                        SYSERR("bind failed");
                        return result;
+               } else {
+                       if (chmod(filename, ipc_perm) < 0) {
+                               int result = -errno;
+                               SYSERR("chmod failed");
+                               return result;
+                       }
                }
        } else {
                if (connect(sock, (struct sockaddr *) addr, size) < 0) {
@@ -297,7 +303,7 @@
        if (ret < 0)
                return ret;
        
-       ret = make_local_socket(dmix->shmptr->socket_name, 1);
+       ret = make_local_socket(dmix->shmptr->socket_name, 1, dmix->ipc_perm);
        if (ret < 0)
                return ret;
        dmix->server_fd = ret;
@@ -349,7 +355,7 @@
        int ret;
        unsigned char buf;
 
-       ret = make_local_socket(dmix->shmptr->socket_name, 0);
+       ret = make_local_socket(dmix->shmptr->socket_name, 0, dmix->ipc_perm);
        if (ret < 0)
                return ret;
        dmix->comm_fd = ret;
diff -Nur alsa-lib-1.0.0rc2/src/pcm/pcm_direct.h 
alsa-lib-1.0.0rc2-dmix-ipc-perm/src/pcm/pcm_direct.h
--- alsa-lib-1.0.0rc2/src/pcm/pcm_direct.h      2003-09-17 19:09:45.000000000 +0200
+++ alsa-lib-1.0.0rc2-dmix-ipc-perm/src/pcm/pcm_direct.h        2003-12-07 
02:52:52.000000000 +0100
@@ -79,6 +79,7 @@
 struct snd_pcm_direct {
        snd_pcm_type_t type;            /* type (dmix, dsnoop, dshare) */
        key_t ipc_key;                  /* IPC key for semaphore and memory */
+       mode_t ipc_perm;                /* IPC socket permissions */
        int semid;                      /* IPC global semaphore identification */
        int shmid;                      /* IPC global shared memory identification */
        snd_pcm_direct_share_t *shmptr; /* pointer to shared memory area */
diff -Nur alsa-lib-1.0.0rc2/src/pcm/pcm_dmix.c 
alsa-lib-1.0.0rc2-dmix-ipc-perm/src/pcm/pcm_dmix.c
--- alsa-lib-1.0.0rc2/src/pcm/pcm_dmix.c        2003-10-23 16:42:47.000000000 +0200
+++ alsa-lib-1.0.0rc2-dmix-ipc-perm/src/pcm/pcm_dmix.c  2003-12-07 04:58:36.000000000 
+0100
@@ -743,7 +743,8 @@
  *          changed in future.
  */
 int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
-                     key_t ipc_key, struct slave_params *params,
+                     key_t ipc_key, mode_t ipc_perm,
+                     struct slave_params *params,
                      snd_config_t *bindings,
                      snd_config_t *root, snd_config_t *sconf,
                      snd_pcm_stream_t stream, int mode)
@@ -771,6 +772,7 @@
                goto _err;
        
        dmix->ipc_key = ipc_key;
+       dmix->ipc_perm = ipc_perm;
        dmix->semid = -1;
        dmix->shmid = -1;
 
@@ -1056,6 +1058,7 @@
        struct slave_params params;
        int bsize, psize, ipc_key_add_uid = 0;
        key_t ipc_key = 0;
+       mode_t ipc_perm = 0644;
        int err;
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
@@ -1074,6 +1077,21 @@
                        ipc_key = key;
                        continue;
                }
+               if (strcmp(id, "ipc_perm") == 0) {
+                       char *perm;
+                       char *endp;
+                       err = snd_config_get_ascii(n, &perm);
+                       if (err < 0) {
+                               SNDERR("The field ipc_perm must be a valid file 
permission");
+                               return err;
+                       }
+                       if (isdigit(*perm) == 0) {
+                               SNDERR("The field ipc_perm must be a valid file 
permission");
+                               return -EINVAL;
+                       }
+                       ipc_perm = strtol(perm, &endp, 8);
+                       continue;
+               }
                if (strcmp(id, "ipc_key_add_uid") == 0) {
                        char *tmp;
                        err = snd_config_get_ascii(n, &tmp);
@@ -1135,7 +1153,7 @@
        params.period_size = psize;
        params.buffer_size = bsize;
 
-       err = snd_pcm_dmix_open(pcmp, name, ipc_key, &params, bindings, root, sconf, 
stream, mode);
+       err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, 
root, sconf, stream, mode);
        if (err < 0)
                snd_config_delete(sconf);
        return err;

Reply via email to