From: Sam Hartman Date: Mon, 11 Sep 2023 14:00:42 -0600 Subject: _modules_pam_limits_chroot =================================================================== --- modules/pam_limits/limits.conf | 2 ++ modules/pam_limits/limits.conf.5 | 5 +++++ modules/pam_limits/limits.conf.5.xml | 6 ++++++ modules/pam_limits/pam_limits.c | 25 ++++++++++++++++++++++--- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/modules/pam_limits/limits.conf b/modules/pam_limits/limits.conf index c6b058a..6b3865c 100644 --- a/modules/pam_limits/limits.conf +++ b/modules/pam_limits/limits.conf @@ -49,6 +49,7 @@ # - msgqueue - max memory used by POSIX message queues (bytes) # - nice - max nice priority allowed to raise to values: [-20, 19] # - rtprio - max realtime priority +# - chroot - change root to directory (Debian-specific) # # # @@ -60,6 +61,7 @@ #@faculty soft nproc 20 #@faculty hard nproc 50 #ftp hard nproc 0 +#ftp - chroot /ftp #@student - maxlogins 4 # End of file diff --git a/modules/pam_limits/limits.conf.5 b/modules/pam_limits/limits.conf.5 index 32c4b2f..ce0ca35 100644 --- a/modules/pam_limits/limits.conf.5 +++ b/modules/pam_limits/limits.conf.5 @@ -283,6 +283,11 @@ rtprio .RS 4 maximum realtime priority allowed for non\-privileged processes (Linux 2\&.6\&.12 and higher) .RE +.PP +\fBchroot\fR +.RS 4 +the directory to chroot the user to +.RE .RE .PP All items support the values diff --git a/modules/pam_limits/limits.conf.5.xml b/modules/pam_limits/limits.conf.5.xml index 9f2662a..f6f7d87 100644 --- a/modules/pam_limits/limits.conf.5.xml +++ b/modules/pam_limits/limits.conf.5.xml @@ -271,6 +271,12 @@ (Linux 2.6.12 and higher) + + + + the directory to chroot the user to + + diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c index 746c441..529d2fc 100644 --- a/modules/pam_limits/pam_limits.c +++ b/modules/pam_limits/pam_limits.c @@ -104,6 +104,7 @@ struct pam_limit_s { specific user or to count all logins */ int priority; /* the priority to run user process with */ int nonewprivs; /* whether to prctl(PR_SET_NO_NEW_PRIVS) */ + char chroot_dir[8092]; /* directory to chroot into */ struct user_limits_struct limits[RLIM_NLIMITS]; const char *conf_file; int utmp_after_pam_call; @@ -115,6 +116,7 @@ struct pam_limit_s { #define LIMIT_PRI RLIM_NLIMITS+3 #define LIMIT_NONEWPRIVS RLIM_NLIMITS+4 +#define LIMIT_CHROOT RLIM_NLIMITS+5 #define LIMIT_SOFT 1 #define LIMIT_HARD 2 @@ -570,6 +572,8 @@ static int init_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int ctrl) pl->login_limit = -2; pl->login_limit_def = LIMITS_DEF_NONE; + pl->chroot_dir[0] = '\0'; + return retval; } @@ -677,6 +681,8 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type, limit_item = LIMIT_PRI; } else if (strcmp(lim_item, "nonewprivs") == 0) { limit_item = LIMIT_NONEWPRIVS; + } else if (strcmp(lim_item, "chroot") == 0) { + limit_item = LIMIT_CHROOT; } else { pam_syslog(pamh, LOG_DEBUG, "unknown limit item '%s'", lim_item); return; @@ -726,9 +732,9 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type, pam_syslog(pamh, LOG_DEBUG, "wrong limit value '%s' for limit type '%s'", lim_value, lim_type); - return; + return; } - } else { + } else if (limit_item != LIMIT_CHROOT) { #ifdef __USE_FILE_OFFSET64 rlimit_value = strtoull (lim_value, &endptr, 10); #else @@ -803,7 +809,11 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type, break; } - if ( (limit_item != LIMIT_LOGIN) + if (limit_item == LIMIT_CHROOT) { + strncpy(pl->chroot_dir, value_orig, sizeof(pl->chroot_dir)-1); + pl->chroot_dir[sizeof(pl->chroot_dir)-1]='\0'; + } + else if ( (limit_item != LIMIT_LOGIN) && (limit_item != LIMIT_NUMSYSLOGINS) && (limit_item != LIMIT_PRI) && (limit_item != LIMIT_NONEWPRIVS) ) { @@ -1163,6 +1173,15 @@ static int setup_limits(pam_handle_t *pamh, } } + if (!retval && pl->chroot_dir[0]) { + i = chdir(pl->chroot_dir); + if (i == 0) + i = chroot(pl->chroot_dir); + if (i == 0) + i = chdir("/"); + if (i != 0) + retval = LIMIT_ERR; + } return retval; }