1/* 2 * Copyright (c) 1993-1996, 1998-2010 Todd C. Miller <Todd.Miller@courtesan.com> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * 16 * Sponsored in part by the Defense Advanced Research Projects 17 * Agency (DARPA) and Air Force Research Laboratory, Air Force 18 * Materiel Command, USAF, under agreement number F39502-99-1-0512. 19 * 20 * For a brief history of sudo, please see the HISTORY file included 21 * with this distribution. 22 */ 23 24#define _SUDO_MAIN 25 26#ifdef __TANDEM 27# include <floss.h> 28#endif 29 30#include <config.h> 31 32#include <sys/types.h> 33#include <sys/stat.h> 34#include <sys/wait.h> 35#include <sys/param.h> 36#include <sys/socket.h> 37#ifdef HAVE_SETRLIMIT 38# include <sys/time.h> 39# include <sys/resource.h> 40#endif 41#include <stdio.h> 42#ifdef STDC_HEADERS 43# include <stdlib.h> 44# include <stddef.h> 45#else 46# ifdef HAVE_STDLIB_H 47# include <stdlib.h> 48# endif 49#endif /* STDC_HEADERS */ 50#ifdef HAVE_STRING_H 51# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) 52# include <memory.h> 53# endif 54# include <string.h> 55#endif /* HAVE_STRING_H */ 56#ifdef HAVE_STRINGS_H 57# include <strings.h> 58#endif /* HAVE_STRINGS_H */ 59#ifdef HAVE_UNISTD_H 60# include <unistd.h> 61#endif /* HAVE_UNISTD_H */ 62#include <pwd.h> 63#include <ctype.h> 64#include <errno.h> 65#include <fcntl.h> 66#include <signal.h> 67#include <grp.h> 68#if TIME_WITH_SYS_TIME 69# include <time.h> 70#endif 71#ifdef HAVE_SETLOCALE 72# include <locale.h> 73#endif 74#include <netinet/in.h> 75#include <netdb.h> 76#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS) 77# ifdef __hpux 78# undef MAXINT 79# include <hpsecurity.h> 80# else 81# include <sys/security.h> 82# endif /* __hpux */ 83# include <prot.h> 84#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */ 85#ifdef HAVE_LOGIN_CAP_H 86# include <login_cap.h> 87# ifndef LOGIN_DEFROOTCLASS 88# define LOGIN_DEFROOTCLASS "daemon" 89# endif 90# ifndef LOGIN_SETENV 91# define LOGIN_SETENV 0 92# endif 93#endif 94#ifdef HAVE_MBR_CHECK_MEMBERSHIP 95# include <membership.h> 96#endif 97#if defined(HAVE_STRUCT_KINFO_PROC_P_TDEV) || defined (HAVE_STRUCT_KINFO_PROC_KP_EPROC_E_TDEV) 98# include <sys/sysctl.h> 99#else 100# if defined(HAVE_STRUCT_KINFO_PROC_KI_TDEV) 101# include <sys/sysctl.h> 102# include <sys/user.h> 103# endif 104#endif 105 106#include "sudo.h" 107#include "lbuf.h" 108#include "interfaces.h" 109#include "secure_path.h" 110#include "sudo_usage.h" 111 112#ifdef USING_NONUNIX_GROUPS 113# include "nonunix.h" 114#endif 115 116#if defined(HAVE_PAM) && !defined(NO_PAM_SESSION) 117# define CMND_WAIT TRUE 118#else 119# define CMND_WAIT FALSE 120#endif 121 122/* 123 * Prototypes 124 */ 125static void init_vars __P((char **)); 126static int set_cmnd __P((int)); 127static void initial_setup __P((void)); 128static void set_loginclass __P((struct passwd *)); 129static void set_runaspw __P((const char *)); 130static void set_runasgr __P((const char *)); 131static int cb_runas_default __P((const char *)); 132static void show_version __P((void)); 133static void create_admin_success_flag __P((void)); 134extern int sudo_edit __P((int, char **, char **)); 135int run_command __P((const char *path, char *argv[], char *envp[], uid_t uid, int dowait)); /* XXX should be in sudo.h */ 136static void sudo_check_suid __P((const char *path)); 137 138/* 139 * Globals 140 */ 141int Argc, NewArgc; 142char **Argv, **NewArgv; 143char *prev_user; 144int user_closefrom = -1; 145struct sudo_user sudo_user; 146struct passwd *list_pw; 147struct interface *interfaces; 148int num_interfaces; 149int tgetpass_flags; 150int long_list; 151uid_t timestamp_uid; 152extern int errorlineno; 153extern int parse_error; 154extern char *errorfile; 155#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) 156static struct rlimit corelimit; 157#endif /* RLIMIT_CORE && !SUDO_DEVEL */ 158#if defined(__linux__) 159static struct rlimit nproclimit; 160#endif 161#ifdef HAVE_LOGIN_CAP_H 162login_cap_t *lc; 163#endif /* HAVE_LOGIN_CAP_H */ 164sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp; 165char *runas_user; 166char *runas_group; 167static struct sudo_nss_list *snl; 168int sudo_mode; 169 170/* For getopt(3) */ 171extern char *optarg; 172extern int optind; 173 174int 175main(argc, argv, envp) 176 int argc; 177 char *argv[]; 178 char *envp[]; 179{ 180 int sources = 0, validated; 181 int fd, cmnd_status, pwflag, rval = TRUE; 182 sigaction_t sa; 183 struct sudo_nss *nss; 184#if defined(SUDO_DEVEL) && defined(__OpenBSD__) 185 extern char *malloc_options; 186 malloc_options = "AFGJPR"; 187#endif 188 189#ifdef HAVE_SETLOCALE 190 setlocale(LC_ALL, ""); 191#endif 192 193 Argv = argv; 194 if ((Argc = argc) < 1) 195 usage(1); 196 197 /* Must be done as the first thing... */ 198#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS) 199 (void) set_auth_parameters(Argc, Argv); 200# ifdef HAVE_INITPRIVS 201 initprivs(); 202# endif 203#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */ 204 205 /* Make sure we are setuid root. */ 206 sudo_check_suid(argv[0]); 207 208 /* 209 * Signal setup: 210 * Ignore keyboard-generated signals so the user cannot interrupt 211 * us at some point and avoid the logging. 212 * Install handler to wait for children when they exit. 213 */ 214 save_signals(); 215 zero_bytes(&sa, sizeof(sa)); 216 sigemptyset(&sa.sa_mask); 217 sa.sa_flags = SA_RESTART; 218 sa.sa_handler = SIG_IGN; 219 (void) sigaction(SIGINT, &sa, &saved_sa_int); 220 (void) sigaction(SIGQUIT, &sa, &saved_sa_quit); 221 (void) sigaction(SIGTSTP, &sa, &saved_sa_tstp); 222 223 /* Initialize environment functions (including replacements). */ 224 env_init(FALSE); 225 226 /* 227 * Turn off core dumps and make sure fds 0-2 are open. 228 */ 229 initial_setup(); 230 sudo_setpwent(); 231 sudo_setgrent(); 232 233 /* Parse our arguments. */ 234 sudo_mode = parse_args(Argc, Argv); 235 236 /* Setup defaults data structures. */ 237 init_defaults(); 238 239 /* Load the list of local ip addresses and netmasks. */ 240 load_interfaces(); 241 242 pwflag = 0; 243 if (ISSET(sudo_mode, MODE_SHELL)) 244 user_cmnd = "shell"; 245 else if (ISSET(sudo_mode, MODE_EDIT)) 246 user_cmnd = "sudoedit"; 247 else { 248 switch (sudo_mode & MODE_MASK) { 249 case MODE_VERSION: 250 show_version(); 251 break; 252 case MODE_HELP: 253 help(); 254 break; 255 case MODE_VALIDATE: 256 case MODE_VALIDATE|MODE_INVALIDATE: 257 user_cmnd = "validate"; 258 pwflag = I_VERIFYPW; 259 break; 260 case MODE_KILL: 261 case MODE_INVALIDATE: 262 user_cmnd = "kill"; 263 pwflag = -1; 264 break; 265 case MODE_LISTDEFS: 266 list_options(); 267 goto done; 268 break; 269 case MODE_LIST: 270 case MODE_LIST|MODE_INVALIDATE: 271 user_cmnd = "list"; 272 pwflag = I_LISTPW; 273 break; 274 case MODE_CHECK: 275 case MODE_CHECK|MODE_INVALIDATE: 276 pwflag = I_LISTPW; 277 break; 278 } 279 } 280 281 /* Must have a command to run... */ 282 if (user_cmnd == NULL && NewArgc == 0) 283 usage(1); 284 285 init_vars(envp); /* XXX - move this later? */ 286 287#ifdef USING_NONUNIX_GROUPS 288 sudo_nonunix_groupcheck_init(); /* initialise nonunix groups impl */ 289#endif /* USING_NONUNIX_GROUPS */ 290 291 /* Parse nsswitch.conf for sudoers order. */ 292 snl = sudo_read_nss(); 293 294 /* Open and parse sudoers, set global defaults */ 295 tq_foreach_fwd(snl, nss) { 296 if (nss->open(nss) == 0 && nss->parse(nss) == 0) { 297 sources++; 298 if (nss->setdefs(nss) != 0) 299 log_error(NO_STDERR, "problem with defaults entries"); 300 } 301 } 302 if (sources == 0) 303 log_fatal(0, "no valid sudoers sources found, quitting"); 304 305 /* XXX - collect post-sudoers parse settings into a function */ 306 307 /* 308 * Set runas passwd/group entries based on command line or sudoers. 309 * Note that if runas_group was specified without runas_user we 310 * defer setting runas_pw so the match routines know to ignore it. 311 */ 312 if (runas_group != NULL) { 313 set_runasgr(runas_group); 314 if (runas_user != NULL) 315 set_runaspw(runas_user); 316 } else 317 set_runaspw(runas_user ? runas_user : def_runas_default); 318 319 if (!update_defaults(SETDEF_RUNAS)) 320 log_error(NO_STDERR, "problem with defaults entries"); 321 322 if (def_fqdn) 323 set_fqdn(); /* deferred until after sudoers is parsed */ 324 325 /* Set login class if applicable. */ 326 set_loginclass(runas_pw ? runas_pw : sudo_user.pw); 327 328 /* Update initial shell now that runas is set. */ 329 if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) 330 NewArgv[0] = estrdup(runas_pw->pw_shell); 331 332 /* This goes after sudoers is parsed since it may have timestamp options. */ 333 if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { 334 /* Not an audit event. */ 335 remove_timestamp((sudo_mode == MODE_KILL)); 336 goto done; 337 } 338 339 /* Is root even allowed to run sudo? */ 340 if (user_uid == 0 && !def_root_sudo) { 341 /* Not an audit event. */ 342 (void) fprintf(stderr, 343 "Sorry, %s has been configured to not allow root to run it.\n", 344 getprogname()); 345 goto bad; 346 } 347 348 /* Check for -C overriding def_closefrom. */ 349 if (user_closefrom >= 0 && user_closefrom != def_closefrom) { 350 if (!def_closefrom_override) { 351 warningx("you are not permitted to use the -C option"); 352 goto bad; 353 } 354 def_closefrom = user_closefrom; 355 } 356 357 /* If given the -P option, set the "preserve_groups" flag. */ 358 if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS)) 359 def_preserve_groups = TRUE; 360 361 cmnd_status = set_cmnd(sudo_mode); 362 363#ifdef HAVE_SETLOCALE 364 if (!setlocale(LC_ALL, def_sudoers_locale)) { 365 warningx("unable to set locale to \"%s\", using \"C\"", 366 def_sudoers_locale); 367 setlocale(LC_ALL, "C"); 368 } 369#endif 370 371 validated = FLAG_NO_USER | FLAG_NO_HOST; 372 tq_foreach_fwd(snl, nss) { 373 validated = nss->lookup(nss, validated, pwflag); 374 375 if (ISSET(validated, VALIDATE_OK)) { 376 /* Handle [SUCCESS=return] */ 377 if (nss->ret_if_found) 378 break; 379 } else { 380 /* Handle [NOTFOUND=return] */ 381 if (nss->ret_if_notfound) 382 break; 383 } 384 } 385 386 if (safe_cmnd == NULL) 387 safe_cmnd = estrdup(user_cmnd); 388 389#ifdef HAVE_SETLOCALE 390 setlocale(LC_ALL, ""); 391#endif 392 393 /* If only a group was specified, set runas_pw based on invoking user. */ 394 if (runas_pw == NULL) 395 set_runaspw(user_name); 396 397 /* 398 * Look up the timestamp dir owner if one is specified. 399 */ 400 if (def_timestampowner) { 401 struct passwd *pw; 402 403 if (*def_timestampowner == '#') 404 pw = sudo_getpwuid(atoi(def_timestampowner + 1)); 405 else 406 pw = sudo_getpwnam(def_timestampowner); 407 if (pw != NULL) { 408 timestamp_uid = pw->pw_uid; 409 pw_delref(pw); 410 } else { 411 log_error(0, "timestamp owner (%s): No such user", 412 def_timestampowner); 413 timestamp_uid = ROOT_UID; 414 } 415 } 416 417 /* If no command line args and "set_home" is not set, error out. */ 418 if (ISSET(sudo_mode, MODE_IMPLIED_SHELL) && !def_shell_noargs) 419 usage(1); 420 421 /* Bail if a tty is required and we don't have one. */ 422 if (def_requiretty) { 423 if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) { 424 audit_failure(NewArgv, "no tty"); 425 log_fatal(NO_MAIL, "sorry, you must have a tty to run sudo"); 426 } else 427 (void) close(fd); 428 } 429 430 /* Use askpass value from sudoers unless user specified their own. */ 431 if (def_askpass && !user_askpass) 432 user_askpass = def_askpass; 433 434 /* 435 * We don't reset the environment for sudoedit or if the user 436 * specified the -E command line flag and they have setenv privs. 437 */ 438 if (ISSET(sudo_mode, MODE_EDIT) || 439 (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)) 440 def_env_reset = FALSE; 441 442 /* Build a new environment that avoids any nasty bits. */ 443 rebuild_env(def_noexec); 444 445 /* Require a password if sudoers says so. */ 446 rval = check_user(validated, sudo_mode); 447 if (rval != TRUE) { 448 if (!ISSET(validated, VALIDATE_OK)) 449 log_denial(validated, FALSE); 450 goto done; 451 } 452 453 /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */ 454 /* XXX - causes confusion when root is not listed in sudoers */ 455 if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) { 456 if (user_uid == 0 && strcmp(prev_user, "root") != 0) { 457 struct passwd *pw; 458 459 if ((pw = sudo_getpwnam(prev_user)) != NULL) { 460 if (sudo_user.pw != NULL) 461 pw_delref(sudo_user.pw); 462 sudo_user.pw = pw; 463#ifdef HAVE_MBR_CHECK_MEMBERSHIP 464 mbr_uid_to_uuid(user_uid, user_uuid); 465#endif 466 } 467 } 468 } 469 470 /* If the user was not allowed to run the command we are done. */ 471 if (!ISSET(validated, VALIDATE_OK)) { 472 log_failure(validated, cmnd_status); 473 goto bad; 474 } 475 476 /* Create Ubuntu-style dot file to indicate sudo was successful. */ 477 create_admin_success_flag(); 478 479 /* Finally tell the user if the command did not exist. */ 480 if (cmnd_status == NOT_FOUND_DOT) { 481 audit_failure(NewArgv, "command in current directory"); 482 warningx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd); 483 goto bad; 484 } else if (cmnd_status == NOT_FOUND) { 485 audit_failure(NewArgv, "%s: command not found", user_cmnd); 486 warningx("%s: command not found", user_cmnd); 487 goto bad; 488 } 489 490 /* If user specified env vars make sure sudoers allows it. */ 491 if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) { 492 if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) { 493 warningx("sorry, you are not allowed to preserve the environment"); 494 goto bad; 495 } else 496 validate_env_vars(sudo_user.env_vars); 497 } 498 499#ifdef _PATH_SUDO_IO_LOGDIR 500 /* Get next session ID so we can log it. */ 501 if (ISSET(sudo_mode, (MODE_RUN | MODE_EDIT)) && (def_log_input || def_log_output)) 502 io_nextid(); 503#endif 504 log_allowed(validated); 505 if (ISSET(sudo_mode, MODE_CHECK)) 506 rval = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw); 507 else if (ISSET(sudo_mode, MODE_LIST)) 508 display_privs(snl, list_pw ? list_pw : sudo_user.pw); 509 510 /* Cleanup sudoers sources */ 511 tq_foreach_fwd(snl, nss) { 512 nss->close(nss); 513 } 514#ifdef USING_NONUNIX_GROUPS 515 /* Finished with the groupcheck code */ 516 sudo_nonunix_groupcheck_cleanup(); 517#endif 518 519 if (ISSET(sudo_mode, (MODE_VALIDATE|MODE_CHECK|MODE_LIST))) { 520 /* rval already set appropriately */ 521 goto done; 522 } 523 524 /* Must audit before uid change. */ 525 audit_success(NewArgv); 526 527 if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) { 528 char *p; 529 530 /* Convert /bin/sh -> -sh so shell knows it is a login shell */ 531 if ((p = strrchr(NewArgv[0], '/')) == NULL) 532 p = NewArgv[0]; 533 *p = '-'; 534 NewArgv[0] = p; 535 536 /* 537 * Newer versions of bash require the --login option to be used 538 * in conjunction with the -c option even if the shell name starts 539 * with a '-'. Unfortunately, bash 1.x uses -login, not --login 540 * so this will cause an error for that. 541 */ 542 if (NewArgc > 1 && strcmp(NewArgv[0], "-bash") == 0) { 543 /* Use an extra slot before NewArgv so we can store --login. */ 544 NewArgv--; 545 NewArgc++; 546 NewArgv[0] = NewArgv[1]; 547 NewArgv[1] = "--login"; 548 } 549 550#if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM)) 551 /* Insert system-wide environment variables. */ 552 read_env_file(_PATH_ENVIRONMENT, TRUE); 553#endif 554#ifdef HAVE_LOGIN_CAP_H 555 /* Set environment based on login class. */ 556 if (login_class) { 557 login_cap_t *lc = login_getclass(login_class); 558 if (lc != NULL) { 559 setusercontext(lc, runas_pw, runas_pw->pw_uid, 560 LOGIN_SETPATH|LOGIN_SETENV); 561 login_close(lc); 562 } 563 } 564#endif /* HAVE_LOGIN_CAP_H */ 565 } 566 567 if (ISSET(sudo_mode, MODE_RUN)) { 568 /* Insert system-wide environment variables. */ 569 if (def_env_file) 570 read_env_file(def_env_file, FALSE); 571 572 /* Insert user-specified environment variables. */ 573 insert_env_vars(sudo_user.env_vars); 574 } 575 576 /* Restore signal handlers before we exec. */ 577 (void) sigaction(SIGINT, &saved_sa_int, NULL); 578 (void) sigaction(SIGQUIT, &saved_sa_quit, NULL); 579 (void) sigaction(SIGTSTP, &saved_sa_tstp, NULL); 580 581 if (ISSET(sudo_mode, MODE_EDIT)) { 582 exit(sudo_edit(NewArgc, NewArgv, envp)); 583 } else { 584 exit(run_command(safe_cmnd, NewArgv, env_get(), runas_pw->pw_uid, 585 CMND_WAIT)); 586 } 587 588bad: 589 rval = FALSE; 590 591done: 592 cleanup(0); 593 exit(!rval); 594} 595 596/* 597 * Initialize timezone, set umask, fill in ``sudo_user'' struct and 598 * load the ``interfaces'' array. 599 */ 600static void 601init_vars(envp) 602 char **envp; 603{ 604 char *p, **ep, thost[MAXHOSTNAMELEN + 1]; 605 int nohostname; 606 607 /* Sanity check command from user. */ 608 if (user_cmnd == NULL && strlen(NewArgv[0]) >= PATH_MAX) { 609 audit_failure(NULL, "pathname too long"); 610 errorx(1, "%s: File name too long", NewArgv[0]); 611 } 612 613#ifdef HAVE_TZSET 614 (void) tzset(); /* set the timezone if applicable */ 615#endif /* HAVE_TZSET */ 616 617 /* Default value for cmnd and cwd, overridden later. */ 618 if (user_cmnd == NULL) 619 user_cmnd = NewArgv[0]; 620 (void) strlcpy(user_cwd, "unknown", sizeof(user_cwd)); 621 622 /* 623 * We avoid gethostbyname() if possible since we don't want 624 * sudo to block if DNS or NIS is hosed. 625 * "host" is the (possibly fully-qualified) hostname and 626 * "shost" is the unqualified form of the hostname. 627 */ 628 nohostname = gethostname(thost, sizeof(thost)); 629 if (nohostname) { 630 user_host = user_shost = "localhost"; 631 } else { 632 thost[sizeof(thost) - 1] = '\0'; 633 user_host = estrdup(thost); 634 if ((p = strchr(user_host, '.'))) { 635 *p = '\0'; 636 user_shost = estrdup(user_host); 637 *p = '.'; 638 } else { 639 user_shost = user_host; 640 } 641 } 642 643 if ((p = get_process_ttyname()) != NULL) { 644 user_tty = user_ttypath = p; 645 if (strncmp(user_tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) 646 user_tty += sizeof(_PATH_DEV) - 1; 647 } else 648 user_tty = "unknown"; 649 650 for (ep = envp; *ep; ep++) { 651 /* XXX - don't fill in if empty string */ 652 switch (**ep) { 653 case 'D': 654 if (strncmp("DISPLAY=", *ep, 8) == 0) 655 user_display = *ep + 8; 656 break; 657 case 'K': 658 if (strncmp("KRB5CCNAME=", *ep, 11) == 0) 659 user_ccname = *ep + 11; 660 break; 661 case 'P': 662 if (strncmp("PATH=", *ep, 5) == 0) 663 user_path = *ep + 5; 664 break; 665 case 'S': 666 if (strncmp("SHELL=", *ep, 6) == 0) 667 user_shell = *ep + 6; 668 else if (!user_prompt && strncmp("SUDO_PROMPT=", *ep, 12) == 0) 669 user_prompt = *ep + 12; 670 else if (strncmp("SUDO_USER=", *ep, 10) == 0) 671 prev_user = *ep + 10; 672 else if (strncmp("SUDO_ASKPASS=", *ep, 13) == 0) 673 user_askpass = *ep + 13; 674 break; 675 } 676 } 677 678 /* 679 * Stash a local copy of the user's struct passwd. 680 */ 681 if ((sudo_user.pw = sudo_getpwuid(getuid())) == NULL) { 682 uid_t uid = getuid(); 683 gid_t gid = getgid(); 684 685 /* 686 * If we are in -k/-K mode, just spew to stderr. It is not unusual for 687 * users to place "sudo -k" in a .logout file which can cause sudo to 688 * be run during reboot after the YP/NIS/NIS+/LDAP/etc daemon has died. 689 */ 690 if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) 691 errorx(1, "unknown uid: %u", (unsigned int) uid); 692 693 /* Need to make a fake struct passwd for the call to log_fatal(). */ 694 sudo_user.pw = sudo_fakepwuid(uid, gid); 695 log_fatal(0, "unknown uid: %u", (unsigned int) uid); 696 } 697#ifdef HAVE_MBR_CHECK_MEMBERSHIP 698 mbr_uid_to_uuid(user_uid, user_uuid); 699#endif 700#ifdef HAVE_GETSID 701 user_sid = getsid(0); 702#endif 703 if (user_shell == NULL || *user_shell == '\0') 704 user_shell = estrdup(sudo_user.pw->pw_shell); 705 706 /* It is now safe to use log_fatal() and set_perms() */ 707 708#ifdef HAVE_GETGROUPS 709 if ((user_ngroups = getgroups(0, NULL)) > 0) { 710 user_groups = emalloc2(user_ngroups, sizeof(GETGROUPS_T)); 711 if (getgroups(user_ngroups, user_groups) < 0) 712 log_fatal(USE_ERRNO|MSG_ONLY, "can't get group vector"); 713 } 714#endif 715 716 if (nohostname) 717 log_fatal(USE_ERRNO|MSG_ONLY, "can't get hostname"); 718 719 /* 720 * Get current working directory. Try as user, fall back to root. 721 */ 722 set_perms(PERM_USER); 723 if (!getcwd(user_cwd, sizeof(user_cwd))) { 724 set_perms(PERM_ROOT); 725 if (!getcwd(user_cwd, sizeof(user_cwd))) { 726 warningx("cannot get working directory"); 727 (void) strlcpy(user_cwd, "unknown", sizeof(user_cwd)); 728 } 729 } else 730 set_perms(PERM_ROOT); 731 732 /* 733 * If in shell or edit mode, or if running a pseudo-command 734 * such as "list", we need to redo NewArgv and NewArgc. 735 */ 736 if (ISSET(sudo_mode, MODE_SHELL)) { 737 char **av, *cmnd = NULL; 738 int ac = 1; 739 740 if (NewArgc > 0) { 741 /* shell -c "command" */ 742 char *src, *dst; 743 size_t cmnd_size = (size_t) (NewArgv[NewArgc - 1] - NewArgv[0]); 744 for (av = NewArgv; *av != NULL; av++) 745 cmnd_size += strlen(*av); 746 747 cmnd = dst = emalloc2(cmnd_size, 2); 748 for (av = NewArgv; *av != NULL; av++) { 749 for (src = *av; *src != '\0'; src++) { 750 /* quote potential meta characters */ 751 // if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-') 752 // *dst++ = '\\'; 753 *dst++ = *src; 754 } 755 *dst++ = ' '; 756 } 757 if (cmnd != dst) 758 dst--; /* replace last space with a NUL */ 759 *dst = '\0'; 760 761 ac += 2; /* -c cmnd */ 762 } 763 764 /* Allocate 2 extra slots for --login and execve() failure (ENOEXEC). */ 765 av = (char **) emalloc2(ac + 3, sizeof(char *)); 766 av += 2; 767 av[0] = user_shell; /* may be updated later */ 768 if (cmnd != NULL) { 769 av[1] = "-c"; 770 av[2] = cmnd; 771 } 772 av[ac] = NULL; 773 NewArgv = av; 774 NewArgc = ac; 775 } else if (ISSET(sudo_mode, MODE_EDIT) || NewArgc == 0) { 776 NewArgv--; 777 NewArgc++; 778 NewArgv[0] = user_cmnd; 779 } 780 781 /* Set runas callback. */ 782 sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default; 783} 784 785/* 786 * Fill in user_cmnd, user_args, user_base and user_stat variables 787 * and apply any command-specific defaults entries. 788 */ 789static int 790set_cmnd(sudo_mode) 791 int sudo_mode; 792{ 793 int rval; 794 char *path = user_path; 795 796 /* Resolve the path and return. */ 797 rval = FOUND; 798 user_stat = ecalloc(1, sizeof(struct stat)); 799 if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { 800 if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) { 801 if (def_secure_path && !user_is_exempt()) 802 path = def_secure_path; 803 set_perms(PERM_RUNAS); 804 rval = find_path(NewArgv[0], &user_cmnd, user_stat, path, 805 def_ignore_dot); 806 set_perms(PERM_ROOT); 807 if (rval != FOUND) { 808 /* Failed as root, try as invoking user. */ 809 set_perms(PERM_USER); 810 rval = find_path(NewArgv[0], &user_cmnd, user_stat, path, 811 def_ignore_dot); 812 set_perms(PERM_ROOT); 813 } 814 } 815 816 /* set user_args */ 817 if (NewArgc > 1) { 818 char *to, *from, **av; 819 size_t size, n; 820 821 if (ISSET(sudo_mode, MODE_SHELL)) { 822 for (size = 0, av = NewArgv + 1; *av; av++) 823 size += strlen(*av) + 1; 824 user_args = emalloc(size); 825 826 /* 827 * When running a command via a shell, sudo escapes potential 828 * meta chars in NewArgv. We unescape non-spaces for sudoers 829 * matching and logging purposes. 830 */ 831 for (to = user_args, av = NewArgv + 1; (from = *av); av++) { 832 while (*from) { 833 if (from[0] == '\\' && !isspace((unsigned char)from[1])) 834 from++; 835 *to++ = *from++; 836 } 837 *to++ = ' '; 838 } 839 *--to = '\0'; 840 } else { 841 /* NewArgv is contiguous so just count. */ 842 size = (size_t) (NewArgv[NewArgc - 1] - NewArgv[1]) + 843 strlen(NewArgv[NewArgc - 1]) + 1; 844 user_args = emalloc(size); 845 846 for (to = user_args, av = NewArgv + 1; *av; av++) { 847 n = strlcpy(to, *av, size - (to - user_args)); 848 if (n >= size - (to - user_args)) 849 errorx(1, "internal error, init_vars() overflow"); 850 to += n; 851 *to++ = ' '; 852 } 853 *--to = '\0'; 854 } 855 } 856 } 857 if ((user_base = strrchr(user_cmnd, '/')) != NULL) 858 user_base++; 859 else 860 user_base = user_cmnd; 861 862 if (!update_defaults(SETDEF_CMND)) 863 log_error(NO_STDERR, "problem with defaults entries"); 864 865 return rval; 866} 867 868/* 869 * Setup the execution environment immediately prior to the call to execve() 870 * Returns TRUE on success and FALSE on failure. 871 */ 872int 873exec_setup(rbac_enabled, ttyname, ttyfd) 874 int rbac_enabled; 875 const char *ttyname; 876 int ttyfd; 877{ 878 int rval = FALSE; 879 880#ifdef HAVE_SELINUX 881 if (rbac_enabled) { 882 if (selinux_setup(user_role, user_type, ttyname, ttyfd) == -1) 883 goto done; 884 } 885#endif 886 887 /* 888 * For sudoedit, the command runas a the user with no additional setup. 889 */ 890 if (ISSET(sudo_mode, MODE_EDIT)) { 891 set_perms(PERM_FULL_USER); 892 rval = TRUE; 893 goto done; 894 } 895 896 /* 897 * Set umask based on sudoers. 898 * If user's umask is more restrictive, OR in those bits too 899 * unless umask_override is set. 900 */ 901 if (def_umask != 0777) { 902 if (def_umask_override) { 903 umask(def_umask); 904 } else { 905 mode_t mask = umask(def_umask); 906 mask |= def_umask; 907 if (mask != def_umask) 908 umask(mask); 909 } 910 } 911 912 /* Restore coredumpsize resource limit. */ 913#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) 914 (void) setrlimit(RLIMIT_CORE, &corelimit); 915#endif /* RLIMIT_CORE && !SUDO_DEVEL */ 916 917 if (ISSET(sudo_mode, MODE_RUN)) 918 set_perms(PERM_FULL_RUNAS); 919 920 if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) { 921 /* Change to target user's homedir. */ 922 if (chdir(runas_pw->pw_dir) == -1) { 923 warning("unable to change directory to %s", runas_pw->pw_dir); 924 goto done; 925 } 926 } 927 928 /* 929 * Restore nproc resource limit if pam_limits didn't do it for us. 930 * We must do this *after* the uid change to avoid potential EAGAIN 931 * from setuid(). 932 */ 933#if defined(__linux__) 934 { 935 struct rlimit rl; 936 if (getrlimit(RLIMIT_NPROC, &rl) == 0) { 937 if (rl.rlim_cur == RLIM_INFINITY && rl.rlim_max == RLIM_INFINITY) 938 (void) setrlimit(RLIMIT_NPROC, &nproclimit); 939 } 940 } 941#endif 942 943 /* Close the password and group files and free up memory. */ 944 sudo_endpwent(); 945 sudo_endgrent(); 946 pw_delref(sudo_user.pw); 947 pw_delref(runas_pw); 948 if (runas_gr != NULL) 949 gr_delref(runas_gr); 950 951 rval = TRUE; 952 953done: 954 return rval; 955} 956 957/* 958 * Run the command and wait for it to complete. 959 */ 960int 961run_command(path, argv, envp, uid, dowait) 962 const char *path; 963 char *argv[]; 964 char *envp[]; 965 uid_t uid; 966 int dowait; 967{ 968 struct command_status cstat; 969 int exitcode = 1; 970 971#ifdef PROFILING 972 exit(0); 973#endif 974 975 cstat.type = CMD_INVALID; 976 cstat.val = 0; 977 978 sudo_execve(path, argv, envp, uid, &cstat, dowait, 979 ISSET(sudo_mode, MODE_BACKGROUND)); 980 981 switch (cstat.type) { 982 case CMD_ERRNO: 983 /* exec_setup() or execve() returned an error. */ 984 warningx("unable to execute %s: %s", path, strerror(cstat.val)); 985 exitcode = 127; 986 break; 987 case CMD_WSTATUS: 988 /* Command ran, exited or was killed. */ 989 if (WIFEXITED(cstat.val)) 990 exitcode = WEXITSTATUS(cstat.val); 991 else if (WIFSIGNALED(cstat.val)) 992 exitcode = WTERMSIG(cstat.val) | 128; 993 break; 994 default: 995 warningx("unexpected child termination condition: %d", cstat.type); 996 break; 997 } 998#ifdef HAVE_PAM 999 pam_end_session(runas_pw); 1000#endif /* HAVE_PAM */ 1001#ifdef _PATH_SUDO_IO_LOGDIR 1002 io_log_close(); 1003#endif 1004 sudo_endpwent(); 1005 sudo_endgrent(); 1006 pw_delref(sudo_user.pw); 1007 pw_delref(runas_pw); 1008 if (runas_gr != NULL) 1009 gr_delref(runas_gr); 1010 return exitcode; 1011} 1012 1013/* 1014 * Open sudoers and sanity check mode/owner/type. 1015 * Returns a handle to the sudoers file or NULL on error. 1016 */ 1017FILE * 1018open_sudoers(sudoers, doedit, keepopen) 1019 const char *sudoers; 1020 int doedit; 1021 int *keepopen; 1022{ 1023 struct stat sb; 1024 FILE *fp = NULL; 1025 1026 set_perms(PERM_SUDOERS); 1027 1028 switch (sudo_secure_file(sudoers, SUDOERS_UID, SUDOERS_GID, &sb)) { 1029 case SUDO_PATH_SECURE: 1030 /* 1031 * If we are expecting sudoers to be group readable but 1032 * it is not, we must open the file as root, not uid 1. 1033 */ 1034 if (SUDOERS_UID == ROOT_UID && (SUDOERS_MODE & S_IRGRP)) { 1035 if ((sb.st_mode & S_IRGRP) == 0) 1036 set_perms(PERM_ROOT); 1037 } 1038 /* 1039 * Open sudoers and make sure we can read it so we can present 1040 * the user with a reasonable error message (unlike the lexer). 1041 */ 1042 if ((fp = fopen(sudoers, "r")) == NULL) { 1043 log_error(USE_ERRNO, "unable to open %s", sudoers); 1044 } else { 1045 if (sb.st_size != 0 && fgetc(fp) == EOF) { 1046 log_error(USE_ERRNO, "unable to read %s", 1047 sudoers); 1048 fclose(fp); 1049 fp = NULL; 1050 } else { 1051 /* Rewind fp and set close on exec flag. */ 1052 rewind(fp); 1053 (void) fcntl(fileno(fp), F_SETFD, 1); 1054 } 1055 } 1056 break; 1057 case SUDO_PATH_MISSING: 1058 log_error(USE_ERRNO, "unable to stat %s", sudoers); 1059 break; 1060 case SUDO_PATH_BAD_TYPE: 1061 log_error(0, "%s is not a regular file", sudoers); 1062 break; 1063 case SUDO_PATH_WRONG_OWNER: 1064 log_error(0, "%s is owned by uid %u, should be %u", 1065 sudoers, (unsigned int) sb.st_uid, (unsigned int) SUDOERS_UID); 1066 break; 1067 case SUDO_PATH_WORLD_WRITABLE: 1068 log_error(0, "%s is world writable", sudoers); 1069 break; 1070 case SUDO_PATH_GROUP_WRITABLE: 1071 log_error(0, "%s is owned by gid %u, should be %u", 1072 sudoers, (unsigned int) sb.st_gid, (unsigned int) SUDOERS_GID); 1073 break; 1074 default: 1075 /* NOTREACHED */ 1076 break; 1077 } 1078 1079 set_perms(PERM_ROOT); /* change back to root */ 1080 1081 return fp; 1082} 1083 1084static void 1085sudo_check_suid(path) 1086 const char *path; 1087{ 1088 struct stat sb; 1089 1090 if (geteuid() != 0) { 1091 if (strchr(path, '/') != NULL && stat(path, &sb) == 0) { 1092 /* Try to determine why sudo was not running as root. */ 1093 if (sb.st_uid != ROOT_UID || !ISSET(sb.st_mode, S_ISUID)) { 1094 errorx(1, 1095 "%s must be owned by uid %d and have the setuid bit set", 1096 path, ROOT_UID); 1097 } else { 1098 errorx(1, "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?", ROOT_UID, path); 1099 } 1100 } else { 1101 errorx(1, "effective uid is not %d, is sudo installed setuid root?", 1102 ROOT_UID); 1103 } 1104 } 1105} 1106 1107/* 1108 * Close all open files (except std*) and turn off core dumps. 1109 * Also sets the set_perms() pointer to the correct function. 1110 */ 1111static void 1112initial_setup() 1113{ 1114 int miss[3], devnull = -1; 1115 sigset_t mask; 1116#if defined(__linux__) || (defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)) 1117 struct rlimit rl; 1118#endif 1119 1120 /* Reset signal mask and save signal state. */ 1121 (void) sigemptyset(&mask); 1122 (void) sigprocmask(SIG_SETMASK, &mask, NULL); 1123 1124#if defined(__linux__) 1125 /* 1126 * Unlimit the number of processes since Linux's setuid() will 1127 * apply resource limits when changing uid and return EAGAIN if 1128 * nproc would be violated by the uid switch. 1129 */ 1130 (void) getrlimit(RLIMIT_NPROC, &nproclimit); 1131 rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; 1132 if (setrlimit(RLIMIT_NPROC, &rl)) { 1133 memcpy(&rl, &nproclimit, sizeof(struct rlimit)); 1134 rl.rlim_cur = rl.rlim_max; 1135 (void)setrlimit(RLIMIT_NPROC, &rl); 1136 } 1137#endif /* __linux__ */ 1138#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) 1139 /* 1140 * Turn off core dumps. 1141 */ 1142 (void) getrlimit(RLIMIT_CORE, &corelimit); 1143 memcpy(&rl, &corelimit, sizeof(struct rlimit)); 1144 rl.rlim_cur = 0; 1145 (void) setrlimit(RLIMIT_CORE, &rl); 1146#endif /* RLIMIT_CORE && !SUDO_DEVEL */ 1147 1148 /* 1149 * stdin, stdout and stderr must be open; set them to /dev/null 1150 * if they are closed and close all other fds. 1151 */ 1152 miss[STDIN_FILENO] = fcntl(STDIN_FILENO, F_GETFL, 0) == -1; 1153 miss[STDOUT_FILENO] = fcntl(STDOUT_FILENO, F_GETFL, 0) == -1; 1154 miss[STDERR_FILENO] = fcntl(STDERR_FILENO, F_GETFL, 0) == -1; 1155 if (miss[STDIN_FILENO] || miss[STDOUT_FILENO] || miss[STDERR_FILENO]) { 1156 if ((devnull = open(_PATH_DEVNULL, O_RDWR, 0644)) == -1) 1157 error(1, "unable to open %s", _PATH_DEVNULL); 1158 if (miss[STDIN_FILENO] && dup2(devnull, STDIN_FILENO) == -1) 1159 error(1, "dup2"); 1160 if (miss[STDOUT_FILENO] && dup2(devnull, STDOUT_FILENO) == -1) 1161 error(1, "dup2"); 1162 if (miss[STDERR_FILENO] && dup2(devnull, STDERR_FILENO) == -1) 1163 error(1, "dup2"); 1164 if (devnull > STDERR_FILENO) 1165 close(devnull); 1166 } 1167} 1168 1169#ifdef HAVE_LOGIN_CAP_H 1170static void 1171set_loginclass(pw) 1172 struct passwd *pw; 1173{ 1174 const int errflags = NO_MAIL|MSG_ONLY; 1175 1176 if (!def_use_loginclass) 1177 return; 1178 1179 if (login_class && strcmp(login_class, "-") != 0) { 1180 if (user_uid != 0 && 1181 strcmp(runas_user ? runas_user : def_runas_default, "root") != 0) 1182 errorx(1, "only root can use -c %s", login_class); 1183 } else { 1184 login_class = pw->pw_class; 1185 if (!login_class || !*login_class) 1186 login_class = 1187 (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS; 1188 } 1189 1190 /* Make sure specified login class is valid. */ 1191 lc = login_getclass(login_class); 1192 if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) { 1193 /* 1194 * Don't make it a fatal error if the user didn't specify the login 1195 * class themselves. We do this because if login.conf gets 1196 * corrupted we want the admin to be able to use sudo to fix it. 1197 */ 1198 if (login_class) 1199 log_fatal(errflags, "unknown login class: %s", login_class); 1200 else 1201 log_error(errflags, "unknown login class: %s", login_class); 1202 def_use_loginclass = FALSE; 1203 } 1204} 1205#else 1206static void 1207set_loginclass(pw) 1208 struct passwd *pw; 1209{ 1210} 1211#endif /* HAVE_LOGIN_CAP_H */ 1212 1213#ifndef AI_FQDN 1214# define AI_FQDN AI_CANONNAME 1215#endif 1216 1217/* 1218 * Look up the fully qualified domain name and set user_host and user_shost. 1219 */ 1220void 1221set_fqdn() 1222{ 1223#ifdef HAVE_GETADDRINFO 1224 struct addrinfo *res0, hint; 1225#else 1226 struct hostent *hp; 1227#endif 1228 char *p; 1229 1230#ifdef HAVE_GETADDRINFO 1231 zero_bytes(&hint, sizeof(hint)); 1232 hint.ai_family = PF_UNSPEC; 1233 hint.ai_flags = AI_FQDN; 1234 if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) { 1235#else 1236 if (!(hp = gethostbyname(user_host))) { 1237#endif 1238 log_error(MSG_ONLY, "unable to resolve host %s", user_host); 1239 } else { 1240 if (user_shost != user_host) 1241 efree(user_shost); 1242 efree(user_host); 1243#ifdef HAVE_GETADDRINFO 1244 user_host = estrdup(res0->ai_canonname); 1245 freeaddrinfo(res0); 1246#else 1247 user_host = estrdup(hp->h_name); 1248#endif 1249 if ((p = strchr(user_host, '.'))) { 1250 *p = '\0'; 1251 user_shost = estrdup(user_host); 1252 *p = '.'; 1253 } else { 1254 user_shost = user_host; 1255 } 1256 } 1257} 1258 1259/* 1260 * Get passwd entry for the user we are going to run commands as 1261 * and store it in runas_pw. By default, commands run as "root". 1262 */ 1263void 1264set_runaspw(user) 1265 const char *user; 1266{ 1267 if (runas_pw != NULL) 1268 pw_delref(runas_pw); 1269 if (*user == '#') { 1270 if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL) 1271 runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); 1272 } else { 1273 if ((runas_pw = sudo_getpwnam(user)) == NULL) { 1274 audit_failure(NewArgv, "unknown user: %s", user); 1275 log_fatal(NO_MAIL|MSG_ONLY, "unknown user: %s", user); 1276 } 1277 } 1278} 1279 1280/* 1281 * Get group entry for the group we are going to run commands as 1282 * and store it in runas_gr. 1283 */ 1284static void 1285set_runasgr(group) 1286 const char *group; 1287{ 1288 if (runas_gr != NULL) 1289 gr_delref(runas_gr); 1290 if (*group == '#') { 1291 if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL) 1292 runas_gr = sudo_fakegrnam(group); 1293 } else { 1294 if ((runas_gr = sudo_getgrnam(group)) == NULL) 1295 log_fatal(NO_MAIL|MSG_ONLY, "unknown group: %s", group); 1296 } 1297} 1298 1299/* 1300 * Callback for runas_default sudoers setting. 1301 */ 1302static int 1303cb_runas_default(user) 1304 const char *user; 1305{ 1306 /* Only reset runaspw if user didn't specify one. */ 1307 if (!runas_user && !runas_group) 1308 set_runaspw(user); 1309 return TRUE; 1310} 1311 1312/* 1313 * Cleanup hook for error()/errorx() 1314 */ 1315void 1316cleanup(gotsignal) 1317 int gotsignal; 1318{ 1319 struct sudo_nss *nss; 1320 1321 if (!gotsignal) { 1322 if (snl != NULL) { 1323 tq_foreach_fwd(snl, nss) 1324 nss->close(nss); 1325 } 1326#ifdef USING_NONUNIX_GROUPS 1327 sudo_nonunix_groupcheck_cleanup(); 1328#endif 1329 sudo_endpwent(); 1330 sudo_endgrent(); 1331#ifdef _PATH_SUDO_IO_LOGDIR 1332 io_log_close(); 1333#endif 1334 } 1335#ifdef _PATH_SUDO_IO_LOGDIR 1336 cleanup_pty(gotsignal); 1337#endif 1338#ifdef HAVE_SELINUX 1339 selinux_restore_tty(); 1340#endif 1341} 1342 1343static void 1344show_version() 1345{ 1346 (void) printf("Sudo version %s\n", PACKAGE_VERSION); 1347 if (getuid() == 0) { 1348 putchar('\n'); 1349 (void) printf("Configure args: %s\n", CONFIGURE_ARGS); 1350 (void) printf("Sudoers path: %s\n", _PATH_SUDOERS); 1351#ifdef HAVE_LDAP 1352# ifdef _PATH_NSSWITCH_CONF 1353 (void) printf("nsswitch path: %s\n", _PATH_NSSWITCH_CONF); 1354# endif 1355 (void) printf("ldap.conf path: %s\n", _PATH_LDAP_CONF); 1356 (void) printf("ldap.secret path: %s\n", _PATH_LDAP_SECRET); 1357#endif 1358 dump_auth_methods(); 1359 dump_defaults(); 1360 dump_interfaces(); 1361 } 1362 exit(0); 1363} 1364 1365#ifdef USE_ADMIN_FLAG 1366static void 1367create_admin_success_flag() 1368{ 1369 struct stat statbuf; 1370 char flagfile[PATH_MAX]; 1371 int fd, n; 1372 1373 /* Check whether the user is in the admin group. */ 1374 if (!user_in_group(sudo_user.pw, "admin")) 1375 return; 1376 1377 /* Build path to flag file. */ 1378 n = snprintf(flagfile, sizeof(flagfile), "%s/.sudo_as_admin_successful", 1379 user_dir); 1380 if (n <= 0 || n >= sizeof(flagfile)) 1381 return; 1382 1383 /* Create admin flag file if it doesn't already exist. */ 1384 set_perms(PERM_USER); 1385 if (stat(flagfile, &statbuf) == 0) { 1386 set_perms(PERM_ROOT); 1387 return; 1388 } 1389 1390 fd = open(flagfile, O_CREAT|O_WRONLY|O_EXCL, 0644); 1391 close(fd); 1392 set_perms(PERM_ROOT); 1393} 1394#else /* !USE_ADMIN_FLAG */ 1395static void 1396create_admin_success_flag() 1397{ 1398 /* STUB */ 1399} 1400#endif /* USE_ADMIN_FLAG */ 1401