1 /*
2 * ProFTPD - FTP server daemon
3 * Copyright (c) 2013-2016 The ProFTPD Project team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 *
19 * As a special exemption, The ProFTPD Project team and other respective
20 * copyright holders give permission to link this program with OpenSSL, and
21 * distribute the resulting executable, without including the source code for
22 * OpenSSL in the source distribution.
23 */
24
25 /* Resource limits implementation */
26
27 #include "conf.h"
28
get_rlimit(int resource,rlim_t * current,rlim_t * max)29 static int get_rlimit(int resource, rlim_t *current, rlim_t *max) {
30 struct rlimit rlim;
31 int res;
32
33 if (current == NULL &&
34 max == NULL) {
35 errno = EINVAL;
36 return -1;
37 }
38
39 res = getrlimit(resource, &rlim);
40 if (res < 0) {
41 /* Some libcs use EPERM instead of ENOSYS; weird. */
42 if (errno == EPERM) {
43 errno = ENOSYS;
44 }
45
46 return res;
47 }
48
49 if (current != NULL) {
50 *current = rlim.rlim_cur;
51 }
52
53 if (max != NULL) {
54 *max = rlim.rlim_max;
55 }
56
57 return 0;
58 }
59
set_rlimit(int resource,rlim_t current,rlim_t max)60 static int set_rlimit(int resource, rlim_t current, rlim_t max) {
61 struct rlimit rlim;
62 int res;
63
64 rlim.rlim_cur = current;
65 rlim.rlim_max = max;
66
67 res = setrlimit(resource, &rlim);
68 return res;
69 }
70
pr_rlimit_get_core(rlim_t * current,rlim_t * max)71 int pr_rlimit_get_core(rlim_t *current, rlim_t *max) {
72 #if defined(RLIMIT_CORE)
73 return get_rlimit(RLIMIT_CORE, current, max);
74
75 #else
76 errno = ENOSYS;
77 return -1;
78 #endif /* No RLIMIT_CORE */
79 }
80
pr_rlimit_set_core(rlim_t current,rlim_t max)81 int pr_rlimit_set_core(rlim_t current, rlim_t max) {
82 #if defined(RLIMIT_CORE)
83 return set_rlimit(RLIMIT_CORE, current, max);
84
85 #else
86 errno = ENOSYS;
87 return -1;
88 #endif /* No RLIMIT_CORE */
89 }
90
pr_rlimit_get_cpu(rlim_t * current,rlim_t * max)91 int pr_rlimit_get_cpu(rlim_t *current, rlim_t *max) {
92 #if defined(RLIMIT_CPU)
93 return get_rlimit(RLIMIT_CPU, current, max);
94
95 #else
96 errno = ENOSYS;
97 return -1;
98 #endif /* No RLIMIT_CPU */
99 }
100
pr_rlimit_set_cpu(rlim_t current,rlim_t max)101 int pr_rlimit_set_cpu(rlim_t current, rlim_t max) {
102 #if defined(RLIMIT_CPU)
103 return set_rlimit(RLIMIT_CPU, current, max);
104
105 #else
106 errno = ENOSYS;
107 return -1;
108 #endif /* No RLIMIT_CPU */
109 }
110
pr_rlimit_get_files(rlim_t * current,rlim_t * max)111 int pr_rlimit_get_files(rlim_t *current, rlim_t *max) {
112 #if defined(RLIMIT_NOFILE)
113 return get_rlimit(RLIMIT_NOFILE, current, max);
114
115 #elif defined(RLIMIT_OFILE)
116 return get_rlimit(RLIMIT_OFILE, current, max);
117
118 #else
119 errno = ENOSYS;
120 return -1;
121 #endif /* No RLIMIT_NOFILE or RLIMIT_OFILE */
122 }
123
pr_rlimit_set_files(rlim_t current,rlim_t max)124 int pr_rlimit_set_files(rlim_t current, rlim_t max) {
125 #if defined(RLIMIT_NOFILE)
126 return set_rlimit(RLIMIT_NOFILE, current, max);
127
128 #elif defined(RLIMIT_OFILE)
129 return set_rlimit(RLIMIT_OFILE, current, max);
130
131 #else
132 errno = ENOSYS;
133 return -1;
134 #endif /* No RLIMIT_NOFILE or RLIMIT_OFILE */
135 }
136
pr_rlimit_get_memory(rlim_t * current,rlim_t * max)137 int pr_rlimit_get_memory(rlim_t *current, rlim_t *max) {
138 #if defined(RLIMIT_AS)
139 return get_rlimit(RLIMIT_AS, current, max);
140
141 #elif defined(RLIMIT_DATA)
142 return get_rlimit(RLIMIT_DATA, current, max);
143
144 #elif defined(RLIMIT_VMEM)
145 return get_rlimit(RLIMIT_VMEM, current, max);
146
147 #else
148 errno = ENOSYS;
149 return -1;
150 #endif /* No RLIMIT_AS, RLIMIT_DATA, or RLIMIT_VMEM. */
151 }
152
pr_rlimit_set_memory(rlim_t current,rlim_t max)153 int pr_rlimit_set_memory(rlim_t current, rlim_t max) {
154 #if defined(RLIMIT_AS)
155 return set_rlimit(RLIMIT_AS, current, max);
156
157 #elif defined(RLIMIT_DATA)
158 return set_rlimit(RLIMIT_DATA, current, max);
159
160 #else
161 errno = ENOSYS;
162 return -1;
163 #endif /* No RLIMIT_AS or RLIMIT_DATA */
164 }
165
pr_rlimit_get_nproc(rlim_t * current,rlim_t * max)166 int pr_rlimit_get_nproc(rlim_t *current, rlim_t *max) {
167 #if defined(RLIMIT_NPROC)
168 return get_rlimit(RLIMIT_NPROC, current, max);
169
170 #else
171 errno = ENOSYS;
172 return -1;
173 #endif /* No RLIMIT_NPROC */
174 }
175
pr_rlimit_set_nproc(rlim_t current,rlim_t max)176 int pr_rlimit_set_nproc(rlim_t current, rlim_t max) {
177 #if defined(RLIMIT_NPROC)
178 return set_rlimit(RLIMIT_NPROC, current, max);
179
180 #else
181 errno = ENOSYS;
182 return -1;
183 #endif /* No RLIMIT_NPROC */
184 }
185
186