aboutsummaryrefslogtreecommitdiff
path: root/patches-applied/029_pam_limits_capabilities
blob: a064cc1ce12968c6b168878d8b4f60161cd0464a (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
Patch for Debian bug #74176

Add support to pam_limits for setting capabilities via limits.conf.

Authors: Topi Miettinen <Topi.Miettinen@nic.fi>,
         Steve Langasek <vorlon@debian.org>

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 <sys/capability.h>
+#include <sys/prctl.h>
+#endif /* HAVE_SYS_CAPABILITY_H */
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
@@ -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 '<domain> -' 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
-