summaryrefslogtreecommitdiffstats
path: root/src/pulsecore
diff options
context:
space:
mode:
Diffstat (limited to 'src/pulsecore')
-rw-r--r--src/pulsecore/core-util.c86
-rw-r--r--src/pulsecore/core-util.h5
-rw-r--r--src/pulsecore/core.c5
-rw-r--r--src/pulsecore/core.h2
-rw-r--r--src/pulsecore/iochannel.c17
-rw-r--r--src/pulsecore/iochannel.h2
-rw-r--r--src/pulsecore/pdispatch.c4
-rw-r--r--src/pulsecore/pdispatch.h6
-rw-r--r--src/pulsecore/pid.c15
-rw-r--r--src/pulsecore/protocol-native.c2
-rw-r--r--src/pulsecore/pstream-util.c2
-rw-r--r--src/pulsecore/pstream-util.h4
-rw-r--r--src/pulsecore/pstream.c31
-rw-r--r--src/pulsecore/pstream.h6
14 files changed, 123 insertions, 64 deletions
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 7cb85209..6375e5ef 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -84,10 +84,10 @@
#endif
#ifndef OS_IS_WIN32
-#define PA_RUNTIME_PATH_PREFIX "/tmp/pulse-"
+#define PA_USER_RUNTIME_PATH_PREFIX "/tmp/pulse-"
#define PATH_SEP '/'
#else
-#define PA_RUNTIME_PATH_PREFIX "%TEMP%\\pulse-"
+#define PA_USER_RUNTIME_PATH_PREFIX "%TEMP%\\pulse-"
#define PATH_SEP '\\'
#endif
@@ -136,23 +136,32 @@ void pa_make_nonblock_fd(int fd) {
}
/** Creates a directory securely */
-int pa_make_secure_dir(const char* dir) {
+int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
struct stat st;
+ int r;
+
assert(dir);
#ifdef OS_IS_WIN32
- if (mkdir(dir) < 0)
+ r = mkdir(dir);
#else
- if (mkdir(dir, 0700) < 0)
+ {
+ mode_t u;
+ u = umask(~m);
+ r = mkdir(dir, m);
+ umask(u);
+ }
#endif
- if (errno != EEXIST)
- return -1;
+
+ if (r < 0 && errno != EEXIST)
+ return -1;
#ifdef HAVE_CHOWN
- chown(dir, getuid(), getgid());
+ chown(dir, uid, gid);
#endif
+
#ifdef HAVE_CHMOD
- chmod(dir, 0700);
+ chmod(dir, m);
#endif
#ifdef HAVE_LSTAT
@@ -163,8 +172,13 @@ int pa_make_secure_dir(const char* dir) {
goto fail;
#ifndef OS_IS_WIN32
- if (!S_ISDIR(st.st_mode) || (st.st_uid != getuid()) || ((st.st_mode & 0777) != 0700))
+ if (!S_ISDIR(st.st_mode) ||
+ (st.st_uid != uid) ||
+ (st.st_gid != gid) ||
+ ((st.st_mode & 0777) != m)) {
+ errno = EACCES;
goto fail;
+ }
#else
fprintf(stderr, "FIXME: pa_make_secure_dir()\n");
#endif
@@ -180,23 +194,24 @@ fail:
char *pa_parent_dir(const char *fn) {
char *slash, *dir = pa_xstrdup(fn);
- slash = (char*) pa_path_get_filename(dir);
- if (slash == fn)
+ if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
+ pa_xfree(dir);
return NULL;
+ }
*(slash-1) = 0;
return dir;
}
/* Creates a the parent directory of the specified path securely */
-int pa_make_secure_parent_dir(const char *fn) {
+int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {
int ret = -1;
char *dir;
if (!(dir = pa_parent_dir(fn)))
goto finish;
- if (pa_make_secure_dir(dir) < 0)
+ if (pa_make_secure_dir(dir, m, uid, gid) < 0)
goto finish;
ret = 0;
@@ -669,6 +684,7 @@ finish:
return r;
}
+/* Check whether the specifc user id is a member of the specified group */
int pa_uid_in_group(uid_t uid, const char *name) {
char *g_buf, *p_buf;
long g_n, p_n;
@@ -705,6 +721,26 @@ finish:
return r;
}
+/* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
+gid_t pa_get_gid_of_group(const char *name) {
+ gid_t ret = (gid_t) -1;
+ char *g_buf;
+ long g_n;
+ struct group grbuf, *gr;
+
+ g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
+ g_buf = pa_xmalloc(g_n);
+
+ if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
+ goto finish;
+
+ ret = gr->gr_gid;
+
+finish:
+ pa_xfree(g_buf);
+ return ret;
+}
+
#else /* HAVE_GRP_H */
int pa_own_uid_in_group(const char *name, gid_t *gid) {
@@ -1003,7 +1039,7 @@ int pa_endswith(const char *s, const char *sfx) {
* if fn is non-null and starts with / return fn in s
* otherwise append fn to the run time path and return it in s */
char *pa_runtime_path(const char *fn, char *s, size_t l) {
- char u[256];
+ const char *e;
#ifndef OS_IS_WIN32
if (fn && *fn == '/')
@@ -1012,10 +1048,22 @@ char *pa_runtime_path(const char *fn, char *s, size_t l) {
#endif
return pa_strlcpy(s, fn, l);
- if (fn)
- snprintf(s, l, "%s%s%c%s", PA_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PATH_SEP, fn);
- else
- snprintf(s, l, "%s%s", PA_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)));
+ if ((e = getenv("PULSE_RUNTIME_PATH"))) {
+
+ if (fn)
+ snprintf(s, l, "%s%c%s", e, PATH_SEP, fn);
+ else
+ snprintf(s, l, "%s", e);
+
+ } else {
+ char u[256];
+
+ if (fn)
+ snprintf(s, l, "%s%s%c%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PATH_SEP, fn);
+ else
+ snprintf(s, l, "%s%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)));
+ }
+
#ifdef OS_IS_WIN32
{
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index 864a96ec..db764de1 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -33,8 +33,8 @@ struct timeval;
void pa_make_nonblock_fd(int fd);
-int pa_make_secure_dir(const char* dir);
-int pa_make_secure_parent_dir(const char *fn);
+int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid);
+int pa_make_secure_parent_dir(const char *fn, mode_t, uid_t uid, gid_t gid);
ssize_t pa_read(int fd, void *buf, size_t count, int *type);
ssize_t pa_write(int fd, const void *buf, size_t count, int *type);
@@ -66,6 +66,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_lock_fd(int fd, int b);
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index 7c780ea8..d6af3ca9 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -46,7 +46,8 @@
pa_core* pa_core_new(pa_mainloop_api *m) {
pa_core* c;
- c = pa_xmalloc(sizeof(pa_core));
+
+ c = pa_xnew(pa_core, 1);
c->mainloop = m;
c->clients = pa_idxset_new(NULL, NULL);
@@ -88,6 +89,8 @@ pa_core* pa_core_new(pa_mainloop_api *m) {
c->resample_method = PA_RESAMPLER_SRC_SINC_FASTEST;
+ c->is_system_instance = 0;
+
pa_property_init(c);
pa_random(&c->cookie, sizeof(c->cookie));
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 261c5f75..61f17432 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -71,6 +71,8 @@ struct pa_core {
pa_time_event *scache_auto_unload_event;
pa_resample_method_t resample_method;
+
+ int is_system_instance;
};
pa_core* pa_core_new(pa_mainloop_api *m);
diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c
index 15aa8e35..852e960e 100644
--- a/src/pulsecore/iochannel.c
+++ b/src/pulsecore/iochannel.c
@@ -263,12 +263,12 @@ 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) {
+ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const struct ucred *ucred) {
ssize_t r;
struct msghdr mh;
struct iovec iov;
uint8_t cmsg_data[CMSG_SPACE(sizeof(struct ucred))];
- struct ucred *ucred;
+ struct ucred *u;
struct cmsghdr *cmsg;
assert(io);
@@ -286,10 +286,15 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_CREDENTIALS;
- ucred = (struct ucred*) CMSG_DATA(cmsg);
- ucred->pid = getpid();
- ucred->uid = getuid();
- ucred->gid = getgid();
+ u = (struct ucred*) CMSG_DATA(cmsg);
+
+ if (ucred)
+ *u = *ucred;
+ else {
+ u->pid = getpid();
+ u->uid = getuid();
+ u->gid = getgid();
+ }
memset(&mh, 0, sizeof(mh));
mh.msg_name = NULL;
diff --git a/src/pulsecore/iochannel.h b/src/pulsecore/iochannel.h
index 64cf331e..3b5cba1c 100644
--- a/src/pulsecore/iochannel.h
+++ b/src/pulsecore/iochannel.h
@@ -54,7 +54,7 @@ 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);
+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);
int pa_iochannel_is_readable(pa_iochannel*io);
diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c
index 5b76b432..9bc20da4 100644
--- a/src/pulsecore/pdispatch.c
+++ b/src/pulsecore/pdispatch.c
@@ -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 void *creds, void *userdata) {
+int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const struct ucred *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 void * pa_pdispatch_creds(pa_pdispatch *pd) {
+const struct ucred * 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 07620e5a..18073502 100644
--- a/src/pulsecore/pdispatch.h
+++ b/src/pulsecore/pdispatch.h
@@ -28,6 +28,8 @@
#include <pulsecore/tagstruct.h>
#include <pulsecore/packet.h>
+struct ucred;
+
typedef struct pa_pdispatch pa_pdispatch;
typedef void (*pa_pdispatch_cb_t)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
@@ -37,7 +39,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 void*creds, void *userdata);
+int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, const struct ucred*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);
@@ -48,6 +50,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 void * pa_pdispatch_creds(pa_pdispatch *pd);
+const struct ucred * pa_pdispatch_creds(pa_pdispatch *pd);
#endif
diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c
index 0ad76a6e..044d223d 100644
--- a/src/pulsecore/pid.c
+++ b/src/pulsecore/pid.c
@@ -79,13 +79,10 @@ static pid_t read_pid(const char *fn, int fd) {
static int open_pid_file(const char *fn, int mode) {
int fd = -1;
- int lock = -1;
for (;;) {
struct stat st;
- pa_make_secure_parent_dir(fn);
-
if ((fd = open(fn, mode, S_IRUSR|S_IWUSR)) < 0) {
if (mode != O_RDONLY || errno != ENOENT)
pa_log_warn(__FILE__": WARNING: failed to open PID file '%s': %s",
@@ -123,10 +120,8 @@ static int open_pid_file(const char *fn, int mode) {
fail:
- if (fd < 0) {
- if (lock >= 0)
- pa_lock_fd(fd, 0);
-
+ if (fd >= 0) {
+ pa_lock_fd(fd, 0);
close(fd);
}
@@ -199,7 +194,6 @@ int pa_pid_file_remove(void) {
char fn[PATH_MAX];
int ret = -1;
pid_t pid;
- char *p;
pa_runtime_path("pid", fn, sizeof(fn));
@@ -235,11 +229,6 @@ int pa_pid_file_remove(void) {
goto fail;
}
- if ((p = pa_parent_dir(fn))) {
- rmdir(p);
- pa_xfree(p);
- }
-
ret = 0;
fail:
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 784610bd..14f880d7 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -2100,7 +2100,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 void *creds, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const struct ucred *creds, void *userdata) {
struct connection *c = userdata;
assert(p && packet && packet->data && c);
diff --git a/src/pulsecore/pstream-util.c b/src/pulsecore/pstream-util.c
index 3a995324..09d6f2fa 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, int creds) {
+void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const struct ucred *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 fc6d18c0..c60000a8 100644
--- a/src/pulsecore/pstream-util.h
+++ b/src/pulsecore/pstream-util.h
@@ -26,8 +26,10 @@
#include <pulsecore/pstream.h>
#include <pulsecore/tagstruct.h>
+struct ucred;
+
/* The tagstruct is freed!*/
-void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, int creds);
+void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const struct ucred *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 7992ccb6..7ef49305 100644
--- a/src/pulsecore/pstream.c
+++ b/src/pulsecore/pstream.c
@@ -27,6 +27,8 @@
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
@@ -69,6 +71,7 @@ struct item_info {
pa_packet *packet;
#ifdef SCM_CREDENTIALS
int with_creds;
+ struct ucred creds;
#endif
};
@@ -112,9 +115,8 @@ struct pa_pstream {
pa_memblock_stat *memblock_stat;
#ifdef SCM_CREDENTIALS
- int send_creds_now;
- struct ucred ucred;
- int creds_valid;
+ struct ucred read_creds, write_creds;
+ int read_creds_valid, send_creds_now;
#endif
};
@@ -216,7 +218,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_memblock_sta
#ifdef SCM_CREDENTIALS
p->send_creds_now = 0;
- p->creds_valid = 0;
+ p->read_creds_valid = 0;
#endif
return p;
}
@@ -256,7 +258,7 @@ static void pstream_free(pa_pstream *p) {
pa_xfree(p);
}
-void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, int with_creds) {
+void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const struct ucred *creds) {
struct item_info *i;
assert(p && packet && p->ref >= 1);
@@ -269,7 +271,8 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, int with_creds) {
i->type = PA_PSTREAM_ITEM_PACKET;
i->packet = pa_packet_ref(packet);
#ifdef SCM_CREDENTIALS
- i->with_creds = with_creds;
+ if ((i->with_creds = !!creds))
+ i->creds = *creds;
#endif
pa_queue_push(p->send_queue, i);
@@ -332,7 +335,9 @@ static void prepare_next_write_item(pa_pstream *p) {
}
#ifdef SCM_CREDENTIALS
- p->send_creds_now = p->write.current->with_creds;
+ if ((p->send_creds_now = p->write.current->with_creds))
+ p->write_creds = p->write.current->creds;
+
#endif
}
@@ -362,7 +367,7 @@ static int do_write(pa_pstream *p) {
#ifdef SCM_CREDENTIALS
if (p->send_creds_now) {
- if ((r = pa_iochannel_write_with_creds(p->io, d, l)) < 0)
+ if ((r = pa_iochannel_write_with_creds(p->io, d, l, &p->write_creds)) < 0)
return -1;
p->send_creds_now = 0;
@@ -403,12 +408,12 @@ static int do_read(pa_pstream *p) {
#ifdef SCM_CREDENTIALS
{
- int b;
+ int b = 0;
- if ((r = pa_iochannel_read_with_creds(p->io, d, l, &p->ucred, &b)) <= 0)
+ if ((r = pa_iochannel_read_with_creds(p->io, d, l, &p->read_creds, &b)) <= 0)
return -1;
- p->creds_valid = p->creds_valid || b;
+ p->read_creds_valid = p->read_creds_valid || b;
}
#else
if ((r = pa_iochannel_read(p->io, d, l)) <= 0)
@@ -491,7 +496,7 @@ static int do_read(pa_pstream *p) {
if (p->recieve_packet_callback)
#ifdef SCM_CREDENTIALS
- p->recieve_packet_callback(p, p->read.packet, p->creds_valid ? &p->ucred : NULL, p->recieve_packet_callback_userdata);
+ 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);
#endif
@@ -502,7 +507,7 @@ static int do_read(pa_pstream *p) {
p->read.index = 0;
#ifdef SCM_CREDENTIALS
- p->creds_valid = 0;
+ p->read_creds_valid = 0;
#endif
}
}
diff --git a/src/pulsecore/pstream.h b/src/pulsecore/pstream.h
index 1a2932d4..39cb7591 100644
--- a/src/pulsecore/pstream.h
+++ b/src/pulsecore/pstream.h
@@ -31,9 +31,11 @@
#include <pulsecore/iochannel.h>
#include <pulsecore/memchunk.h>
+struct ucred;
+
typedef struct pa_pstream pa_pstream;
-typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const void *creds, void *userdata);
+typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const struct ucred *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);
@@ -41,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, int with_creds);
+void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const struct ucred *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);