su.c (153985) | su.c (161815) |
---|---|
1/* 2 * Copyright (c) 2002, 2005 Networks Associates Technologies, Inc. 3 * All rights reserved. 4 * 5 * Portions of this software were developed for the FreeBSD Project by 6 * ThinkSec AS and NAI Labs, the Security Research Division of Network 7 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 8 * ("CBOSS"), as part of the DARPA CHATS research program. --- 60 unchanged lines hidden (view full) --- 69 70#if 0 71#ifndef lint 72static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94"; 73#endif /* not lint */ 74#endif 75 76#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 2002, 2005 Networks Associates Technologies, Inc. 3 * All rights reserved. 4 * 5 * Portions of this software were developed for the FreeBSD Project by 6 * ThinkSec AS and NAI Labs, the Security Research Division of Network 7 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 8 * ("CBOSS"), as part of the DARPA CHATS research program. --- 60 unchanged lines hidden (view full) --- 69 70#if 0 71#ifndef lint 72static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94"; 73#endif /* not lint */ 74#endif 75 76#include <sys/cdefs.h> |
77__FBSDID("$FreeBSD: head/usr.bin/su/su.c 153985 2006-01-03 09:17:04Z brian $"); | 77__FBSDID("$FreeBSD: head/usr.bin/su/su.c 161815 2006-09-01 13:39:02Z csjp $"); |
78 79#include <sys/param.h> 80#include <sys/time.h> 81#include <sys/resource.h> 82#include <sys/wait.h> 83 | 78 79#include <sys/param.h> 80#include <sys/time.h> 81#include <sys/resource.h> 82#include <sys/wait.h> 83 |
84#ifdef USE_BSM_AUDIT 85#include <bsm/libbsm.h> 86#include <bsm/audit_uevents.h> 87#endif 88 |
|
84#include <err.h> 85#include <errno.h> 86#include <grp.h> 87#include <login_cap.h> 88#include <paths.h> 89#include <pwd.h> 90#include <signal.h> 91#include <stdio.h> 92#include <stdlib.h> 93#include <string.h> 94#include <syslog.h> 95#include <unistd.h> | 89#include <err.h> 90#include <errno.h> 91#include <grp.h> 92#include <login_cap.h> 93#include <paths.h> 94#include <pwd.h> 95#include <signal.h> 96#include <stdio.h> 97#include <stdlib.h> 98#include <string.h> 99#include <syslog.h> 100#include <unistd.h> |
101#include <stdarg.h> |
|
96 97#include <security/pam_appl.h> 98#include <security/openpam.h> 99 100#define PAM_END() do { \ 101 int local_ret; \ 102 if (pamh != NULL) { \ 103 local_ret = pam_setcred(pamh, PAM_DELETE_CRED); \ --- 55 unchanged lines hidden (view full) --- 159 pid_t child_pid, child_pgrp, pid; 160 int asme, ch, asthem, fastlogin, prio, i, retcode, 161 statusp, setmaclabel; 162 u_int setwhat; 163 char *username, *class, shellbuf[MAXPATHLEN]; 164 const char *p, *user, *shell, *mytty, **nargv; 165 struct sigaction sa, sa_int, sa_quit, sa_pipe; 166 int temp, fds[2]; | 102 103#include <security/pam_appl.h> 104#include <security/openpam.h> 105 106#define PAM_END() do { \ 107 int local_ret; \ 108 if (pamh != NULL) { \ 109 local_ret = pam_setcred(pamh, PAM_DELETE_CRED); \ --- 55 unchanged lines hidden (view full) --- 165 pid_t child_pid, child_pgrp, pid; 166 int asme, ch, asthem, fastlogin, prio, i, retcode, 167 statusp, setmaclabel; 168 u_int setwhat; 169 char *username, *class, shellbuf[MAXPATHLEN]; 170 const char *p, *user, *shell, *mytty, **nargv; 171 struct sigaction sa, sa_int, sa_quit, sa_pipe; 172 int temp, fds[2]; |
173#ifdef USE_BSM_AUDIT 174 const char *aerr; 175 au_id_t auid; 176#endif |
|
167 168 shell = class = cleanenv = NULL; 169 asme = asthem = fastlogin = statusp = 0; 170 user = "root"; 171 iscsh = UNSET; 172 setmaclabel = 0; 173 174 while ((ch = getopt(argc, argv, "-flmsc:")) != -1) --- 24 unchanged lines hidden (view full) --- 199 200 if (optind < argc) 201 user = argv[optind++]; 202 203 if (user == NULL) 204 usage(); 205 /* NOTREACHED */ 206 | 177 178 shell = class = cleanenv = NULL; 179 asme = asthem = fastlogin = statusp = 0; 180 user = "root"; 181 iscsh = UNSET; 182 setmaclabel = 0; 183 184 while ((ch = getopt(argc, argv, "-flmsc:")) != -1) --- 24 unchanged lines hidden (view full) --- 209 210 if (optind < argc) 211 user = argv[optind++]; 212 213 if (user == NULL) 214 usage(); 215 /* NOTREACHED */ 216 |
207 if (strlen(user) > MAXLOGNAME - 1) 208 errx(1, "username too long"); 209 | |
210 /* 211 * Try to provide more helpful debugging output if su(1) is running 212 * non-setuid, or was run from a file system not mounted setuid. 213 */ 214 if (geteuid() != 0) 215 errx(1, "not running setuid"); 216 | 217 /* 218 * Try to provide more helpful debugging output if su(1) is running 219 * non-setuid, or was run from a file system not mounted setuid. 220 */ 221 if (geteuid() != 0) 222 errx(1, "not running setuid"); 223 |
224#ifdef USE_BSM_AUDIT 225 if (getauid(&auid) < 0 && errno != ENOSYS) { 226 syslog(LOG_AUTH | LOG_ERR, "getauid: %s", strerror(errno)); 227 errx(1, "Permission denied"); 228 } 229#endif 230 if (strlen(user) > MAXLOGNAME - 1) { 231#ifdef USE_BSM_AUDIT 232 if (audit_submit(AUE_su, auid, 233 1, EPERM, "username too long: '%s'", user)) 234 errx(1, "Permission denied"); 235#endif 236 errx(1, "username too long"); 237 } 238 |
|
217 nargv = malloc(sizeof(char *) * (size_t)(argc + 4)); 218 if (nargv == NULL) 219 errx(1, "malloc failure"); 220 221 nargv[argc + 3] = NULL; 222 for (i = argc; i >= optind; i--) 223 nargv[i + 3] = argv[i]; 224 np.a = &nargv[i + 3]; --- 9 unchanged lines hidden (view full) --- 234 openlog("su", LOG_CONS, LOG_AUTH); 235 236 /* get current login name, real uid and shell */ 237 ruid = getuid(); 238 username = getlogin(); 239 pwd = getpwnam(username); 240 if (username == NULL || pwd == NULL || pwd->pw_uid != ruid) 241 pwd = getpwuid(ruid); | 239 nargv = malloc(sizeof(char *) * (size_t)(argc + 4)); 240 if (nargv == NULL) 241 errx(1, "malloc failure"); 242 243 nargv[argc + 3] = NULL; 244 for (i = argc; i >= optind; i--) 245 nargv[i + 3] = argv[i]; 246 np.a = &nargv[i + 3]; --- 9 unchanged lines hidden (view full) --- 256 openlog("su", LOG_CONS, LOG_AUTH); 257 258 /* get current login name, real uid and shell */ 259 ruid = getuid(); 260 username = getlogin(); 261 pwd = getpwnam(username); 262 if (username == NULL || pwd == NULL || pwd->pw_uid != ruid) 263 pwd = getpwuid(ruid); |
242 if (pwd == NULL) | 264 if (pwd == NULL) { 265#ifdef USE_BSM_AUDIT 266 if (audit_submit(AUE_su, auid, 1, EPERM, 267 "unable to determine invoking subject: '%s'", username)) 268 errx(1, "Permission denied"); 269#endif |
243 errx(1, "who are you?"); | 270 errx(1, "who are you?"); |
271 } |
|
244 245 username = strdup(pwd->pw_name); 246 if (username == NULL) 247 err(1, "strdup failure"); 248 249 if (asme) { 250 if (pwd->pw_shell != NULL && *pwd->pw_shell != '\0') { 251 /* must copy - pwd memory is recycled */ --- 18 unchanged lines hidden (view full) --- 270 271 mytty = ttyname(STDERR_FILENO); 272 if (!mytty) 273 mytty = "tty"; 274 PAM_SET_ITEM(PAM_TTY, mytty); 275 276 retcode = pam_authenticate(pamh, 0); 277 if (retcode != PAM_SUCCESS) { | 272 273 username = strdup(pwd->pw_name); 274 if (username == NULL) 275 err(1, "strdup failure"); 276 277 if (asme) { 278 if (pwd->pw_shell != NULL && *pwd->pw_shell != '\0') { 279 /* must copy - pwd memory is recycled */ --- 18 unchanged lines hidden (view full) --- 298 299 mytty = ttyname(STDERR_FILENO); 300 if (!mytty) 301 mytty = "tty"; 302 PAM_SET_ITEM(PAM_TTY, mytty); 303 304 retcode = pam_authenticate(pamh, 0); 305 if (retcode != PAM_SUCCESS) { |
306#ifdef USE_BSM_AUDIT 307 if (audit_submit(AUE_su, auid, 1, EPERM, "bad su %s to %s on %s", 308 username, user, mytty)) 309 errx(1, "Permission denied"); 310#endif |
|
278 syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s on %s", 279 username, user, mytty); 280 errx(1, "Sorry"); 281 } | 311 syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s on %s", 312 username, user, mytty); 313 errx(1, "Sorry"); 314 } |
315#ifdef USE_BSM_AUDIT 316 if (audit_submit(AUE_su, auid, 0, 0, "successful authentication")) 317 errx(1, "Permission denied"); 318#endif |
|
282 retcode = pam_get_item(pamh, PAM_USER, (const void **)&p); 283 if (retcode == PAM_SUCCESS) 284 user = p; 285 else 286 syslog(LOG_ERR, "pam_get_item(PAM_USER): %s", 287 pam_strerror(pamh, retcode)); 288 pwd = getpwnam(user); | 319 retcode = pam_get_item(pamh, PAM_USER, (const void **)&p); 320 if (retcode == PAM_SUCCESS) 321 user = p; 322 else 323 syslog(LOG_ERR, "pam_get_item(PAM_USER): %s", 324 pam_strerror(pamh, retcode)); 325 pwd = getpwnam(user); |
289 if (pwd == NULL) | 326 if (pwd == NULL) { 327#ifdef USE_BSM_AUDIT 328 if (audit_submit(AUE_su, auid, 1, EPERM, 329 "unknown subject: %s", user)) 330 errx(1, "Permission denied"); 331#endif |
290 errx(1, "unknown login: %s", user); | 332 errx(1, "unknown login: %s", user); |
333 } |
|
291 292 retcode = pam_acct_mgmt(pamh, 0); 293 if (retcode == PAM_NEW_AUTHTOK_REQD) { 294 retcode = pam_chauthtok(pamh, 295 PAM_CHANGE_EXPIRED_AUTHTOK); 296 if (retcode != PAM_SUCCESS) { | 334 335 retcode = pam_acct_mgmt(pamh, 0); 336 if (retcode == PAM_NEW_AUTHTOK_REQD) { 337 retcode = pam_chauthtok(pamh, 338 PAM_CHANGE_EXPIRED_AUTHTOK); 339 if (retcode != PAM_SUCCESS) { |
340#ifdef USE_BSM_AUDIT 341 aerr = pam_strerror(pamh, retcode); 342 if (aerr == NULL) 343 aerr = "Unknown PAM error"; 344 if (audit_submit(AUE_su, auid, 1, EPERM, 345 "pam_chauthtok: %s", aerr)) 346 errx(1, "Permission denied"); 347#endif |
|
297 syslog(LOG_ERR, "pam_chauthtok: %s", 298 pam_strerror(pamh, retcode)); 299 errx(1, "Sorry"); 300 } 301 } 302 if (retcode != PAM_SUCCESS) { | 348 syslog(LOG_ERR, "pam_chauthtok: %s", 349 pam_strerror(pamh, retcode)); 350 errx(1, "Sorry"); 351 } 352 } 353 if (retcode != PAM_SUCCESS) { |
354#ifdef USE_BSM_AUDIT 355 if (audit_submit(AUE_su, auid, 1, EPERM, "pam_acct_mgmt: %s", 356 pam_strerror(pamh, retcode))) 357 errx(1, "Permission denied"); 358#endif |
|
303 syslog(LOG_ERR, "pam_acct_mgmt: %s", 304 pam_strerror(pamh, retcode)); 305 errx(1, "Sorry"); 306 } 307 308 /* get target login information */ 309 if (class == NULL) 310 lc = login_getpwclass(pwd); 311 else { | 359 syslog(LOG_ERR, "pam_acct_mgmt: %s", 360 pam_strerror(pamh, retcode)); 361 errx(1, "Sorry"); 362 } 363 364 /* get target login information */ 365 if (class == NULL) 366 lc = login_getpwclass(pwd); 367 else { |
312 if (ruid != 0) | 368 if (ruid != 0) { 369#ifdef USE_BSM_AUDIT 370 if (audit_submit(AUE_su, auid, 1, EPERM, 371 "only root may use -c")) 372 errx(1, "Permission denied"); 373#endif |
313 errx(1, "only root may use -c"); | 374 errx(1, "only root may use -c"); |
375 } |
|
314 lc = login_getclass(class); 315 if (lc == NULL) 316 errx(1, "unknown class: %s", class); 317 } 318 319 /* if asme and non-standard target shell, must be root */ 320 if (asme) { 321 if (ruid != 0 && !chshell(pwd->pw_shell)) --- 259 unchanged lines hidden --- | 376 lc = login_getclass(class); 377 if (lc == NULL) 378 errx(1, "unknown class: %s", class); 379 } 380 381 /* if asme and non-standard target shell, must be root */ 382 if (asme) { 383 if (ruid != 0 && !chshell(pwd->pw_shell)) --- 259 unchanged lines hidden --- |