helper.c (scponly-20110526.tgz) | : | helper.c (scponly-4.8.tgz) | ||
---|---|---|---|---|
/* | /* | |||
* helper functions for scponly | * helper functions for scponly | |||
*/ | */ | |||
#include <stdio.h> /* io */ | #include <stdio.h> /* io */ | |||
#include <string.h> /* for str* */ | #include <string.h> /* for str* */ | |||
#include <sys/types.h> /* for stat, getpwuid */ | #include <sys/types.h> /* for stat, getpwuid */ | |||
#include <sys/stat.h> /* for stat */ | #include <sys/stat.h> /* for stat */ | |||
#include <unistd.h> /* for exit, access, getpwuid, execve, getopt */ | #include <unistd.h> /* for exit, access, getpwuid, execve, getopt */ | |||
#ifdef HAVE_GETOPT_H | ||||
#include <getopt.h> /* for getopt */ | ||||
#endif | ||||
#include <errno.h> /* for debugging */ | #include <errno.h> /* for debugging */ | |||
#include <pwd.h> /* to get username for config parsing */ | #include <pwd.h> /* to get username for config parsing */ | |||
#include <time.h> /* time */ | #include <time.h> /* time */ | |||
#include <libgen.h> /* basename */ | #include <libgen.h> /* basename */ | |||
#include <stdlib.h> /* realloc */ | #include <stdlib.h> /* realloc */ | |||
#include <syslog.h> | #include <syslog.h> | |||
#include "scponly.h" | ||||
#include "config.h" | #include "config.h" | |||
#include "scponly.h" /* includes getopt */ | ||||
#ifdef HAVE_GLOB | #ifdef HAVE_GLOB | |||
#include <glob.h> /* for glob() */ | #include <glob.h> /* for glob() */ | |||
#else | #else | |||
#ifdef HAVE_WORDEXP | #ifdef HAVE_WORDEXP | |||
#include <wordexp.h> /* for wordexp() */ | #include <wordexp.h> /* for wordexp() */ | |||
#endif | #endif | |||
#endif | #endif | |||
#ifdef RSYNC_COMPAT | ||||
#define RSYNC_ARG_SERVER 0x01 | ||||
#define RSYNC_ARG_EXECUTE 0x02 | ||||
#endif | ||||
#define MAX(x,y) ( ( x > y ) ? x : y ) | #define MAX(x,y) ( ( x > y ) ? x : y ) | |||
#define MIN(x,y) ( ( x < y ) ? x : y ) | #define MIN(x,y) ( ( x < y ) ? x : y ) | |||
extern int debuglevel; | extern int debuglevel; | |||
extern char username[MAX_USERNAME]; | extern char username[MAX_USERNAME]; | |||
extern char homedir[FILENAME_MAX]; | extern char homedir[FILENAME_MAX]; | |||
extern cmd_t commands[]; | extern cmd_t commands[]; | |||
extern cmd_arg_t dangerous_args[]; | extern cmd_arg_t dangerous_args[]; | |||
extern char * allowed_env_vars[]; | extern char * allowed_env_vars[]; | |||
extern char * safeenv[MAX_ENV]; | extern char * safeenv[MAX_ENV]; | |||
extern void (*debug)(int priority, const char* format, ...); | extern void (*debug)(int priority, const char* format, ...); | |||
extern int (*scponly_getopt_long)( int argc, char * const argv[], const char *op tstring, const struct option *longopts, int *longindex); | ||||
#ifdef HAVE_GETOPT | #ifdef HAVE_GETOPT | |||
extern char *optarg; | extern char *optarg; | |||
extern int optind; | extern int optind; | |||
#ifdef HAVE_OPTRESET | #ifdef HAVE_OPTRESET | |||
extern int optreset; | extern int optreset; | |||
#endif | #endif | |||
#endif | #endif | |||
void noop_syslog(int priority, const char* format, ...) | void noop_syslog(int priority, const char* format, ...) | |||
skipping to change at line 171 | skipping to change at line 167 | |||
* | * | |||
* RETURN: 1 means reject this command, 0 means it is safe. | * RETURN: 1 means reject this command, 0 means it is safe. | |||
*/ | */ | |||
int check_dangerous_args(char **av) | int check_dangerous_args(char **av) | |||
{ | { | |||
cmd_arg_t *cmdarg=dangerous_args; | cmd_arg_t *cmdarg=dangerous_args; | |||
char **tmpptr=av; | char **tmpptr=av; | |||
int ch; | int ch; | |||
int ac=0; | int ac=0; | |||
int longopt_index = 0; | int longopt_index = 0; | |||
#ifdef RSYNC_COMPAT | ||||
/* | ||||
* bitwise flag: 0x01 = server, 0x02 = -e. | ||||
* Thus 0x03 is allowed and 0x01 is allowed, but 0x02 is not allowed | ||||
*/ | ||||
int rsync_flags = 0; | ||||
#endif /* RSYNC_COMPAT */ | ||||
while (cmdarg != NULL) | while (cmdarg != NULL) | |||
{ | { | |||
if (cmdarg->name == NULL) | if (cmdarg->name == NULL) | |||
return 0; | return 0; | |||
if (exact_match(cmdarg->name,av[0])) | if (exact_match(cmdarg->name,av[0])) | |||
{ | { | |||
/* | /* | |||
* the command matches one of our dangerous commands | * the command matches one of our dangerous commands | |||
* check the rest of the vector for dangerous comman d | * check the rest of the vector for dangerous comman d | |||
skipping to change at line 221 | skipping to change at line 210 | |||
/* | /* | |||
* if we have optreset, use it to reset the globa l variables | * if we have optreset, use it to reset the globa l variables | |||
*/ | */ | |||
optreset=1; | optreset=1; | |||
optind=1; | optind=1; | |||
#else | #else | |||
/* | /* | |||
* otherwise, try a glibc-style reset of the global getopt vars | * otherwise, try a glibc-style reset of the global getopt vars | |||
*/ | */ | |||
optind=0; | optind=0; | |||
#endif /* HAVE_OPTRESET */ | #endif | |||
/* | /* | |||
* tell getopt to only be strict if the 'opt s' is well defined | * tell getopt to only be strict if the 'opt s' is well defined | |||
*/ | */ | |||
opterr=cmdarg->strict; | opterr=cmdarg->strict; | |||
while ((ch = scponly_getopt_long(ac, av, cmdarg-> opts, cmdarg->longopts, &longopt_index)) != -1) { | while ((ch = getopt_long(ac, av, cmdarg->opts, cm darg->longopts, &longopt_index)) != -1) { | |||
debug(LOG_DEBUG, "getopt processing retur ned '%c' (%s)", ch, logstamp()); | debug(LOG_DEBUG, "getopt processing retur ned '%c' (%s)", ch, logstamp()); | |||
#ifdef RSYNC_COMPAT | ||||
if (exact_match(cmdarg->name, PROG_RSYNC) | ||||
&& (ch == 's' || ch == 'e')) { | ||||
if (ch == 's') | ||||
rsync_flags |= RSYNC_ARG_ | ||||
SERVER; | ||||
else | ||||
/* -e */ | ||||
rsync_flags |= RSYNC_ARG_ | ||||
EXECUTE; | ||||
debug(LOG_DEBUG, "rsync_flags are | ||||
now set to: %0x", rsync_flags); | ||||
} | ||||
else | ||||
#endif /* RSYNC_COMPAT */ | ||||
/* if the character is found in badarg, t hen it's not a permitted option */ | /* if the character is found in badarg, t hen it's not a permitted option */ | |||
if (cmdarg->badarg != NULL && (strchr(cmd arg->badarg, ch) != NULL)) | if (cmdarg->badarg != NULL && (strchr(cmd arg->badarg, ch) != NULL)) | |||
{ | { | |||
syslog(LOG_ERR, "option '%c' or a related long option is not permitted for use with %s (arg was %s) (%s))", | syslog(LOG_ERR, "option '%c' or a related long option is not permitted for use with %s (arg was %s) (%s))", | |||
ch, cmdarg->name, (optarg !=NULL ? optarg : "<NULL>"), logstamp()); | ch, cmdarg->name, optarg, logstamp()); | |||
return 1; | return 1; | |||
} | } | |||
else if (cmdarg->strict && ch == '?') | else if (cmdarg->strict && ch == '?') | |||
{ | { | |||
syslog(LOG_ERR, "an unrecognized option was encountered while processing cmd %s (arg was %s) (%s))", | syslog(LOG_ERR, "an unrecognized option was encountered while processing cmd %s (arg was %s) (%s))", | |||
cmdarg->name, (optarg!=NU LL ? optarg : "<NULL>"), logstamp()); | cmdarg->name, optarg, log stamp()); | |||
return 1; | return 1; | |||
} | } | |||
} | } | |||
#ifdef RSYNC_COMPAT | #elif | |||
/* it's not safe if the execute flag was set and | ||||
server was not set */ | ||||
if ((rsync_flags & RSYNC_ARG_EXECUTE) != 0 && (rs | ||||
ync_flags & RSYNC_ARG_SERVER) == 0) { | ||||
syslog(LOG_ERR, "option 'e' is no | ||||
t allowed unless '--server' is also set with cmd %s (%s)", | ||||
PROG_RSYNC, logstamp()); | ||||
return 1; | ||||
} | ||||
#endif /* RSYNC_COMPAT */ | ||||
#else /* HAVE_GETOPT */ | ||||
/* | /* | |||
* make sure that processing doesn't continue if we can't validate a rsync check | * make sure that processing doesn't continue if we can't validate a rsync check | |||
* and if the getopt flag is set. | * and if the getopt flag is set. | |||
*/ | */ | |||
syslog(LOG_ERR, "a getopt() argument check could not be performed for %s, recompile scponly without support for %s or rebuild scp only with getopt", av[0], av[0]); | syslog(LOG_ERR, "a getopt() argument check could not be performed for %s, recompile scponly without support for %s or rebuild scp only with getopt", av[0], av[0]); | |||
return 1; | return 1; | |||
#endif /* HAVE_GETOPT */ | #endif | |||
} | } | |||
else | else | |||
/* | /* | |||
* command does not require getopt processing | * command does not require getopt processing | |||
*/ | */ | |||
{ | { | |||
debug(LOG_DEBUG, "Not using getopt processing on cmd %s (%s)", cmdarg->name, logstamp()); | debug(LOG_DEBUG, "Not using getopt processing on cmd %s (%s)", cmdarg->name, logstamp()); | |||
tmpptr=av; | tmpptr=av; | |||
tmpptr++; | tmpptr++; | |||
End of changes. 13 change blocks. | ||||
49 lines changed or deleted | 10 lines changed or added |