aboutsummaryrefslogtreecommitdiff
path: root/debian/patches/008_modules_pam_limits_chroot
blob: ae7cc6bf4a5b947a272a5e7a9f734f0ba02c2984 (plain)
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;
 }