summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/daemon/daemon-conf.c4
-rw-r--r--src/daemon/main.c3
-rw-r--r--src/modules/module-jack-sink.c6
-rw-r--r--src/modules/module-jack-source.c6
-rw-r--r--src/modules/module-match.c2
-rw-r--r--src/modules/module-protocol-stub.c19
-rw-r--r--src/modules/module-tunnel.c2
-rw-r--r--src/modules/module-volume-restore.c2
-rw-r--r--src/pulse/client-conf.c2
-rw-r--r--src/pulse/context.c22
-rw-r--r--src/pulsecore/core-util.c61
-rw-r--r--src/pulsecore/core-util.h1
-rw-r--r--src/pulsecore/creds.h44
-rw-r--r--src/pulsecore/iochannel.c44
-rw-r--r--src/pulsecore/iochannel.h9
-rw-r--r--src/pulsecore/pdispatch.c6
-rw-r--r--src/pulsecore/pdispatch.h9
-rw-r--r--src/pulsecore/protocol-native.c55
-rw-r--r--src/pulsecore/pstream-util.c2
-rw-r--r--src/pulsecore/pstream-util.h5
-rw-r--r--src/pulsecore/pstream.c27
-rw-r--r--src/pulsecore/pstream.h8
-rw-r--r--src/pulsecore/socket-server.c9
-rw-r--r--todo6
24 files changed, 221 insertions, 133 deletions
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index a5a62567..2577578c 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -46,9 +46,9 @@
#endif
#define DEFAULT_SCRIPT_FILE PA_DEFAULT_CONFIG_DIR PATH_SEP "default.pa"
-#define DEFAULT_SCRIPT_FILE_USER ".pulse" PATH_SEP "default.pa"
+#define DEFAULT_SCRIPT_FILE_USER PATH_SEP "default.pa"
#define DEFAULT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PATH_SEP "daemon.conf"
-#define DEFAULT_CONFIG_FILE_USER ".pulse" PATH_SEP "daemon.conf"
+#define DEFAULT_CONFIG_FILE_USER PATH_SEP "daemon.conf"
#define ENV_SCRIPT_FILE "PULSE_SCRIPT"
#define ENV_CONFIG_FILE "PULSE_CONFIG"
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 4961f0ca..0449cb94 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -229,6 +229,7 @@ static int change_user(void) {
/* Relevant for pa_runtime_path() */
set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH);
+ set_env("PULSE_CONFIG_PATH", PA_SYSTEM_RUNTIME_PATH);
pa_log_info(__FILE__": Successfully dropped root privileges.");
@@ -245,8 +246,6 @@ static int create_runtime_dir(void) {
return -1;
}
- /* Relevant for pa_runtime_path() later on */
- set_env("PULSE_RUNTIME_PATH", fn);
return 0;
}
diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c
index d761c1f7..c645caa9 100644
--- a/src/modules/module-jack-sink.c
+++ b/src/modules/module-jack-sink.c
@@ -242,7 +242,7 @@ int pa__init(pa_core *c, pa_module*m) {
jack_status_t status;
const char *server_name, *client_name;
uint32_t channels = 0;
- int connect = 1;
+ int do_connect = 1;
unsigned i;
const char **ports = NULL, **p;
@@ -256,7 +256,7 @@ int pa__init(pa_core *c, pa_module*m) {
goto fail;
}
- if (pa_modargs_get_value_boolean(ma, "connect", &connect) < 0) {
+ if (pa_modargs_get_value_boolean(ma, "connect", &do_connect) < 0) {
pa_log(__FILE__": failed to parse connect= argument.");
goto fail;
}
@@ -339,7 +339,7 @@ int pa__init(pa_core *c, pa_module*m) {
goto fail;
}
- if (connect) {
+ if (do_connect) {
for (i = 0, p = ports; i < ss.channels; i++, p++) {
if (!*p) {
diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c
index 649a8f98..2a492929 100644
--- a/src/modules/module-jack-source.c
+++ b/src/modules/module-jack-source.c
@@ -240,7 +240,7 @@ int pa__init(pa_core *c, pa_module*m) {
jack_status_t status;
const char *server_name, *client_name;
uint32_t channels = 0;
- int connect = 1;
+ int do_connect = 1;
unsigned i;
const char **ports = NULL, **p;
@@ -254,7 +254,7 @@ int pa__init(pa_core *c, pa_module*m) {
goto fail;
}
- if (pa_modargs_get_value_boolean(ma, "connect", &connect) < 0) {
+ if (pa_modargs_get_value_boolean(ma, "connect", &do_connect) < 0) {
pa_log(__FILE__": failed to parse connect= argument.");
goto fail;
}
@@ -337,7 +337,7 @@ int pa__init(pa_core *c, pa_module*m) {
goto fail;
}
- if (connect) {
+ if (do_connect) {
for (i = 0, p = ports; i < ss.channels; i++, p++) {
if (!*p) {
diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index cd58a838..ab94b02d 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -53,7 +53,7 @@ PA_MODULE_VERSION(PACKAGE_VERSION)
#define WHITESPACE "\n\r \t"
#define DEFAULT_MATCH_TABLE_FILE PA_DEFAULT_CONFIG_DIR"/match.table"
-#define DEFAULT_MATCH_TABLE_FILE_USER ".pulse/match.table"
+#define DEFAULT_MATCH_TABLE_FILE_USER "match.table"
static const char* const valid_modargs[] = {
"table",
diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c
index fa21b737..ecbc5676 100644
--- a/src/modules/module-protocol-stub.c
+++ b/src/modules/module-protocol-stub.c
@@ -52,10 +52,11 @@
#include <pulsecore/modargs.h>
#include <pulsecore/log.h>
#include <pulsecore/native-common.h>
+#include <pulsecore/creds.h>
#ifdef USE_TCP_SOCKETS
#define SOCKET_DESCRIPTION "(TCP sockets)"
-#define SOCKET_USAGE "port=<TCP port number> loopback=<listen on loopback device only?> listen=<address to listen on>"
+#define SOCKET_USAGE "port=<TCP port number> listen=<address to listen on>"
#else
#define SOCKET_DESCRIPTION "(UNIX sockets)"
#define SOCKET_USAGE "socket=<path to UNIX socket>"
@@ -127,9 +128,9 @@
#include "module-native-protocol-unix-symdef.h"
#endif
- #if defined(SCM_CREDENTIALS) && !defined(USE_TCP_SOCKETS)
- #define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-group",
- #define AUTH_USAGE "auth-group=<local group to allow access>"
+ #if defined(HAVE_CREDS) && !defined(USE_TCP_SOCKETS)
+ #define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-group", "auth-group-enable="
+ #define AUTH_USAGE "auth-group=<system group to allow access> auth-group-enable=<enable auth by UNIX group?> "
#else
#define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON
#define AUTH_USAGE
@@ -171,7 +172,6 @@ static const char* const valid_modargs[] = {
MODULE_ARGUMENTS
#if defined(USE_TCP_SOCKETS)
"port",
- "loopback",
"listen",
#else
"socket",
@@ -197,7 +197,6 @@ int pa__init(pa_core *c, pa_module*m) {
#if defined(USE_TCP_SOCKETS)
pa_socket_server *s_ipv4 = NULL, *s_ipv6 = NULL;
- int loopback = 1;
uint32_t port = IPV4_PORT;
const char *listen_on;
#else
@@ -216,11 +215,6 @@ int pa__init(pa_core *c, pa_module*m) {
u = pa_xnew0(struct userdata, 1);
#if defined(USE_TCP_SOCKETS)
- if (pa_modargs_get_value_boolean(ma, "loopback", &loopback) < 0) {
- pa_log(__FILE__": loopback= expects a boolean argument.");
- goto fail;
- }
-
if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port < 1 || port > 0xFFFF) {
pa_log(__FILE__": port= expects a numerical argument between 1 and 65535.");
goto fail;
@@ -231,9 +225,6 @@ int pa__init(pa_core *c, pa_module*m) {
if (listen_on) {
s_ipv6 = pa_socket_server_new_ipv6_string(c->mainloop, listen_on, port, TCPWRAP_SERVICE);
s_ipv4 = pa_socket_server_new_ipv4_string(c->mainloop, listen_on, port, TCPWRAP_SERVICE);
- } else if (loopback) {
- s_ipv6 = pa_socket_server_new_ipv6_loopback(c->mainloop, port, TCPWRAP_SERVICE);
- s_ipv4 = pa_socket_server_new_ipv4_loopback(c->mainloop, port, TCPWRAP_SERVICE);
} else {
s_ipv6 = pa_socket_server_new_ipv6_any(c->mainloop, port, TCPWRAP_SERVICE);
s_ipv4 = pa_socket_server_new_ipv4_any(c->mainloop, port, TCPWRAP_SERVICE);
diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index c018c520..2fb34d12 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -611,7 +611,7 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) {
}
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const struct ucred *creds, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
struct userdata *u = userdata;
assert(p && packet && u);
diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c
index 2f45082b..d0956509 100644
--- a/src/modules/module-volume-restore.c
+++ b/src/modules/module-volume-restore.c
@@ -53,7 +53,7 @@ PA_MODULE_VERSION(PACKAGE_VERSION)
#define WHITESPACE "\n\r \t"
-#define DEFAULT_VOLUME_TABLE_FILE ".pulse/volume.table"
+#define DEFAULT_VOLUME_TABLE_FILE "volume.table"
static const char* const valid_modargs[] = {
"table",
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c
index 28b4f2d1..21917597 100644
--- a/src/pulse/client-conf.c
+++ b/src/pulse/client-conf.c
@@ -46,7 +46,7 @@
#endif
#define DEFAULT_CLIENT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PATH_SEP "client.conf"
-#define DEFAULT_CLIENT_CONFIG_FILE_USER ".pulse" PATH_SEP "client.conf"
+#define DEFAULT_CLIENT_CONFIG_FILE_USER "client.conf"
#define ENV_CLIENT_CONFIG_FILE "PULSE_CLIENTCONFIG"
#define ENV_DEFAULT_SINK "PULSE_SINK"
diff --git a/src/pulse/context.c b/src/pulse/context.c
index f6452d4e..0150204c 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -62,6 +62,7 @@
#include <pulsecore/core-util.h>
#include <pulsecore/log.h>
#include <pulsecore/socket-util.h>
+#include <pulsecore/creds.h>
#include "internal.h"
@@ -272,7 +273,7 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) {
pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
}
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const struct ucred *creds, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
pa_context *c = userdata;
assert(p);
@@ -423,15 +424,17 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION);
pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
{
- struct ucred ucred;
+ pa_creds ucred;
+ gid_t g;
- ucred.pid = getpid();
ucred.uid = getuid();
+ ucred.gid = getgid();
- if ((ucred.gid = pa_get_gid_of_group(c->conf->access_group)) == (gid_t) -1)
- ucred.gid = getgid();
+ if ((g = pa_get_gid_of_group(c->conf->access_group)) != (gid_t) -1)
+ if (pa_check_in_group(g) > 0)
+ ucred.gid = g;
pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
}
@@ -690,7 +693,12 @@ int pa_context_connect(
}
c->server_list = pa_strlist_prepend(c->server_list, "tcp6:localhost");
- c->server_list = pa_strlist_prepend(c->server_list, "localhost");
+ c->server_list = pa_strlist_prepend(c->server_list, "tcp4:localhost");
+
+ /* The system wide instance */
+ c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH "/" PA_NATIVE_DEFAULT_UNIX_SOCKET);
+
+ /* The per-user instance */
c->server_list = pa_strlist_prepend(c->server_list, pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET, ufn, sizeof(ufn)));
/* Wrap the connection attempts in a single transaction for sane autospawn locking */
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 6375e5ef..0e6501b8 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -741,6 +741,20 @@ finish:
return ret;
}
+int pa_check_in_group(gid_t g) {
+ gid_t gids[NGROUPS_MAX];
+ int r;
+
+ if ((r = getgroups(NGROUPS_MAX, gids)) < 0)
+ return -1;
+
+ for (; r > 0; r--)
+ if (gids[r-1] == g)
+ return 1;
+
+ return 0;
+}
+
#else /* HAVE_GRP_H */
int pa_own_uid_in_group(const char *name, gid_t *gid) {
@@ -752,6 +766,14 @@ int pa_uid_in_group(uid_t uid, const char *name) {
return -1;
}
+gid_t pa_get_gid_of_group(const char *name) {
+ return (gid_t) -1;
+}
+
+int pa_check_in_group(gid_t g) {
+ return -1;
+}
+
#endif
/* Lock or unlock a file entirely.
@@ -909,28 +931,33 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
return fopen(fn, mode);
}
- if (local && pa_get_home_dir(h, sizeof(h))) {
- FILE *f;
- char *lfn;
-
- fn = lfn = pa_sprintf_malloc("%s/%s", h, local);
+ if (local) {
+ const char *e;
+ char *lfn = NULL;
+ if ((e = getenv("PULSE_CONFIG_PATH")))
+ fn = lfn = pa_sprintf_malloc("%s/%s", e, local);
+ else if (pa_get_home_dir(h, sizeof(h)))
+ fn = lfn = pa_sprintf_malloc("%s/.pulse/%s", h, local);
+
+ if (lfn) {
+ FILE *f;
+
#ifdef OS_IS_WIN32
- if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX))
- return NULL;
- fn = buf;
+ if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX))
+ return NULL;
+ fn = buf;
#endif
-
- f = fopen(fn, mode);
-
- if (f || errno != ENOENT) {
- if (result)
- *result = pa_xstrdup(fn);
+
+ if ((f = fopen(fn, mode)) || errno != ENOENT) {
+ if (result)
+ *result = pa_xstrdup(fn);
+ pa_xfree(lfn);
+ return f;
+ }
+
pa_xfree(lfn);
- return f;
}
-
- pa_xfree(lfn);
}
if (!global) {
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index db764de1..ba325968 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -67,6 +67,7 @@ const char *pa_strsignal(int sig);
int pa_own_uid_in_group(const char *name, gid_t *gid);
int pa_uid_in_group(uid_t uid, const char *name);
gid_t pa_get_gid_of_group(const char *name);
+int pa_check_in_group(gid_t g);
int pa_lock_fd(int fd, int b);
diff --git a/src/pulsecore/creds.h b/src/pulsecore/creds.h
new file mode 100644
index 00000000..a95f4480
--- /dev/null
+++ b/src/pulsecore/creds.h
@@ -0,0 +1,44 @@
+#ifndef foocredshfoo
+#define foocredshfoo
+
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+typedef struct pa_creds pa_creds;
+
+#if defined(SCM_CREDENTIALS)
+
+#define HAVE_CREDS 1
+
+struct pa_creds {
+ gid_t gid;
+ uid_t uid;
+};
+
+#else
+#undef HAVE_CREDS
+#endif
+
+#endif
diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c
index 852e960e..b50293bf 100644
--- a/src/pulsecore/iochannel.c
+++ b/src/pulsecore/iochannel.c
@@ -231,7 +231,7 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) {
return r;
}
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
int pa_iochannel_creds_supported(pa_iochannel *io) {
struct sockaddr_un sa;
@@ -263,7 +263,7 @@ int pa_iochannel_creds_enable(pa_iochannel *io) {
return 0;
}
-ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const struct ucred *ucred) {
+ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const pa_creds *ucred) {
ssize_t r;
struct msghdr mh;
struct iovec iov;
@@ -288,10 +288,11 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l
u = (struct ucred*) CMSG_DATA(cmsg);
- if (ucred)
- *u = *ucred;
- else {
- u->pid = getpid();
+ u->pid = getpid();
+ if (ucred) {
+ u->uid = ucred->uid;
+ u->gid = ucred->gid;
+ } else {
u->uid = getuid();
u->gid = getgid();
}
@@ -313,7 +314,7 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l
return r;
}
-ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid) {
+ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_creds *creds, int *creds_valid) {
ssize_t r;
struct msghdr mh;
struct iovec iov;
@@ -323,7 +324,7 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struc
assert(data);
assert(l);
assert(io->ifd >= 0);
- assert(ucred);
+ assert(creds);
assert(creds_valid);
memset(&iov, 0, sizeof(iov));
@@ -349,8 +350,12 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struc
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
+ struct ucred u;
assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)));
- memcpy(ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
+ memcpy(&u, CMSG_DATA(cmsg), sizeof(struct ucred));
+
+ creds->gid = u.gid;
+ creds->uid = u.uid;
*creds_valid = 1;
break;
}
@@ -362,27 +367,8 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struc
return r;
}
-#else /* SCM_CREDENTIALS */
-
-int pa_iochannel_creds_supported(pa_iochannel *io) {
- return 0;
-}
-
-int pa_iochannel_creds_enable(pa_iochannel *io) {
- return -1;
-}
-
-ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l) {
- pa_log_error("pa_iochannel_write_with_creds() not supported.");
- return -1;
-}
-
-ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid) {
- pa_log_error("pa_iochannel_read_with_creds() not supported.");
- return -1;
-}
-#endif /* SCM_CREDENTIALS */
+#endif /* HAVE_CREDS */
void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t _callback, void *userdata) {
assert(io);
diff --git a/src/pulsecore/iochannel.h b/src/pulsecore/iochannel.h
index 3b5cba1c..1f9ab0d4 100644
--- a/src/pulsecore/iochannel.h
+++ b/src/pulsecore/iochannel.h
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <pulse/mainloop-api.h>
+#include <pulsecore/creds.h>
/* A wrapper around UNIX file descriptors for attaching them to the a
main event loop. Everytime new data may be read or be written to
@@ -49,13 +50,13 @@ void pa_iochannel_free(pa_iochannel*io);
ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l);
ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l);
+#ifdef HAVE_CREDS
int pa_iochannel_creds_supported(pa_iochannel *io);
int pa_iochannel_creds_enable(pa_iochannel *io);
-struct ucred;
-
-ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const struct ucred *ucred);
-ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid);
+ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const pa_creds *ucred);
+ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_creds *ucred, int *creds_valid);
+#endif
int pa_iochannel_is_readable(pa_iochannel*io);
int pa_iochannel_is_writable(pa_iochannel*io);
diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c
index 9bc20da4..db54b2a3 100644
--- a/src/pulsecore/pdispatch.c
+++ b/src/pulsecore/pdispatch.c
@@ -112,7 +112,7 @@ struct pa_pdispatch {
PA_LLIST_HEAD(struct reply_info, replies);
pa_pdispatch_drain_callback drain_callback;
void *drain_userdata;
- const void *creds;
+ const pa_creds *creds;
};
static void reply_info_free(struct reply_info *r) {
@@ -180,7 +180,7 @@ static void run_action(pa_pdispatch *pd, struct reply_info *r, uint32_t command,
pa_pdispatch_unref(pd);
}
-int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const struct ucred *creds, void *userdata) {
+int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_creds *creds, void *userdata) {
uint32_t tag, command;
pa_tagstruct *ts = NULL;
int ret = -1;
@@ -310,7 +310,7 @@ pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd) {
return pd;
}
-const struct ucred * pa_pdispatch_creds(pa_pdispatch *pd) {
+const pa_creds * pa_pdispatch_creds(pa_pdispatch *pd) {
assert(pd);
assert(pd->ref >= 1);
diff --git a/src/pulsecore/pdispatch.h b/src/pulsecore/pdispatch.h
index 18073502..479eb6b4 100644
--- a/src/pulsecore/pdispatch.h
+++ b/src/pulsecore/pdispatch.h
@@ -23,12 +23,13 @@
***/
#include <inttypes.h>
+
#include <pulse/mainloop-api.h>
#include <pulse/def.h>
+
#include <pulsecore/tagstruct.h>
#include <pulsecore/packet.h>
-
-struct ucred;
+#include <pulsecore/creds.h>
typedef struct pa_pdispatch pa_pdispatch;
@@ -39,7 +40,7 @@ pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *m, const pa_pdispatch_cb_t*table
void pa_pdispatch_unref(pa_pdispatch *pd);
pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd);
-int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, const struct ucred*creds, void *userdata);
+int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, const pa_creds *creds, void *userdata);
void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t callback, void *userdata, pa_free_cb_t free_cb);
@@ -50,6 +51,6 @@ void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, pa_pdispatch_drain_callba
/* Remove all reply slots with the give userdata parameter */
void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata);
-const struct ucred * pa_pdispatch_creds(pa_pdispatch *pd);
+const pa_creds * pa_pdispatch_creds(pa_pdispatch *pd);
#endif
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 14f880d7..2775d774 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -55,6 +55,8 @@
#include <pulsecore/props.h>
#include <pulsecore/sample-util.h>
#include <pulsecore/llist.h>
+#include <pulsecore/creds.h>
+#include <pulsecore/core-util.h>
#include "protocol-native.h"
@@ -134,7 +136,7 @@ struct pa_protocol_native {
pa_idxset *connections;
uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH];
int auth_cookie_in_property;
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
char *auth_group;
#endif
};
@@ -910,25 +912,32 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t
if (!c->authorized) {
int success = 0;
-#ifdef SCM_CREDENTIALS
- const struct ucred *ucred = pa_pdispatch_creds(pd);
+#ifdef HAVE_CREDS
+ const pa_creds *creds;
- if (ucred) {
- if (ucred->uid == getuid())
+ if ((creds = pa_pdispatch_creds(pd))) {
+ if (creds->uid == getuid())
success = 1;
else if (c->protocol->auth_group) {
int r;
-
- if ((r = pa_uid_in_group(ucred->uid, c->protocol->auth_group)) < 0)
- pa_log_warn(__FILE__": failed to check group membership.");
- else if (r > 0)
+ gid_t gid;
+
+ if ((gid = pa_get_gid_of_group(c->protocol->auth_group)) == (gid_t) -1)
+ pa_log_warn(__FILE__": failed to get GID of group '%s'", c->protocol->auth_group);
+ else if (gid == creds->gid)
success = 1;
+
+ if (!success) {
+ if ((r = pa_uid_in_group(creds->uid, c->protocol->auth_group)) < 0)
+ pa_log_warn(__FILE__": failed to check group membership.");
+ else if (r > 0)
+ success = 1;
+ }
}
- pa_log_info(__FILE__": Got credentials: pid=%lu uid=%lu gid=%lu auth=%i",
- (unsigned long) ucred->pid,
- (unsigned long) ucred->uid,
- (unsigned long) ucred->gid,
+ pa_log_info(__FILE__": Got credentials: uid=%lu gid=%lu success=%i",
+ (unsigned long) creds->uid,
+ (unsigned long) creds->gid,
success);
}
#endif
@@ -2100,7 +2109,7 @@ static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC
/*** pstream callbacks ***/
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const struct ucred *creds, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
struct connection *c = userdata;
assert(p && packet && packet->data && c);
@@ -2272,7 +2281,7 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo
pa_idxset_put(p->connections, c, NULL);
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
if (pa_iochannel_creds_supported(io))
pa_iochannel_creds_enable(io);
@@ -2323,8 +2332,18 @@ static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_mo
p->public = public;
p->server = NULL;
-#ifdef SCM_CREDENTIALS
- p->auth_group = pa_xstrdup(pa_modargs_get_value(ma, "auth-group", NULL));
+#ifdef HAVE_CREDS
+ {
+ int a = 1;
+ if (pa_modargs_get_value_boolean(ma, "auth-group-enabled", &a) < 0) {
+ pa_log(__FILE__": auth-group-enabled= expects a boolean argument.");
+ return NULL;
+ }
+ p->auth_group = a ? pa_xstrdup(pa_modargs_get_value(ma, "auth-group", c->is_system_instance ? PA_ACCESS_GROUP : NULL)) : NULL;
+
+ if (p->auth_group)
+ pa_log_info(__FILE__": Allowing access to group '%s'.", p->auth_group);
+ }
#endif
if (load_key(p, pa_modargs_get_value(ma, "cookie", NULL)) < 0) {
@@ -2386,7 +2405,7 @@ void pa_protocol_native_free(pa_protocol_native *p) {
if (p->auth_cookie_in_property)
pa_authkey_prop_unref(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME);
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
pa_xfree(p->auth_group);
#endif
pa_xfree(p);
diff --git a/src/pulsecore/pstream-util.c b/src/pulsecore/pstream-util.c
index 09d6f2fa..d7c1b31b 100644
--- a/src/pulsecore/pstream-util.c
+++ b/src/pulsecore/pstream-util.c
@@ -29,7 +29,7 @@
#include "pstream-util.h"
-void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const struct ucred *creds) {
+void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const pa_creds *creds) {
size_t length;
uint8_t *data;
pa_packet *packet;
diff --git a/src/pulsecore/pstream-util.h b/src/pulsecore/pstream-util.h
index c60000a8..f384d889 100644
--- a/src/pulsecore/pstream-util.h
+++ b/src/pulsecore/pstream-util.h
@@ -25,11 +25,10 @@
#include <inttypes.h>
#include <pulsecore/pstream.h>
#include <pulsecore/tagstruct.h>
-
-struct ucred;
+#include <pulsecore/creds.h>
/* The tagstruct is freed!*/
-void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const struct ucred *creds);
+void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const pa_creds *creds);
#define pa_pstream_send_tagstruct(p, t) pa_pstream_send_tagstruct_with_creds((p), (t), 0)
diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c
index 7ef49305..de5fa43e 100644
--- a/src/pulsecore/pstream.c
+++ b/src/pulsecore/pstream.c
@@ -41,6 +41,7 @@
#include <pulsecore/queue.h>
#include <pulsecore/log.h>
#include <pulsecore/core-scache.h>
+#include <pulsecore/creds.h>
#include "pstream.h"
@@ -69,9 +70,9 @@ struct item_info {
/* packet info */
pa_packet *packet;
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
int with_creds;
- struct ucred creds;
+ pa_creds creds;
#endif
};
@@ -114,8 +115,8 @@ struct pa_pstream {
pa_memblock_stat *memblock_stat;
-#ifdef SCM_CREDENTIALS
- struct ucred read_creds, write_creds;
+#ifdef HAVE_CREDS
+ pa_creds read_creds, write_creds;
int read_creds_valid, send_creds_now;
#endif
};
@@ -216,7 +217,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_memblock_sta
pa_iochannel_socket_set_rcvbuf(io, 1024*8);
pa_iochannel_socket_set_sndbuf(io, 1024*8);
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
p->send_creds_now = 0;
p->read_creds_valid = 0;
#endif
@@ -258,7 +259,7 @@ static void pstream_free(pa_pstream *p) {
pa_xfree(p);
}
-void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const struct ucred *creds) {
+void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *creds) {
struct item_info *i;
assert(p && packet && p->ref >= 1);
@@ -270,7 +271,7 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const struct ucred
i = pa_xnew(struct item_info, 1);
i->type = PA_PSTREAM_ITEM_PACKET;
i->packet = pa_packet_ref(packet);
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
if ((i->with_creds = !!creds))
i->creds = *creds;
#endif
@@ -294,7 +295,7 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa
i->channel = channel;
i->offset = offset;
i->seek_mode = seek_mode;
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
i->with_creds = 0;
#endif
@@ -334,7 +335,7 @@ static void prepare_next_write_item(pa_pstream *p) {
p->write.descriptor[PA_PSTREAM_DESCRIPTOR_SEEK] = htonl(p->write.current->seek_mode);
}
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
if ((p->send_creds_now = p->write.current->with_creds))
p->write_creds = p->write.current->creds;
@@ -364,7 +365,7 @@ static int do_write(pa_pstream *p) {
l = ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE);
}
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
if (p->send_creds_now) {
if ((r = pa_iochannel_write_with_creds(p->io, d, l, &p->write_creds)) < 0)
@@ -406,7 +407,7 @@ static int do_read(pa_pstream *p) {
l = ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE);
}
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
{
int b = 0;
@@ -495,7 +496,7 @@ static int do_read(pa_pstream *p) {
assert(p->read.packet);
if (p->recieve_packet_callback)
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
p->recieve_packet_callback(p, p->read.packet, p->read_creds_valid ? &p->read_creds : NULL, p->recieve_packet_callback_userdata);
#else
p->recieve_packet_callback(p, p->read.packet, NULL, p->recieve_packet_callback_userdata);
@@ -506,7 +507,7 @@ static int do_read(pa_pstream *p) {
}
p->read.index = 0;
-#ifdef SCM_CREDENTIALS
+#ifdef HAVE_CREDS
p->read_creds_valid = 0;
#endif
}
diff --git a/src/pulsecore/pstream.h b/src/pulsecore/pstream.h
index 39cb7591..789e40bc 100644
--- a/src/pulsecore/pstream.h
+++ b/src/pulsecore/pstream.h
@@ -26,16 +26,16 @@
#include <pulse/mainloop-api.h>
#include <pulse/def.h>
+
#include <pulsecore/packet.h>
#include <pulsecore/memblock.h>
#include <pulsecore/iochannel.h>
#include <pulsecore/memchunk.h>
-
-struct ucred;
+#include <pulsecore/creds.h>
typedef struct pa_pstream pa_pstream;
-typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const struct ucred *creds, void *userdata);
+typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata);
typedef void (*pa_pstream_memblock_cb_t)(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata);
typedef void (*pa_pstream_notify_cb_t)(pa_pstream *p, void *userdata);
@@ -43,7 +43,7 @@ pa_pstream* pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_memblock_sta
void pa_pstream_unref(pa_pstream*p);
pa_pstream* pa_pstream_ref(pa_pstream*p);
-void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const struct ucred *creds);
+void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *creds);
void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk);
void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata);
diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c
index 77ea13e7..25483592 100644
--- a/src/pulsecore/socket-server.c
+++ b/src/pulsecore/socket-server.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
+#include <sys/stat.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@@ -185,12 +186,18 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file
sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
pa_socket_low_delay(fd);
-
+
if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) {
pa_log(__FILE__": bind(): %s", pa_cstrerror(errno));
goto fail;
}
+ /* Allow access from all clients. Sockets like this one should
+ * always be put inside a directory with proper access rights,
+ * because not all OS check the access rights on the socket
+ * inodes. */
+ chmod(filename, 0777);
+
if (listen(fd, 5) < 0) {
pa_log(__FILE__": listen(): %s", pa_cstrerror(errno));
goto fail;
diff --git a/todo b/todo
index 07d022b7..0173ccd9 100644
--- a/todo
+++ b/todo
@@ -3,7 +3,6 @@
Post 0.9.0:
- alsa mmap driver
- dbus/hal (Shams King is working on this one)
-- polish for starting polypaudio as root/system-wide instance
- chroot()
- module-tunnel: improve latency calculation
- multiline configuration statements
@@ -32,6 +31,11 @@ Post 0.9.0:
- gconf module + frontend
- hooks for creating sink inputs
- insert the low-level device name in the default sink/source name, to make them recognizable
+- ssl
+- key rings for auth
+- challenge response auth
+- sasl auth
+- setrlimit
Long term:
- pass meta info for hearing impaired