smbd: Fix CID 1035536 Uninitialized pointer read
[Samba.git] / lib / uid_wrapper / uid_wrapper.c
blob7a85a9563ad5ceede2eaf7802a01444346368c75
1 /*
2 Copyright (C) Andrew Tridgell 2009
3 Copyright (c) 2011 Andreas Schneider <asn@samba.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifdef _SAMBA_BUILD_
21 #define UID_WRAPPER_NOT_REPLACE
22 #include "replace.h"
23 #include "system/passwd.h"
24 #include <talloc.h>
25 #include "../lib/util/setid.h"
27 #else /* _SAMBA_BUILD_ */
29 #error uid_wrapper_only_supported_in_samba_yet
31 #endif
33 #ifndef _PUBLIC_
34 #define _PUBLIC_
35 #endif
38 we keep the virtualised euid/egid/groups information here
40 static struct {
41 bool initialised;
42 bool enabled;
43 uid_t myuid;
44 uid_t euid;
45 uid_t mygid;
46 gid_t egid;
47 gid_t *groups;
48 } uwrap;
50 static void uwrap_init(void)
52 if (uwrap.initialised) return;
53 uwrap.initialised = true;
54 if (getenv("UID_WRAPPER")) {
55 uwrap.enabled = true;
56 /* put us in one group */
57 uwrap.myuid = uwrap.euid = geteuid();
58 uwrap.mygid = uwrap.egid = getegid();
59 uwrap.groups = talloc_array(NULL, gid_t, 1);
60 uwrap.groups[0] = 0;
64 #undef uwrap_enabled
65 _PUBLIC_ int uwrap_enabled(void)
67 uwrap_init();
68 return uwrap.enabled?1:0;
71 #ifdef HAVE_SETEUID
72 _PUBLIC_ int uwrap_seteuid(uid_t euid)
74 uwrap_init();
75 if (!uwrap.enabled) {
76 return samba_seteuid(euid);
78 /* assume for now that the ruid stays as root */
79 if (euid == 0) {
80 uwrap.euid = uwrap.myuid;
81 } else {
82 uwrap.euid = euid;
84 return 0;
86 #endif
88 #ifdef HAVE_SETREUID
89 _PUBLIC_ int uwrap_setreuid(uid_t ruid, uid_t euid)
91 uwrap_init();
92 if (!uwrap.enabled) {
93 return samba_setreuid(ruid, euid);
95 /* assume for now that the ruid stays as root */
96 if (euid == 0) {
97 uwrap.euid = uwrap.myuid;
98 } else {
99 uwrap.euid = euid;
101 return 0;
103 #endif
105 #ifdef HAVE_SETRESUID
106 _PUBLIC_ int uwrap_setresuid(uid_t ruid, uid_t euid, uid_t suid)
108 uwrap_init();
109 if (!uwrap.enabled) {
110 return samba_setresuid(ruid, euid, suid);
112 /* assume for now that the ruid stays as root */
113 if (euid == 0) {
114 uwrap.euid = uwrap.myuid;
115 } else {
116 uwrap.euid = euid;
118 return 0;
120 #endif
122 _PUBLIC_ uid_t uwrap_geteuid(void)
124 uwrap_init();
125 if (!uwrap.enabled) {
126 return geteuid();
128 return uwrap.euid;
131 #ifdef HAVE_SETEGID
132 _PUBLIC_ int uwrap_setegid(gid_t egid)
134 uwrap_init();
135 if (!uwrap.enabled) {
136 return samba_setegid(egid);
138 /* assume for now that the ruid stays as root */
139 if (egid == 0) {
140 uwrap.egid = uwrap.mygid;
141 } else {
142 uwrap.egid = egid;
144 return 0;
146 #endif
148 #ifdef HAVE_SETREGID
149 _PUBLIC_ int uwrap_setregid(gid_t rgid, gid_t egid)
151 uwrap_init();
152 if (!uwrap.enabled) {
153 return samba_setregid(rgid, egid);
155 /* assume for now that the ruid stays as root */
156 if (egid == 0) {
157 uwrap.egid = uwrap.mygid;
158 } else {
159 uwrap.egid = egid;
161 return 0;
163 #endif
165 #ifdef HAVE_SETRESGID
166 _PUBLIC_ int uwrap_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
168 uwrap_init();
169 if (!uwrap.enabled) {
170 return samba_setresgid(rgid, egid, sgid);
172 /* assume for now that the ruid stays as root */
173 if (egid == 0) {
174 uwrap.egid = uwrap.mygid;
175 } else {
176 uwrap.egid = egid;
178 return 0;
180 #endif
182 _PUBLIC_ uid_t uwrap_getegid(void)
184 uwrap_init();
185 if (!uwrap.enabled) {
186 return getegid();
188 return uwrap.egid;
191 _PUBLIC_ int uwrap_setgroups(size_t size, const gid_t *list)
193 uwrap_init();
194 if (!uwrap.enabled) {
195 return samba_setgroups(size, list);
198 talloc_free(uwrap.groups);
199 uwrap.groups = NULL;
201 if (size != 0) {
202 uwrap.groups = talloc_array(NULL, gid_t, size);
203 if (uwrap.groups == NULL) {
204 errno = ENOMEM;
205 return -1;
207 memcpy(uwrap.groups, list, size*sizeof(gid_t));
209 return 0;
212 _PUBLIC_ int uwrap_getgroups(int size, gid_t *list)
214 size_t ngroups;
216 uwrap_init();
217 if (!uwrap.enabled) {
218 return getgroups(size, list);
221 ngroups = talloc_array_length(uwrap.groups);
223 if (size > ngroups) {
224 size = ngroups;
226 if (size == 0) {
227 return ngroups;
229 if (size < ngroups) {
230 errno = EINVAL;
231 return -1;
233 memcpy(list, uwrap.groups, size*sizeof(gid_t));
234 return ngroups;
237 _PUBLIC_ uid_t uwrap_getuid(void)
239 uwrap_init();
240 if (!uwrap.enabled) {
241 return getuid();
243 /* we don't simulate ruid changing */
244 return 0;
247 _PUBLIC_ gid_t uwrap_getgid(void)
249 uwrap_init();
250 if (!uwrap.enabled) {
251 return getgid();
253 /* we don't simulate rgid changing */
254 return 0;