1 /* This file is part of GNU Rush.
2    Copyright (C) 2008-2019 Sergey Poznyakoff
3 
4    GNU Rush is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    GNU Rush is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with GNU Rush.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <errno.h>
24 #include <pwd.h>
25 #include <grp.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/time.h>
30 #include <sys/wait.h>
31 #include <sys/resource.h>
32 #include <syslog.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <signal.h>
36 #include <getopt.h>
37 #include <ctype.h>
38 
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <sys/un.h>
42 #include <netdb.h>
43 #include <arpa/inet.h>
44 
45 #include <xalloc.h>
46 #include <regex.h>
47 #include <c-ctype.h>
48 #include <inttostr.h>
49 
50 #include <defines.h>
51 #include <librush.h>
52 #include <wordsplit.h>
53 
54 #ifndef SYSCONFDIR
55 # define SYSCONFDIR "/usr/local/etc"
56 #endif
57 #define CONFIG_FILE SYSCONFDIR "/rush.rc"
58 #ifndef CANONICAL_PROGRAM_NAME
59 # define CANONICAL_PROGRAM_NAME "/usr/local/sbin/rush"
60 #endif
61 
62 #define RUSH_DB LOCALSTATEDIR "/rush"
63 
64 #if defined HAVE_SYSCONF && defined _SC_OPEN_MAX
65 # define getmaxfd() sysconf(_SC_OPEN_MAX)
66 #elif defined (HAVE_GETDTABLESIZE)
67 # define getmaxfd() getdtablesize()
68 #else
69 # define getmaxfd() 256
70 #endif
71 
72 #ifndef LOG_AUTHPRIV
73 # define LOG_AUTHPRIV LOG_AUTH
74 #endif
75 
76 #define ISWS(c) ((c) == ' ' || (c) == '\t')
77 
78 enum error_type {
79 	usage_error,
80 	nologin_error,
81 	config_error,
82 	system_error
83 };
84 
85 typedef struct limits_rec *limits_record_t;
86 typedef struct transform *transform_t;
87 
88 struct rush_map {
89 	char *file;
90 	char *delim;
91 	char *key;
92 	unsigned key_field;
93 	unsigned val_field;
94 	char *defval;
95 };
96 
97 enum transform_target_type {
98 	target_readonly,     /* Read-only variable */
99 	target_command,      /* Command line */
100 	target_program,      /* Executable program name */
101 	target_arg,          /* Single command line argument */
102 	target_var,          /* Variable */
103 	target_env           /* Environment variable */
104 };
105 
106 struct transform_target {
107 	enum transform_target_type type;
108 	union {
109 		char *name;
110 		struct {
111 			int idx;
112 			int ins;
113 		} arg;
114 	} v;
115 };
116 
117 enum transform_node_type {
118 	transform_set,
119 	transform_delete,
120 	transform_map,
121 	transform_remopt,
122 };
123 
124 struct option_defn {
125 	char *s_opt;  /* short option name with optional argument designator */
126 	char *l_opt;    /* optional long option name */
127 };
128 
129 struct transform_node {
130 	struct transform_node *next;
131 	enum transform_node_type type;
132 	struct transform_target target;
133 	union {
134 		struct {
135 			char *pattern;
136 			transform_t trans;
137 		} xf;
138 		struct rush_map map;    /* For transform_map */
139 		int arg_end;            /* For tranform_delete, if target.type
140 					   is target_arg */
141 		struct option_defn remopt; /* For transform_remopt */
142 	} v;
143 };
144 
145 enum test_type {
146 	test_cmpn,
147 	test_cmps,
148 	test_in,
149 	test_group,
150 	test_and,
151 	test_or,
152 	test_not
153 };
154 
155 enum cmp_op {
156 	cmp_eq,
157 	cmp_ne,
158 	cmp_lt,
159 	cmp_le,
160 	cmp_gt,
161 	cmp_ge,
162 	cmp_match,
163 	cmp_in
164 };
165 
166 typedef unsigned long rush_num_t;
167 
168 struct test_node {
169 	enum test_type type;
170 	union {
171 		struct {
172 			enum cmp_op op;
173 			char *larg;
174 			union {
175 				char *str;
176 				char **strv;
177 				regex_t rx;
178 				rush_num_t num;
179 			} rarg;
180 		} cmp;
181 		char **groups;
182 		struct test_node *arg[2];
183 	} v;
184 };
185 
186 struct rush_sockaddr {
187 	socklen_t len;
188 	struct sockaddr *sa;
189 };
190 
191 enum rush_three_state { rush_undefined = -1, rush_false, rush_true };
192 typedef enum rush_three_state rush_bool_t;
193 
194 struct rush_i18n {
195 	char *text_domain;           /* Gettext domain, if any */
196 	char *localedir;             /* Locale directory, if any */
197 	char *locale;
198 };
199 
200 struct rush_error {     /* Rush error object */
201 	int fd;         /* File descriptor to write to */
202 	int idx;        /* Index of the standard error message, or -1 for
203 			   user-defined message */
204 };
205 
206 enum envar_type {
207 	envar_set,   /* Set variable */
208 	envar_unset, /* Unset variable(s) */
209 	envar_keep,  /* Preserve variable(s) while clearing the environment */
210 	envar_eval   /* Evaluate string for side effects. Discard the result */
211 };
212 
213 struct envar {
214 	struct envar *next;
215 	enum envar_type type;
216 	char *name;
217 	char *value;
218 };
219 
220 struct rush_rule {
221 	struct rush_rule *next;      /* Next rule in the list */
222 
223 	char *tag;
224 	int fall_through;
225 	int interactive;
226 
227 	/* Source location */
228 	const char *file;                 /* Configuration file name */
229 	int line;                         /* and line number. */
230 
231 	/* Match parameters */
232 	struct test_node *test_node;
233 
234 	/* Transformation parameters: */
235 	struct transform_node *transform_head, *transform_tail;
236 
237 	/* Environment modification: */
238 	int clrenv;
239 	struct envar *envar_head, *envar_tail;
240 
241 	/* If not NULL, print this message on ERROR_FD and exit */
242 	struct rush_error *error;
243 
244 	struct rush_i18n i18n;
245 
246 	mode_t mask;                 /* umask */
247 	char *chroot_dir;            /* chroot directory */
248 	char *home_dir;              /* home directory */
249 	gid_t gid;                   /* primary group ID */
250 	limits_record_t limits;      /* resource limits */
251 
252 	enum rush_three_state fork;  /* Fork a subprocess */
253 	enum rush_three_state acct;  /* Run accounting */
254 
255 	struct rush_sockaddr post_sockaddr;
256 };
257 
258 struct rush_backref {
259 	char *subject;
260  	regmatch_t *match;
261 	size_t nmatch;
262 	size_t maxmatch;
263 };
264 
265 struct rush_request {
266         char *cmdline;         /* Command line */
267         size_t argc;           /* Number of elements in argv */
268         char **argv;           /* Command line in parsed form */
269 	int interactive;       /* Request for interactive shell */
270 	char *prog;            /* Program file name, if different
271 				  from argv[0] */
272         struct passwd *pw;     /* User passwd entry */
273 	unsigned umask;
274 	char *chroot_dir;
275         char *home_dir;
276 	gid_t gid;
277 	enum rush_three_state fork;
278 	enum rush_three_state acct;
279 	const struct rush_sockaddr *post_sockaddr;
280 	struct rush_i18n i18n;
281 
282 	/* Backreferences
283 	   The backref field contains backreferences from the recent and
284 	   penultimate regex matches. The backref_cur field indexes the
285 	   recent backreferences. Remaining slot is used as a temporary
286 	   storage during eventual next match. If that match succeeds, the
287 	   value of backref_cur is updated to reflect the fact. The
288 	   backref_count field keeps the actual number of backreferences
289 	   used in the recent match. */
290 	struct rush_backref backref[2];
291 	int backref_cur;
292 	size_t backref_count;
293 
294 	/* Constructed environment */
295 	char **env;
296 	size_t env_count;
297 	size_t env_max;
298 
299 	/* Temporary variable storage */
300 	char **var_kv;
301 	size_t var_count;
302 	size_t var_max;
303 };
304 
305 #define PROGFILE(req) ((req)->prog ? (req)->prog : (req)->argv[0])
306 #define NO_UMASK ((mode_t)-1)
307 #define NO_GID ((gid_t)-1)
308 
309 extern char *rush_config_file;
310 extern int lint_option;
311 extern unsigned sleep_time;
312 extern struct rush_rule *rule_head, *rule_tail;
313 extern unsigned debug_level;
314 extern char *dump_option;
315 extern int debug_option;
316 extern struct passwd *rush_pw;
317 
318 #define __debug_p(x) ((x) <= debug_level)
319 
320 #define debug(lev,fmt,...)					\
321 	do {							\
322 		if (__debug_p(lev))				\
323 			logmsg(LOG_DEBUG, fmt, __VA_ARGS__);	\
324 	} while(0)
325 
326 struct cfloc;
327 
328 void die(enum error_type type, struct rush_i18n *i18n, const char *fmt, ...)
329 	 RUSH_NORETURN RUSH_PRINTFLIKE(3,4);
330 void die_usage(struct cfloc const *loc, char const *fmt, ...)
331 	 RUSH_NORETURN RUSH_PRINTFLIKE(2,3);
332 void logmsg(int prio, const char *fmt, ...)  RUSH_PRINTFLIKE(2,3);
333 void vlogmsg(int prio, const char *fmt, va_list ap);
334 
335 enum {
336 	lrec_ok = 0,
337 	lrec_error = 1,
338 	lrec_badval = 2
339 };
340 limits_record_t limits_record_create(void);
341 int limits_record_add(limits_record_t lrec, char *str, char **endp);
342 int parse_limits(limits_record_t *plrec, char *str, char **endp);
343 int set_user_limits(const char *name, struct limits_rec *lrec);
344 
345 transform_t compile_transform_expr (const char *expr, int cflags,
346 				    struct cfloc *loc);
347 char *transform_string (struct transform *tf, const char *input);
348 
349 int post_socket_send(const struct rush_sockaddr *sockaddr,
350 		     const struct rush_rule *rule,
351 		     const struct rush_request *req);
352 
353 char *make_file_name(const char *dir, const char *name);
354 char *expand_tilde(const char *dir, const char *home);
355 
356 
357 /* cfck.c */
358 #define RUSH_CHK_OWNER      0x0001
359 #define RUSH_CHK_IWGRP      0x0002
360 #define RUSH_CHK_IWOTH      0x0004
361 #define RUSH_CHK_LINK       0x0008
362 #define RUSH_CHK_DIR_IWGRP  0x0010
363 #define RUSH_CHK_DIR_IWOTH  0x0020
364 #define RUSH_CHK_ALL        \
365 	(RUSH_CHK_OWNER|RUSH_CHK_IWGRP|RUSH_CHK_IWOTH|\
366 	 RUSH_CHK_LINK|RUSH_CHK_DIR_IWGRP|RUSH_CHK_DIR_IWOTH)
367 #ifndef RUSH_CHK_DEFAULT
368 # define RUSH_CHK_DEFAULT RUSH_CHK_ALL
369 #endif
370 
371 int check_config_permissions(const char *filename, struct stat *st);
372 int cfck_keyword(const char *name);
373 
374 
375 /* map.c */
376 char *map_string(struct rush_map *map, struct rush_request *req);
377 char *rush_expand_string(const char *string, struct rush_request *req);
378 char **rush_getvarptr(struct rush_request *req, char const *varname);
379 void rush_request_delvar(struct rush_request *req, char const *varname);
380 enum transform_target_type rush_variable_target(char const *varname);
381 void rush_ws_error (const char *fmt, ...);
382 
383 /* dump.c */
384 void dump_request(struct rush_request *req, FILE *fp);
385 
386 /* rush_error management */
387 void set_error_msg(enum error_type type, char *text);
388 int string_to_error_index(const char *name);
389 
390 struct rush_error *new_standard_error(int fd, int idx);
391 struct rush_error *new_error(int fd, char const *text, int unescape);
392 char const *rush_error_msg(struct rush_error const *err,
393 			   struct rush_i18n const *i18n);
394 
395 
396