Fix smbclient/tarmode panic on connecting to Windows 2000 clients.
[Samba.git] / lib / uid_wrapper / uid_wrapper.c
blobc67679777c5fdaefa7ad442181472bb4d2897e53
1 /*
2 Copyright (C) Andrew Tridgell 2009
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #ifdef _SAMBA_BUILD_
20 #define UID_WRAPPER_NOT_REPLACE
21 #include "../replace/replace.h"
22 #include <talloc.h>
23 #include "system/passwd.h"
25 #else /* _SAMBA_BUILD_ */
27 #error uid_wrapper_only_supported_in_samba_yet
29 #endif
31 #ifndef _PUBLIC_
32 #define _PUBLIC_
33 #endif
36 we keep the virtualised euid/egid/groups information here
38 static struct {
39 bool initialised;
40 bool enabled;
41 uid_t euid;
42 gid_t egid;
43 unsigned ngroups;
44 gid_t *groups;
45 } uwrap;
47 static void uwrap_init(void)
49 if (uwrap.initialised) return;
50 uwrap.initialised = true;
51 if (getenv("UID_WRAPPER")) {
52 uwrap.enabled = true;
53 /* put us in one group */
54 uwrap.ngroups = 1;
55 uwrap.groups = talloc_array(NULL, gid_t, 1);
56 uwrap.groups[0] = 0;
60 #undef uwrap_enabled
61 _PUBLIC_ int uwrap_enabled(void)
63 uwrap_init();
64 return uwrap.enabled?1:0;
67 _PUBLIC_ int uwrap_seteuid(uid_t euid)
69 uwrap_init();
70 if (!uwrap.enabled) {
71 return seteuid(euid);
73 /* assume for now that the ruid stays as root */
74 uwrap.euid = euid;
75 return 0;
78 _PUBLIC_ uid_t uwrap_geteuid(void)
80 uwrap_init();
81 if (!uwrap.enabled) {
82 return geteuid();
84 return uwrap.euid;
87 _PUBLIC_ int uwrap_setegid(gid_t egid)
89 uwrap_init();
90 if (!uwrap.enabled) {
91 return setegid(egid);
93 /* assume for now that the ruid stays as root */
94 uwrap.egid = egid;
95 return 0;
98 _PUBLIC_ uid_t uwrap_getegid(void)
100 uwrap_init();
101 if (!uwrap.enabled) {
102 return getegid();
104 return uwrap.egid;
107 _PUBLIC_ int uwrap_setgroups(size_t size, const gid_t *list)
109 uwrap_init();
110 if (!uwrap.enabled) {
111 return setgroups(size, list);
114 talloc_free(uwrap.groups);
115 uwrap.ngroups = 0;
116 uwrap.groups = NULL;
118 if (size != 0) {
119 uwrap.groups = talloc_array(NULL, gid_t, size);
120 if (uwrap.groups == NULL) {
121 errno = ENOMEM;
122 return -1;
124 memcpy(uwrap.groups, list, size*sizeof(gid_t));
125 uwrap.ngroups = size;
127 return 0;
130 _PUBLIC_ int uwrap_getgroups(int size, gid_t *list)
132 uwrap_init();
133 if (!uwrap.enabled) {
134 return getgroups(size, list);
137 if (size > uwrap.ngroups) {
138 size = uwrap.ngroups;
140 if (size == 0) {
141 return uwrap.ngroups;
143 if (size < uwrap.ngroups) {
144 errno = EINVAL;
145 return -1;
147 memcpy(list, uwrap.groups, size*sizeof(gid_t));
148 return uwrap.ngroups;
151 _PUBLIC_ uid_t uwrap_getuid(void)
153 uwrap_init();
154 if (!uwrap.enabled) {
155 return getuid();
157 /* we don't simulate ruid changing */
158 return 0;
161 _PUBLIC_ gid_t uwrap_getgid(void)
163 uwrap_init();
164 if (!uwrap.enabled) {
165 return getgid();
167 /* we don't simulate rgid changing */
168 return 0;