# include <project.h>
# include <sys/task.h>
#endif
+#ifdef HAVE_SELINUX
+# include <selinux/selinux.h>
+#endif
#include "sudo.h"
#include "interfaces.h"
#include "version.h"
#ifndef lint
-__unused __unused static const char rcsid[] = "$Sudo: sudo.c,v 1.369.2.31 2007/09/13 23:06:51 millert Exp $";
+__unused __unused static const char rcsid[] = "$Sudo: sudo.c,v 1.369.2.39 2008/04/10 17:56:05 millert Exp $";
#endif /* lint */
/*
validated = sudo_ldap_check(pwflag);
/* Skip reading /etc/sudoers if LDAP told us to */
- if (def_ignore_local_sudoers); /* skips */
- else if (ISSET(validated, VALIDATE_OK) && !printmatches); /* skips */
- else if (ISSET(validated, VALIDATE_OK) && printmatches)
- {
- check_sudoers(); /* check mode/owner on _PATH_SUDOERS */
+ if (!def_ignore_local_sudoers) {
+ int v;
- /* User is found in LDAP and we want a list of all sudo commands the
- * user can do, so consult sudoers but throw away result.
- */
- sudoers_lookup(pwflag);
- }
- else
-#endif
- {
check_sudoers(); /* check mode/owner on _PATH_SUDOERS */
- /* Validate the user but don't search for pseudo-commands. */
- validated = sudoers_lookup(pwflag);
+ /* Local sudoers file overrides LDAP if we have a match. */
+ v = sudoers_lookup(pwflag);
+ if (validated == VALIDATE_ERROR || ISSET(v, VALIDATE_OK))
+ validated = v;
}
+#else
+ check_sudoers(); /* check mode/owner on _PATH_SUDOERS */
+
+ /* Validate the user but don't search for pseudo-commands. */
+ validated = sudoers_lookup(pwflag);
+#endif
if (safe_cmnd == NULL)
safe_cmnd = estrdup(user_cmnd);
#ifndef PROFILING
if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0)
exit(0);
- else
+ else {
+#ifdef HAVE_SELINUX
+ if (is_selinux_enabled() > 0 && user_role != NULL)
+ selinux_exec(user_role, user_type, NewArgv, environ,
+ ISSET(sudo_mode, MODE_LOGIN_SHELL));
+#endif
execve(safe_cmnd, NewArgv, environ);
+ }
#else
exit(0);
#endif /* PROFILING */
* "host" is the (possibly fully-qualified) hostname and
* "shost" is the unqualified form of the hostname.
*/
+ sudo_user.host_fqdn_queried = FALSE;
nohostname = gethostname(thost, sizeof(thost));
if (nohostname)
user_host = user_shost = "localhost";
/* Defer call to set_fqdn() until log_error() is safe. */
user_shost = user_host;
} else {
- if ((p = strchr(user_host, '.'))) {
- *p = '\0';
- user_shost = estrdup(user_host);
- *p = '.';
- } else {
- user_shost = user_host;
- }
+ user_shost = user_host;
}
}
#ifdef HAVE_GETGROUPS
if ((user_ngroups = getgroups(0, NULL)) > 0) {
- user_groups = emalloc2(user_ngroups, MAX(sizeof(gid_t), sizeof(int)));
+ user_groups = emalloc2(user_ngroups, sizeof(GETGROUPS_T));
if (getgroups(user_ngroups, user_groups) < 0)
log_error(USE_ERRNO|MSG_ONLY, "can't get group vector");
} else
while (NewArgc > 0) {
if (NewArgv[0][0] == '-') {
- if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0')
+ if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') {
warnx("please use single character options");
+ usage(1);
+ }
switch (NewArgv[0][1]) {
case 'p':
usage(1);
user_prompt = NewArgv[1];
+ def_passprompt_override = TRUE;
NewArgc--;
NewArgv++;
case 'E':
SET(rval, MODE_PRESERVE_ENV);
break;
+#ifdef HAVE_SELINUX
+ case 'r':
+ /* Must have an associated SELinux role. */
+ if (NewArgv[1] == NULL)
+ usage(1);
+
+ user_role = NewArgv[1];
+
+ NewArgc--;
+ NewArgv++;
+ break;
+ case 't':
+ /* Must have an associated SELinux type. */
+ if (NewArgv[1] == NULL)
+ usage(1);
+
+ user_type = NewArgv[1];
+
+ NewArgc--;
+ NewArgv++;
+ break;
+#endif
case '-':
NewArgc--;
NewArgv++;
initial_setup()
{
int miss[3], devnull = -1;
-#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
+#if defined(__linux__) || (defined(RLIMIT_CORE) && !defined(SUDO_DEVEL))
struct rlimit rl;
+#endif
+#if defined(__linux__)
+ /*
+ * Unlimit the number of processes since Linux's setuid() will
+ * apply resource limits when changing uid and return EAGAIN if
+ * nproc would be violated by the uid switch.
+ */
+ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_NPROC, &rl)) {
+ if (getrlimit(RLIMIT_NPROC, &rl) == 0) {
+ rl.rlim_cur = rl.rlim_max;
+ (void)setrlimit(RLIMIT_NPROC, &rl);
+ }
+ }
+#endif /* __linux__ */
+#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
/*
* Turn off core dumps.
*/
} else {
user_shost = user_host;
}
+ sudo_user.host_fqdn_queried = TRUE;
+}
+
+/*
+ * Get passwd entry for the user we are going to run commands as.
+ * By default, this is "root". Updates runas_pw as a side effect.
+ */
+int
+set_runaspw(user)
+ char *user;
+{
+ if (runas_pw != NULL) {
+ if (user_runas != &def_runas_default)
+ return(TRUE); /* don't override -u option */
+ efree(runas_pw);
+ }
+ if (*user == '#') {
+ runas_pw = sudo_getpwuid(atoi(user + 1));
+ if (runas_pw == NULL) {
+ runas_pw = emalloc(sizeof(struct passwd));
+ (void) memset((VOID *)runas_pw, 0, sizeof(struct passwd));
+ runas_pw->pw_uid = atoi(user + 1);
+ }
+ } else {
+ runas_pw = sudo_getpwnam(user);
+ if (runas_pw == NULL)
+ log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", user);
+ }
+ return(TRUE);
}
/*
#endif
#ifdef HAVE_LOGIN_CAP_H
" [-c class|-]",
+#endif
+#ifdef HAVE_SELINUX
+ " [-r role]",
#endif
" [-p prompt]",
+#ifdef HAVE_SELINUX
+ " [-t type]",
+#endif
" [-u username|#uid]",
" [VAR=value]",
" {-i | -s | <command>}",