1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
From: Sam Hartman <hartmans@debian.org>
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.xml | 6 ++++++
modules/pam_limits/pam_limits.c | 26 ++++++++++++++++++++++----
3 files changed, 30 insertions(+), 4 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)
#
#<domain> <type> <item> <value>
#
@@ -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.xml b/modules/pam_limits/limits.conf.5.xml
index 803cb4e..348758a 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)</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>chroot</option></term>
+ <listitem>
+ <para>the directory to chroot the user to</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</listitem>
</varlistentry>
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
index 9f11927..f7487ba 100644
--- a/modules/pam_limits/pam_limits.c
+++ b/modules/pam_limits/pam_limits.c
@@ -108,6 +108,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;
@@ -116,9 +117,9 @@ struct pam_limit_s {
#define LIMIT_LOGIN (RLIM_NLIMITS+1)
#define LIMIT_NUMSYSLOGINS (RLIM_NLIMITS+2)
-
#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
@@ -653,6 +654,8 @@ static int init_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int ctrl)
pl->login_limit_def = LIMITS_DEF_NONE;
pl->login_group = NULL;
+ pl->chroot_dir[0] = '\0';
+
return retval;
}
@@ -763,6 +766,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;
@@ -812,9 +817,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
@@ -889,7 +894,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) ) {
@@ -1307,6 +1316,15 @@ static int setup_limits(pam_handle_t *pamh,
#endif
}
+ 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;
}
|