Patch for Debian bug #74176 Add support to pam_limits for setting capabilities via limits.conf. Authors: Topi Miettinen , Steve Langasek Upstream status: not yet submitted Index: Linux-PAM/configure.in =================================================================== --- Linux-PAM/configure.in.orig +++ Linux-PAM/configure.in @@ -385,11 +385,14 @@ AC_DEFINE([WITH_SELINUX], 1, [Defined if SE Linux support is compiled in]) fi +AC_CHECK_LIB([cap], [cap_init], LIBCAP="-lcap", LIBCAP="") +AC_SUBST(LIBCAP) + dnl Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/file.h sys/ioctl.h sys/time.h syslog.h net/if.h termio.h unistd.h sys/fsuid.h inittypes.h) +AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/file.h sys/ioctl.h sys/time.h syslog.h net/if.h termio.h unistd.h sys/fsuid.h inittypes.h sys/capability.h) AC_CHECK_HEADERS(crypt.h) Index: Linux-PAM/modules/pam_limits/pam_limits.c =================================================================== --- Linux-PAM/modules/pam_limits/pam_limits.c.orig +++ Linux-PAM/modules/pam_limits/pam_limits.c @@ -19,6 +19,10 @@ #include "config.h" +#ifdef HAVE_SYS_CAPABILITY_H +#include +#include +#endif /* HAVE_SYS_CAPABILITY_H */ #include #include #include @@ -76,6 +80,9 @@ specific user or to count all logins */ int priority; /* the priority to run user process with */ char chroot_dir[8092]; /* directory to chroot into */ +#ifdef HAVE_SYS_CAPABILITY_H + cap_t capabilities; /* capability handle */ +#endif /* HAVE_SYS_CAPABILITY_H */ struct user_limits_struct limits[RLIM_NLIMITS]; char conf_file[BUFSIZ]; int utmp_after_pam_call; @@ -87,6 +94,7 @@ #define LIMIT_PRI RLIM_NLIMITS+3 #define LIMIT_CHROOT RLIM_NLIMITS+4 +#define LIMIT_CAPS RLIM_NLIMITS+5 #define LIMIT_SOFT 1 #define LIMIT_HARD 2 @@ -274,6 +282,9 @@ pl->login_limit = -2; pl->login_limit_def = LIMITS_DEF_NONE; +#ifdef HAVE_SYS_CAPABILITY_H + pl->capabilities = NULL; +#endif /* HAVE_SYS_CAPABILITY_H */ pl->chroot_dir[0] = '\0'; return retval; @@ -348,6 +359,10 @@ limit_item = LIMIT_PRI; } else if (strcmp(lim_item, "chroot") == 0) { limit_item = LIMIT_CHROOT; +#ifdef HAVE_SYS_CAPABILITY_H + } else if (strcmp(lim_item, "capabilities") == 0) { + limit_item = LIMIT_CAPS; +#endif /* HAVE_SYS_CAPABILITY_H */ } else { pam_syslog(pamh, LOG_DEBUG, "unknown limit item '%s'", lim_item); return; @@ -387,7 +402,7 @@ lim_value, lim_type); return; } - } else if (limit_item != LIMIT_CHROOT) { + } else if (limit_item != LIMIT_CHROOT && limit_item != LIMIT_CAPS) { #ifdef __USE_FILE_OFFSET64 rlimit_value = strtoull (lim_value, &endptr, 10); #else @@ -438,6 +453,14 @@ if (limit_item == LIMIT_CHROOT) strncpy(pl->chroot_dir, value_orig, sizeof(pl->chroot_dir)); +#ifdef HAVE_SYS_CAPABILITY_H + else if (limit_item == LIMIT_CAPS) { + if (pl->capabilities) + cap_free(pl->capabilities); + pl->capabilities = cap_from_text(value_orig); + prctl(PR_SET_KEEPCAPS, 1); + } +#endif else if ( (limit_item != LIMIT_LOGIN) && (limit_item != LIMIT_NUMSYSLOGINS) && (limit_item != LIMIT_PRI) ) { @@ -649,6 +672,11 @@ if (i != 0) retval = LIMIT_ERR; } +#ifdef HAVE_SYS_CAPABILITY_H + if (!retval && pl->capabilities != NULL) { + retval = cap_set_proc(pl->capabilities) ? LIMIT_ERR : 0; + } +#endif /* HAVE_SYS_CAPABILITY_H */ return retval; } @@ -693,10 +721,18 @@ retval = parse_config_file(pamh, pwd->pw_name, ctrl, &pl); if (retval == PAM_IGNORE) { D(("the configuration file has an applicable ' -' entry")); +#ifdef HAVE_SYS_CAPABILITY_H + if (pl.capabilities) + cap_free(pl.capabilities); +#endif return PAM_SUCCESS; } if (retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_WARNING, "error parsing the configuration file"); +#ifdef HAVE_SYS_CAPABILITY_H + if (pl.capabilities) + cap_free(pl.capabilities); +#endif return retval; } @@ -704,6 +740,10 @@ setreuid(pwd->pw_uid, -1); } retval = setup_limits(pamh, pwd->pw_name, pwd->pw_uid, ctrl, &pl); +#ifdef HAVE_SYS_CAPABILITY_H + if (pl.capabilities) + cap_free(pl.capabilities); +#endif if (retval & LOGIN_ERR) pam_error(pamh, _("Too many logins for '%s'."), pwd->pw_name); if (retval != LIMITED_OK) { Index: Linux-PAM/modules/pam_limits/Makefile.am =================================================================== --- Linux-PAM/modules/pam_limits/Makefile.am.orig +++ Linux-PAM/modules/pam_limits/Makefile.am @@ -26,9 +26,10 @@ secureconf_DATA = limits.conf +pam_limits_la_LIBADD = @LIBCAP@ + if ENABLE_REGENERATE_MAN noinst_DATA = README README: pam_limits.8.xml limits.conf.5.xml -include $(top_srcdir)/Make.xml.rules endif -