#define SHELL "/bin/bash"
typedef struct {
+ char *user;
char *svn_root;
char *git_root;
char *owner;
char *git_acl_file;
+ bool allow_interactive;
} cfg_t;
static cfg_t cfg;
-static uid_t user_uid(char *user)
+/* This is the function for which setuid root is needed for repo_shell */
+static void change_user(char *user)
{
struct passwd *pw = getpwnam(user);
if (!pw)
- die("invalid user %s", user);
- return pw->pw_uid;
-}
-
-static void change_user(char *user)
-{
- /* This is the function for which setuid is required, as root */
- setuid(user_uid(user));
+ die("invalid user %s", pw->pw_name);
+ setuid(pw->pw_uid);
}
static char *dequote(char *arg)
return narg;
}
-static int check_ssh_interactive(uid_t uid)
-{
- /* TODO: Check the config file for the user owning uid to see if that
- * user should be able to execute any commands other than those required
- * to support repository access. Return a boolean true/false.
- */
- return 1; /* for now */
-}
-
/* Return true if the user's permissions >= those required */
static bool git_check_access(const char *cmd, const char *repo,
const char *user)
pconfig->owner = xstrdup(value);
else if (!strcmp(name, "git_acl_file"))
pconfig->git_acl_file = xstrdup(value);
+ else if (!strcmp(name, "allow_interactive"))
+ pconfig->allow_interactive = str_has_word(value, pconfig->user);
else
return 0; /* unknown section/name, error */
return 1;
struct commands *cmd;
int devnull_fd;
int count;
+ struct passwd *pw;
/*
* Always open file descriptors 0/1/2 to avoid clobbering files
return 0;
}
+ pw = getpwuid(getuid());
+ cfg.user = xstrdup(pw->pw_name);
+ if (ini_parse(CFG_FILE, ini_handler, &cfg) < 0)
+ die("cannot read config file %s", CFG_FILE);
+
if (argc == 1) {
- if (!check_ssh_interactive(getuid()))
+ if (!cfg.allow_interactive) {
+ fprintf(stderr, "\n");
die("only repository access is allowed");
+ }
setuid(getuid());
argv[0] = SHELL;
execvp(argv[0], (char *const *) argv);
return 1;
}
- if (ini_parse(CFG_FILE, ini_handler, &cfg) < 0)
- die("cannot read config file %s", CFG_FILE);
-
if ((!strcmp(argv[1], "-t") || !strcmp(argv[1], "--test"))) {
perms_t p;
for (cmd = cmd_list ; cmd->name ; cmd++) {
int len = strlen(cmd->name);
char *arg;
- struct passwd *pw;
if (strncmp(cmd->name, prog, len))
continue;
arg = NULL;
continue;
}
- pw = getpwuid(getuid());
- exit(cmd->exec(cmd->name, arg, pw->pw_name));
+ exit(cmd->exec(cmd->name, arg, cfg.user));
}
}
- if (!check_ssh_interactive(getuid()))
+ if (!cfg.allow_interactive)
die("only repository access is allowed");
-
setuid(getuid());
cd_to_homedir();
argv[0] = SHELL;