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, ¶ms, bindings, root, sconf, stream, mode); + err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, ¶ms, bindings, root, sconf, stream, mode); if (err < 0) snd_config_delete(sconf); return err;