Add support to -u and -g flags

Check fmt_string retval
Add timeout for debugging purposes
This commit is contained in:
Todd C. Miller
2010-03-06 16:29:59 -05:00
parent 4e938c0074
commit b814a0d74f

View File

@@ -44,6 +44,8 @@
#endif /* HAVE_UNISTD_H */ #endif /* HAVE_UNISTD_H */
#include <fcntl.h> #include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <grp.h>
#include <pwd.h>
#include <stdarg.h> #include <stdarg.h>
#include <sudo_plugin.h> #include <sudo_plugin.h>
@@ -55,13 +57,11 @@
* caching the validate and invalidate functions are NULL. * caching the validate and invalidate functions are NULL.
*/ */
static struct plugin_state { #ifdef __TANDEM
char **envp; # define ROOT_UID 65535
char * const *settings; #else
char * const *user_info; # define ROOT_UID 0
} plugin_state; #endif
static sudo_conv_t sudo_conv;
static FILE *input, *output;
#undef TRUE #undef TRUE
#define TRUE 1 #define TRUE 1
@@ -70,6 +70,16 @@ static FILE *input, *output;
#undef ERROR #undef ERROR
#define ERROR -1 #define ERROR -1
static struct plugin_state {
char **envp;
char * const *settings;
char * const *user_info;
} plugin_state;
static sudo_conv_t sudo_conv;
static FILE *input, *output;
static uid_t runas_uid = ROOT_UID;
static gid_t runas_gid = -1;
/* /*
* Allocate storage for a name=value string and return it. * Allocate storage for a name=value string and return it.
*/ */
@@ -81,14 +91,14 @@ fmt_string(const char *var, const char *val)
char *cp, *str; char *cp, *str;
cp = str = malloc(var_len + 1 + val_len + 1); cp = str = malloc(var_len + 1 + val_len + 1);
if (!str) if (str != NULL) {
return NULL;
memcpy(cp, var, var_len); memcpy(cp, var, var_len);
cp += var_len; cp += var_len;
*cp++ = '='; *cp++ = '=';
memcpy(cp, val, val_len); memcpy(cp, val, val_len);
cp += val_len; cp += val_len;
*cp = '\0'; *cp = '\0';
}
return(str); return(str);
} }
@@ -128,7 +138,10 @@ policy_open(unsigned int version, sudo_conv_t conversation,
char * const user_env[]) char * const user_env[])
{ {
char * const *ui; char * const *ui;
struct passwd *pw;
const char *runas_user = NULL; const char *runas_user = NULL;
struct group *gr;
const char *runas_group = NULL;
sudo_conv = conversation; sudo_conv = conversation;
@@ -144,11 +157,24 @@ policy_open(unsigned int version, sudo_conv_t conversation,
if (strncmp(*ui, "runas_user=", sizeof("runas_user=") - 1) == 0) { if (strncmp(*ui, "runas_user=", sizeof("runas_user=") - 1) == 0) {
runas_user = *ui + sizeof("runas_user=") - 1; runas_user = *ui + sizeof("runas_user=") - 1;
} }
if (strncmp(*ui, "runas_group=", sizeof("runas_group=") - 1) == 0) {
runas_group = *ui + sizeof("runas_group=") - 1;
} }
if (runas_user && strcmp(runas_user, "root") != 0) { }
sudo_log(SUDO_CONV_ERROR_MSG, "commands may only be run as root."); if (runas_user != NULL) {
if ((pw = getpwnam(runas_user)) == NULL) {
sudo_log(SUDO_CONV_ERROR_MSG, "unknown user %s", runas_user);
return 0; return 0;
} }
runas_uid = pw->pw_uid;
}
if (runas_group != NULL) {
if ((gr = getgrnam(runas_group)) == NULL) {
sudo_log(SUDO_CONV_ERROR_MSG, "unknown group %s", runas_group);
return 0;
}
runas_gid = gr->gr_gid;
}
/* Plugin state. */ /* Plugin state. */
plugin_state.envp = (char **)user_env; plugin_state.envp = (char **)user_env;
@@ -208,9 +234,23 @@ policy_check(int argc, char * const argv[],
sudo_log(SUDO_CONV_ERROR_MSG, "out of memory"); sudo_log(SUDO_CONV_ERROR_MSG, "out of memory");
return ERROR; return ERROR;
} }
command_info[i++] = fmt_string("command", argv[0]); if ((command_info[i++] = fmt_string("command", argv[0])) == NULL ||
command_info[i++] = "runas_uid=0"; asprintf(&command_info[i++], "runas_euid=%ld", (long)runas_uid) == -1 ||
command_info[i++] = "runas_euid=0"; asprintf(&command_info[i++], "runas_uid=%ld", (long)runas_uid) == -1) {
sudo_log(SUDO_CONV_ERROR_MSG, "out of memory");
return ERROR;
}
if (runas_gid != -1) {
if (asprintf(&command_info[i++], "runas_gid=%ld", (long)runas_gid) == -1 ||
asprintf(&command_info[i++], "runas_egid=%ld", (long)runas_gid) == -1) {
sudo_log(SUDO_CONV_ERROR_MSG, "out of memory");
return ERROR;
}
}
#ifdef USE_TIMEOUT
command_info[i++] = "timeout=30";
#endif
*command_info_out = command_info; *command_info_out = command_info;
return TRUE; return TRUE;