summaryrefslogtreecommitdiff
path: root/debian/patches-applied/027_pam_limits_better_init_allow_explicit_root
blob: f12ead7c0ac638f4f19bd09fa10965db31a1b286 (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
Allow explicit limits for root.
Also, remove limits on su.
Index: pam.deb/modules/pam_limits/pam_limits.c
===================================================================
--- pam.deb.orig/modules/pam_limits/pam_limits.c
+++ pam.deb/modules/pam_limits/pam_limits.c
@@ -55,6 +55,10 @@
 #define LIMITS_DEF_DEFAULT  4 /* limit was set by an default entry */
 #define LIMITS_DEF_NONE     5 /* this limit was not set yet */
 
+/* file in /proc on Linux that we read to get the total number of open
+   files allowed on the system */
+#define NR_OPEN_FILES "/proc/sys/fs/nr_open"
+
 static const char *limits_def_names[] = {
        "USER",
        "GROUP",
@@ -74,6 +78,7 @@
 
 /* internal data */
 struct pam_limit_s {
+    int root;            /* running as root? */
     int login_limit;     /* the max logins limit */
     int login_limit_def; /* which entry set the login limit */
     int flag_numsyslogins; /* whether to limit logins only for a
@@ -228,9 +233,25 @@
 {
     int i;
     int retval = PAM_SUCCESS;
+    static rlim_t nofiles_max = RLIM_INFINITY;
+    static int nofiles_init = 0;
 
     D(("called."));
 
+    if (nofiles_init == 0) {
+	FILE *nr_open;
+	unsigned long long ull_nofiles = 0;
+
+	nofiles_init = 1;
+	nr_open = fopen(NR_OPEN_FILES, "r");
+	if (nr_open != NULL) {
+	    if (fscanf(nr_open, "%Lu", &ull_nofiles) == 1)
+		nofiles_max = ull_nofiles;
+	    fclose(nr_open);
+	}
+    }
+
+    pl->root = 0;
     for(i = 0; i < RLIM_NLIMITS; i++) {
 	int r = getrlimit(i, &pl->limits[i].limit);
 	if (r == -1) {
@@ -242,6 +263,41 @@
 	    pl->limits[i].supported = 1;
 	    pl->limits[i].src_soft = LIMITS_DEF_NONE;
 	    pl->limits[i].src_hard = LIMITS_DEF_NONE;
+	    switch(i) {
+		case RLIMIT_CPU:
+		case RLIMIT_FSIZE:
+		case RLIMIT_DATA:
+		case RLIMIT_RSS:
+		case RLIMIT_NPROC:
+		case RLIMIT_MEMLOCK:
+#ifdef RLIMIT_AS
+		case RLIMIT_AS:
+#endif
+#ifdef RLIMIT_LOCKS
+		case RLIMIT_LOCKS:
+#endif
+#ifdef RLIMIT_SIGPENDING
+		case RLIMIT_SIGPENDING:
+#endif
+#ifdef RLIMIT_MSGQUEUE
+		case RLIMIT_MSGQUEUE:
+#endif
+		    pl->limits[i].limit.rlim_cur = RLIM_INFINITY;
+		    pl->limits[i].limit.rlim_max = RLIM_INFINITY;
+		    break;
+		case RLIMIT_CORE:
+		    pl->limits[i].limit.rlim_cur = 0;
+		    pl->limits[i].limit.rlim_max = RLIM_INFINITY;
+		    break;
+		case RLIMIT_STACK:
+		    pl->limits[i].limit.rlim_cur = 8192*1024;
+		    pl->limits[i].limit.rlim_max = RLIM_INFINITY;
+		    break;
+		case RLIMIT_NOFILE:
+		    pl->limits[i].limit.rlim_cur = 1024;
+		    pl->limits[i].limit.rlim_max = nofiles_max;
+		    break;
+	    }
 	}
     }
 
@@ -524,7 +580,7 @@
 
             if (strcmp(uname, domain) == 0) /* this user have a limit */
                 process_limit(pamh, LIMITS_DEF_USER, ltype, item, value, ctrl, pl);
-            else if (domain[0]=='@') {
+            else if (domain[0]=='@' && !pl->root) {
 		    if (ctrl & PAM_DEBUG_ARG) {
 			pam_syslog(pamh, LOG_DEBUG,
 				   "checking if %s is in group %s",
@@ -533,7 +589,7 @@
                 if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1))
                     process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl,
 				  pl);
-            } else if (domain[0]=='%') {
+            } else if (domain[0]=='%' && !pl->root) {
 		    if (ctrl & PAM_DEBUG_ARG) {
 			pam_syslog(pamh, LOG_DEBUG,
 				   "checking if %s is in group %s",
@@ -547,7 +603,7 @@
                     process_limit(pamh, LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl,
 				  pl);
 		}
-            } else if (strcmp(domain, "*") == 0)
+            } else if (strcmp(domain, "*") == 0 && !pl->root)
                 process_limit(pamh, LIMITS_DEF_DEFAULT, ltype, item, value, ctrl,
 			      pl);
 	} else if (i == 2 && ltype[0] == '-') { /* Probably a no-limit line */
@@ -582,6 +638,12 @@
     int status;
     int retval = LIMITED_OK;
 
+    if (uid == 0) {
+        /* do not impose +ve priority limits on the superuser */
+        if (pl->priority > 0)
+            pl->priority = 0;
+    }
+
     for (i=0, status=LIMITED_OK; i<RLIM_NLIMITS; i++) {
 	if (!pl->limits[i].supported) {
 	    /* skip it if its not known to the system */
@@ -675,6 +737,8 @@
         return PAM_ABORT;
     }
 
+    if (pwd->pw_uid == 0)
+        pl->root = 1;
     retval = parse_config_file(pamh, pwd->pw_name, ctrl, pl);
     if (retval == PAM_IGNORE) {
 	D(("the configuration file ('%s') has an applicable '<domain> -' entry", CONF_FILE));