2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-02 15:25:58 +00:00

now uses NewArgv amd NewArgc so cmnd_aegs is no longer needed

this also allows us to eliminate some kludges in parse_args()
and eliminate superfluous code.
This commit is contained in:
Todd C. Miller
1996-02-02 03:34:21 +00:00
parent d386132788
commit e06c19bbb9

161
sudo.c
View File

@@ -133,9 +133,10 @@ extern struct passwd *sudo_getpwuid __P((uid_t));
*/ */
int Argc; int Argc;
char **Argv; char **Argv;
int NewArgc = 0;
char **NewArgv = NULL;
struct passwd *user_pw_ent; struct passwd *user_pw_ent;
char *cmnd = NULL; char *cmnd = NULL;
char *cmnd_args = NULL;
char *tty = NULL; char *tty = NULL;
char *prompt = PASSPROMPT; char *prompt = PASSPROMPT;
char host[MAXHOSTNAMELEN + 1]; char host[MAXHOSTNAMELEN + 1];
@@ -238,6 +239,38 @@ int main(argc, argv)
load_globals(sudo_mode); /* load global variables used throughout sudo */ load_globals(sudo_mode); /* load global variables used throughout sudo */
/*
* If we got the '-s' option (run shell) we need to redo NewArgv
* and NewArgc. This can only be done after load_globals().
*/
if ((sudo_mode & MODE_SHELL)) {
char **dst, **src = NewArgv;
NewArgv = (char **) malloc (sizeof(char *) * (++NewArgc));
if (NewArgv == NULL) {
perror("malloc");
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
exit(1);
}
/* add the shell as argv[0] */
/* XXX - doesn't deal with "" meaning bourne shell */
if (user_shell && *user_shell) {
if ((NewArgv[0] = strrchr(user_shell, '/') + 1) == (char *) 1)
NewArgv[0] = user_shell;
} else {
(void) fprintf(stderr, "%s: Unable to determine shell.", Argv[0]);
exit(1);
}
/* copy the args from Argv */
dst = NewArgv + 1;
*dst = (char *) NULL;
while (*src) {
*dst++ = *src++;
}
}
rtn = check_sudoers(); /* check mode/owner on _PATH_SUDO_SUDOERS */ rtn = check_sudoers(); /* check mode/owner on _PATH_SUDO_SUDOERS */
if (rtn != ALL_SYSTEMS_GO) { if (rtn != ALL_SYSTEMS_GO) {
log_error(rtn); log_error(rtn);
@@ -303,35 +336,7 @@ int main(argc, argv)
} }
} }
/* EXEC(cmnd, NewArgv); /* run the command */
* If invoking a shell, replace "-s" with shell to exec.
* For this to work we need to malloc() a new argv...
*/
if ((sudo_mode & MODE_SHELL)) {
char **NewArgv;
int i;
NewArgv = (char **) malloc (sizeof(char *) * (Argc + 1));
if (NewArgv == NULL) {
perror("malloc");
(void) fprintf(stderr, "%s: cannot allocate memory!\n",
Argv[0]);
exit(1);
}
/* replace "-s" with the shell's name */
if ((NewArgv[0] = strrchr(user_shell, '/') + 1)
== (char *) 1)
NewArgv[0] = user_shell;
for (i = 1; i < Argc; i++)
NewArgv[i] = Argv[i];
NewArgv[i] = (char *) NULL;
EXEC(cmnd, NewArgv);
} else
EXEC(cmnd, &Argv[1]);
} }
#else #else
exit(0); exit(0);
@@ -485,7 +490,6 @@ static int parse_args()
{ {
int ret = MODE_RUN; /* what mode is suod to be run in? */ int ret = MODE_RUN; /* what mode is suod to be run in? */
int excl = 0; /* exclusive arg, no others allowed */ int excl = 0; /* exclusive arg, no others allowed */
char *progname = Argv[0]; /* so we can save Argv[0] */
#ifdef SHELL_IF_NO_ARGS #ifdef SHELL_IF_NO_ARGS
if (Argc < 2) { /* no options and no command */ if (Argc < 2) { /* no options and no command */
@@ -497,26 +501,29 @@ static int parse_args()
usage(1); usage(1);
#endif /* SHELL_IF_NO_ARGS */ #endif /* SHELL_IF_NO_ARGS */
while (Argc > 1 && Argv[1][0] == '-') { NewArgv = Argv + 1;
if (Argv[1][1] != '\0' && Argv[1][2] != '\0') { NewArgc = Argc - 1;
while (NewArgc > 0 && NewArgv[0][0] == '-') {
if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') {
(void) fprintf(stderr, "%s: Please use single character options\n", (void) fprintf(stderr, "%s: Please use single character options\n",
progname); Argv[0]);
usage(1); usage(1);
} }
if (excl) if (excl)
usage(1); /* only one -? option allowed */ usage(1); /* only one -? option allowed */
switch (Argv[1][1]) { switch (NewArgv[0][1]) {
case 'p': case 'p':
if (Argc + (ret & MODE_SHELL) < 4) /* must have an associated prompt */
if (NewArgv[1] == NULL)
usage(1); usage(1);
prompt = Argv[2]; prompt = NewArgv[1];
/* shift Argv over and adjust Argc */ /* shift Argv over and adjust Argc */
Argc--; NewArgc--;
Argv++; NewArgv++;
break; break;
case 'b': case 'b':
ret |= MODE_BACKGROUND; ret |= MODE_BACKGROUND;
@@ -545,9 +552,8 @@ static int parse_args()
ret |= MODE_SHELL; ret |= MODE_SHELL;
break; break;
case '-': case '-':
Argc--; NewArgc--;
Argv++; NewArgv++;
Argv[0] = progname;
#ifdef SHELL_IF_NO_ARGS #ifdef SHELL_IF_NO_ARGS
if (ret == MODE_RUN) if (ret == MODE_RUN)
ret |= MODE_SHELL; ret |= MODE_SHELL;
@@ -555,16 +561,15 @@ static int parse_args()
return(ret); return(ret);
case '\0': case '\0':
(void) fprintf(stderr, "%s: '-' requires an argument\n", (void) fprintf(stderr, "%s: '-' requires an argument\n",
progname); Argv[0]);
usage(1); usage(1);
default: default:
(void) fprintf(stderr, "%s: Illegal option %s\n", progname, (void) fprintf(stderr, "%s: Illegal option %s\n", Argv[0],
Argv[1]); NewArgv[0]);
usage(1); usage(1);
} }
Argc--; NewArgc--;
Argv++; NewArgv++;
Argv[0] = progname;
} }
return(ret); return(ret);
@@ -636,71 +641,25 @@ static void add_env()
* *
* load_cmnd() * load_cmnd()
* *
* This function sets the cmnd and cmnd_args global variables based on Argv * This function sets the cmnd global variable based on Argv
*/ */
static void load_cmnd(sudo_mode) static void load_cmnd(sudo_mode)
int sudo_mode; int sudo_mode;
{ {
int arg_start = 2; /* position where command args start */ if (strlen(NewArgv[0]) > MAXPATHLEN) {
char *old_cmnd; /* command before expansion */
/* If we are running a shell command args start at position 1 */
if ((sudo_mode & MODE_SHELL)) {
if (user_shell && *user_shell) {
old_cmnd = user_shell;
arg_start = 1;
} else {
(void) fprintf(stderr, "%s: Unable to determine shell.", Argv[0]);
exit(1);
}
} else {
old_cmnd = Argv[1];
}
if (strlen(old_cmnd) > MAXPATHLEN) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
(void) fprintf(stderr, "%s: %s: Pathname too long\n", Argv[0], old_cmnd); (void) fprintf(stderr, "%s: %s: Pathname too long\n", Argv[0],
NewArgv[0]);
exit(1); exit(1);
} }
/*
* Find the length of cmnd_args and allocate space, then fill it in.
*/
if (Argc > arg_start) {
size_t arg_len; /* sum length of all args */
char *from, *to; /* loop variables for string copy */
int i; /* venerable loop variable */
/*
* How much space do we need?
* This assumes that Argv (aka argv) is contiguous.
*/
arg_len = (size_t) Argv[Argc-1] + strlen(Argv[Argc-1]) + 1 -
(size_t) Argv[arg_start];
if ((cmnd_args = (char *) malloc(arg_len)) == NULL) {
perror("malloc");
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
exit(1);
}
/*
* Copy from Argv to cmnd_args, replacing NULL's with spaces.
* This assumes that Argv (aka argv) is contiguous.
*/
for (i=0, to=cmnd_args, from=Argv[arg_start]; i < arg_len; i++) {
if ((*to++ = *from++) == NULL)
*(to-1) = ' ';
}
cmnd_args[arg_len-1] = '\0'; /* need a NULL at the end */
}
/* /*
* Resolve the path * Resolve the path
*/ */
if ((cmnd = find_path(old_cmnd)) == NULL) { if ((cmnd = find_path(NewArgv[0])) == NULL) {
(void) fprintf(stderr, "%s: %s: command not found\n", Argv[0], old_cmnd); (void) fprintf(stderr, "%s: %s: command not found\n", Argv[0],
NewArgv[0]);
exit(1); exit(1);
} }
} }