Add copyright notices to all relevant files. (based on svn log)
[profile/ivi/pulseaudio.git] / src / daemon / caps.c
1 /* $Id$ */
2
3 /***
4   This file is part of PulseAudio.
5
6   Copyright 2004-2006 Lennart Poettering
7   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
8
9   PulseAudio is free software; you can redistribute it and/or modify
10   it under the terms of the GNU Lesser General Public License as published
11   by the Free Software Foundation; either version 2 of the License,
12   or (at your option) any later version.
13
14   PulseAudio is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with PulseAudio; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22   USA.
23 ***/
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <assert.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <sys/types.h>
34
35 #ifdef HAVE_SYS_CAPABILITY_H
36 #include <sys/capability.h>
37 #endif
38
39 #include <pulsecore/core-error.h>
40
41 #include <pulsecore/log.h>
42
43 #include "caps.h"
44
45 /* Glibc <= 2.2 has broken unistd.h */
46 #if defined(linux) && (__GLIBC__ <= 2 && __GLIBC_MINOR__ <= 2)
47 int setresgid(gid_t r, gid_t e, gid_t s);
48 int setresuid(uid_t r, uid_t e, uid_t s);
49 #endif
50
51 #ifdef HAVE_GETUID
52
53 /* Drop root rights when called SUID root */
54 void pa_drop_root(void) {
55     uid_t uid = getuid();
56
57     if (uid == 0 || geteuid() != 0)
58         return;
59
60     pa_log_info("dropping root rights.");
61
62 #if defined(HAVE_SETRESUID)
63     setresuid(uid, uid, uid);
64 #elif defined(HAVE_SETREUID)
65     setreuid(uid, uid);
66 #else
67     setuid(uid);
68     seteuid(uid);
69 #endif
70 }
71
72 #else
73
74 void pa_drop_root(void) {
75 }
76
77 #endif
78
79 #ifdef HAVE_SYS_CAPABILITY_H
80
81 /* Limit capabilities set to CAPSYS_NICE */
82 int pa_limit_caps(void) {
83     int r = -1;
84     cap_t caps;
85     cap_value_t nice_cap = CAP_SYS_NICE;
86
87     /* Only drop caps when called SUID */
88     if (getuid() == 0)
89         return 0;
90
91     caps = cap_init();
92     assert(caps);
93
94     cap_clear(caps);
95
96     cap_set_flag(caps, CAP_EFFECTIVE, 1, &nice_cap, CAP_SET);
97     cap_set_flag(caps, CAP_PERMITTED, 1, &nice_cap, CAP_SET);
98
99     if (cap_set_proc(caps) < 0)
100         goto fail;
101
102     pa_log_info("dropped capabilities successfully.");
103
104     r = 0;
105
106 fail:
107     cap_free (caps);
108
109     return r;
110 }
111
112 /* Drop all capabilities, effectively becoming a normal user */
113 int pa_drop_caps(void) {
114     cap_t caps;
115     int r = -1;
116
117     /* Only drop caps when called SUID */
118     if (getuid() == 0)
119         return 0;
120
121     caps = cap_init();
122     assert(caps);
123
124     cap_clear(caps);
125
126     if (cap_set_proc(caps) < 0) {
127         pa_log("failed to drop capabilities: %s", pa_cstrerror(errno));
128         goto fail;
129     }
130
131     r = 0;
132
133 fail:
134     cap_free (caps);
135
136     return r;
137 }
138
139 #else
140
141 /* NOOPs in case capabilities are not available. */
142 int pa_limit_caps(void) {
143     return 0;
144 }
145
146 int pa_drop_caps(void) {
147     pa_drop_root();
148     return 0;
149 }
150
151 #endif
152