"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "helper.c" between
scponly-20110526.tgz and scponly-4.8.tgz

About: scponly is an alternative "shell" of sorts for system administrators who would like to provide access to remote users to both read and write local files without providing any remote execution privileges (a wrapper around "ssh"). Commands like chmod, pwd, chown, etc. are allowed for sftp.

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

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS