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