"Fossies" - the Fresh Open Source Software Archive 
Member "sudo-1.9.11p3/lib/util/aix.c" (12 Jun 2022, 8029 Bytes) of package /linux/misc/sudo-1.9.11p3.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "aix.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * SPDX-License-Identifier: ISC
3 *
4 * Copyright (c) 2008, 2010-2016 Todd C. Miller <Todd.Miller@sudo.ws>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /*
20 * This is an open source non-commercial project. Dear PVS-Studio, please check it.
21 * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
22 */
23
24 #include <config.h>
25
26 #include <sys/resource.h>
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <usersec.h>
32 #include <uinfo.h>
33
34 #include "sudo_compat.h"
35 #include "sudo_debug.h"
36 #include "sudo_fatal.h"
37 #include "sudo_gettext.h"
38 #include "sudo_util.h"
39
40 #ifdef HAVE_GETUSERATTR
41
42 #ifndef HAVE_SETRLIMIT64
43 # define setrlimit64(a, b) setrlimit(a, b)
44 # define rlimit64 rlimit
45 # define rlim64_t rlim_t
46 # define RLIM64_INFINITY RLIM_INFINITY
47 #endif /* HAVE_SETRLIMIT64 */
48
49 #ifndef RLIM_SAVED_MAX
50 # define RLIM_SAVED_MAX RLIM64_INFINITY
51 #endif
52
53 struct aix_limit {
54 int resource;
55 char *soft;
56 char *hard;
57 int factor;
58 };
59
60 static struct aix_limit aix_limits[] = {
61 { RLIMIT_FSIZE, S_UFSIZE, S_UFSIZE_HARD, 512 },
62 { RLIMIT_CPU, S_UCPU, S_UCPU_HARD, 1 },
63 { RLIMIT_DATA, S_UDATA, S_UDATA_HARD, 512 },
64 { RLIMIT_STACK, S_USTACK, S_USTACK_HARD, 512 },
65 { RLIMIT_RSS, S_URSS, S_URSS_HARD, 512 },
66 { RLIMIT_CORE, S_UCORE, S_UCORE_HARD, 512 },
67 { RLIMIT_NOFILE, S_UNOFILE, S_UNOFILE_HARD, 1 }
68 };
69
70 static int
71 aix_getlimit(char *user, char *lim, int *valp)
72 {
73 debug_decl(aix_getlimit, SUDO_DEBUG_UTIL);
74
75 if (getuserattr(user, lim, valp, SEC_INT) != 0)
76 debug_return_int(-1);
77 debug_return_int(0);
78 }
79
80 static int
81 aix_setlimits(char *user)
82 {
83 struct rlimit64 rlim;
84 int val;
85 size_t n;
86 debug_decl(aix_setlimits, SUDO_DEBUG_UTIL);
87
88 if (setuserdb(S_READ) != 0) {
89 sudo_warn("%s", U_("unable to open userdb"));
90 debug_return_int(-1);
91 }
92
93 /*
94 * For each resource limit, get the soft/hard values for the user
95 * and set those values via setrlimit64(). Must be run as euid 0.
96 */
97 for (n = 0; n < nitems(aix_limits); n++) {
98 /*
99 * We have two strategies, depending on whether or not the
100 * hard limit has been defined.
101 */
102 if (aix_getlimit(user, aix_limits[n].hard, &val) == 0) {
103 rlim.rlim_max = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
104 if (aix_getlimit(user, aix_limits[n].soft, &val) == 0)
105 rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
106 else
107 rlim.rlim_cur = rlim.rlim_max; /* soft not specd, use hard */
108 } else {
109 /* No hard limit set, try soft limit, if it exists. */
110 if (aix_getlimit(user, aix_limits[n].soft, &val) == -1)
111 continue;
112 rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
113
114 /* Set default hard limit as per limits(4). */
115 switch (aix_limits[n].resource) {
116 case RLIMIT_CPU:
117 case RLIMIT_FSIZE:
118 rlim.rlim_max = rlim.rlim_cur;
119 break;
120 case RLIMIT_STACK:
121 rlim.rlim_max = 4194304UL * aix_limits[n].factor;
122 break;
123 default:
124 rlim.rlim_max = RLIM64_INFINITY;
125 break;
126 }
127 }
128 (void)setrlimit64(aix_limits[n].resource, &rlim);
129 }
130 enduserdb();
131 debug_return_int(0);
132 }
133
134 #ifdef HAVE_SETAUTHDB
135
136 # ifndef HAVE_AUTHDB_T
137 typedef char authdb_t[16];
138 # endif
139
140 /* The empty string means to access all defined authentication registries. */
141 static authdb_t old_registry;
142
143 # if defined(HAVE_DECL_SETAUTHDB) && !HAVE_DECL_SETAUTHDB
144 int setauthdb(authdb_t new, authdb_t old);
145 int getauthdb(authdb_t val);
146 # endif
147 # if defined(HAVE_DECL_USRINFO) && !HAVE_DECL_USRINFO
148 int usrinfo(int cmd, char *buf, int count);
149 # endif
150
151 /*
152 * Look up authentication registry for user (SYSTEM in /etc/security/user) and
153 * set it as the default for the process. This ensures that password and
154 * group lookups are made against the correct source (files, NIS, LDAP, etc).
155 * Does not modify errno even on error since callers do not check return value.
156 */
157 int
158 aix_getauthregistry_v1(char *user, char *saved_registry)
159 {
160 int serrno = errno;
161 int ret = -1;
162 debug_decl(aix_getauthregistry, SUDO_DEBUG_UTIL);
163
164 saved_registry[0] = '\0';
165 if (user != NULL) {
166 char *registry;
167
168 if (setuserdb(S_READ) != 0) {
169 sudo_warn("%s", U_("unable to open userdb"));
170 goto done;
171 }
172 ret = getuserattr(user, S_REGISTRY, ®istry, SEC_CHAR);
173 if (ret == 0) {
174 /* sizeof(authdb_t) is guaranteed to be 16 */
175 if (strlcpy(saved_registry, registry, 16) >= 16) {
176 sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
177 "registry for user %s too long: %s", user, registry);
178 }
179 sudo_debug_printf(SUDO_DEBUG_INFO,
180 "%s: saved authentication registry for user %s is %s",
181 __func__, user, saved_registry);
182 }
183 enduserdb();
184 } else {
185 /* Get the process-wide registry. */
186 ret = getauthdb(saved_registry);
187 }
188 done:
189 errno = serrno;
190 debug_return_int(ret);
191 }
192
193 /*
194 * Set the specified authentication registry for user (SYSTEM in
195 * /etc/security/user) and set it as the default for the process.
196 * This ensures that password and group lookups are made against
197 * the correct source (files, NIS, LDAP, etc).
198 * If registry is NULL, look it up based on the user name.
199 * Does not modify errno even on error since callers do not check return value.
200 */
201 int
202 aix_setauthdb_v1(char *user)
203 {
204 return aix_setauthdb_v2(user, NULL);
205 }
206
207 int
208 aix_setauthdb_v2(char *user, char *registry)
209 {
210 authdb_t regbuf;
211 int serrno = errno;
212 int ret = -1;
213 debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL);
214
215 if (user != NULL) {
216 /* Look up authentication registry if one is not provided. */
217 if (registry == NULL) {
218 if (aix_getauthregistry(user, regbuf) != 0)
219 goto done;
220 registry = regbuf;
221 }
222 ret = setauthdb(registry, old_registry);
223 if (ret != 0) {
224 sudo_warn(U_("unable to switch to registry \"%s\" for %s"),
225 registry, user);
226 } else {
227 sudo_debug_printf(SUDO_DEBUG_INFO,
228 "%s: setting authentication registry to %s",
229 __func__, registry);
230 }
231 }
232 done:
233 errno = serrno;
234 debug_return_int(ret);
235 }
236
237 /*
238 * Restore the saved authentication registry, if any.
239 * Does not modify errno even on error since callers do not check return value.
240 */
241 int
242 aix_restoreauthdb_v1(void)
243 {
244 int serrno = errno;
245 int ret = 0;
246 debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL);
247
248 if (setauthdb(old_registry, NULL) != 0) {
249 sudo_warn("%s", U_("unable to restore registry"));
250 ret = -1;
251 } else {
252 sudo_debug_printf(SUDO_DEBUG_INFO,
253 "%s: setting authentication registry to %s",
254 __func__, old_registry);
255 }
256 errno = serrno;
257 debug_return_int(ret);
258 }
259 #endif
260
261 int
262 aix_prep_user_v1(char *user, const char *tty)
263 {
264 char *info;
265 int len;
266 debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL);
267
268 /* set usrinfo, like login(1) does */
269 len = asprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c",
270 user, '\0', user, '\0', user, '\0', tty ? tty : "", '\0');
271 if (len == -1) {
272 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
273 debug_return_int(-1);
274 }
275 (void)usrinfo(SETUINFO, info, len);
276 free(info);
277
278 #ifdef HAVE_SETAUTHDB
279 /* set authentication registry */
280 if (aix_setauthdb(user, NULL) != 0)
281 debug_return_int(-1);
282 #endif
283
284 /* set resource limits */
285 if (aix_setlimits(user) != 0)
286 debug_return_int(-1);
287
288 debug_return_int(0);
289 }
290 #endif /* HAVE_GETUSERATTR */