%{
/*
- * Copyright (c) 1996, 1998-2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1996, 1998-2004, 2007
+ * Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* list_matches() can format things the way it wants.
*/
-#include "config.h"
+#include <config.h>
#include <sys/types.h>
#include <sys/param.h>
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <pwd.h>
-#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
-# include <malloc.h>
-#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
#if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
# include <alloca.h>
#endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */
#endif /* HAVE_LSEARCH */
#ifndef lint
-static const char rcsid[] = "$Sudo: parse.yacc,v 1.204 2004/08/11 18:29:10 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: parse.yacc,v 1.204.2.8 2007/11/02 19:09:01 millert Exp $";
#endif /* lint */
/*
match[top].runas = UNSPEC; \
match[top].nopass = def_authenticate ? UNSPEC : TRUE; \
match[top].noexec = def_noexec ? TRUE : UNSPEC; \
+ match[top].setenv = def_setenv ? TRUE : UNSPEC; \
top++; \
} while (0)
match[top].runas = match[top-1].runas; \
match[top].nopass = match[top-1].nopass; \
match[top].noexec = match[top-1].noexec; \
+ match[top].setenv = match[top-1].setenv; \
top++; \
} while (0)
static void expand_ga_list __P((void));
static void expand_match_list __P((void));
static aliasinfo *find_alias __P((char *, int));
-static int more_aliases __P((void));
+static void more_aliases __P((void));
void init_parser __P((void));
void yyerror __P((char *));
%token <command> COMMAND /* absolute pathname w/ optional args */
%token <string> ALIAS /* an UPPERCASE alias name */
%token <string> DEFVAR /* a Defaults variable name */
-%token <string> NTWKADDR /* w.x.y.z */
+%token <string> NTWKADDR /* w.x.y.z or ipv6 address */
%token <string> NETGROUP /* a netgroup (+NAME) */
%token <string> USERGROUP /* a usergroup (%NAME) */
%token <string> WORD /* a word */
%token <tok> PASSWD /* passwd req for command (default) */
%token <tok> NOEXEC /* preload dummy execve() for cmnd */
%token <tok> EXEC /* don't preload dummy execve() */
+%token <tok> SETENV /* user may set environment for cmnd */
+%token <tok> NOSETENV /* user may not set environment */
%token <tok> ALL /* ALL keyword */
%token <tok> COMMENT /* comment and/or carriage return */
%token <tok> HOSTALIAS /* Host_Alias keyword */
yyerror(NULL);
YYERROR;
}
- free($1);
+ efree($1);
}
| '!' DEFVAR {
if (defaults_matches == TRUE &&
yyerror(NULL);
YYERROR;
}
- free($2);
+ efree($2);
}
| DEFVAR '=' WORD {
if (defaults_matches == TRUE &&
yyerror(NULL);
YYERROR;
}
- free($1);
- free($3);
+ efree($1);
+ efree($3);
}
| DEFVAR '+' WORD {
if (defaults_matches == TRUE &&
yyerror(NULL);
YYERROR;
}
- free($1);
- free($3);
+ efree($1);
+ efree($3);
}
| DEFVAR '-' WORD {
if (defaults_matches == TRUE &&
yyerror(NULL);
YYERROR;
}
- free($1);
- free($3);
+ efree($1);
+ efree($3);
}
;
runas_matches = UNSPEC;
no_passwd = def_authenticate ? UNSPEC : TRUE;
no_execve = def_noexec ? TRUE : UNSPEC;
+ setenv_ok = def_setenv ? TRUE : UNSPEC;
}
;
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
}
| NETGROUP {
if (netgr_matches($1, user_host, user_shost, NULL))
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
}
| WORD {
if (hostname_matches(user_shost, user_host, $1) == 0)
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
}
| ALIAS {
aliasinfo *aip = find_alias($1, HOST_ALIAS);
}
$$ = NOMATCH;
}
- free($1);
+ efree($1);
}
;
* then check against default runas user.
*/
if (runas_matches == UNSPEC) {
- runas_matches =
- userpw_matches(def_runas_default,
- *user_runas, runas_pw);
+ runas_matches = userpw_matches(def_runas_default,
+ *user_runas, runas_pw) ? TRUE : NOMATCH;
}
}
| RUNAS runaslist {
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
used_runas = TRUE;
}
| USERGROUP {
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
used_runas = TRUE;
}
| NETGROUP {
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
used_runas = TRUE;
}
| ALIAS {
}
$$ = NOMATCH;
}
- free($1);
+ efree($1);
used_runas = TRUE;
}
| ALL {
;
cmndtag : /* empty */ {
- /* Inherit {NOPASSWD,PASSWD,NOEXEC,EXEC} status. */
+ /* Inherit {NO,}{PASSWD,EXEC,SETENV} status. */
if (printmatches == TRUE && host_matches == TRUE &&
user_matches == TRUE) {
if (no_passwd == TRUE)
cm_list[cm_list_len].noexecve = TRUE;
else
cm_list[cm_list_len].noexecve = FALSE;
+ if (setenv_ok == TRUE)
+ cm_list[cm_list_len].setenv = TRUE;
+ else
+ cm_list[cm_list_len].setenv = FALSE;
}
}
| cmndtag NOPASSWD {
user_matches == TRUE)
cm_list[cm_list_len].noexecve = FALSE;
}
+ | cmndtag SETENV {
+ setenv_ok = TRUE;
+ if (printmatches == TRUE && host_matches == TRUE &&
+ user_matches == TRUE)
+ cm_list[cm_list_len].setenv = TRUE;
+ }
+ | cmndtag NOSETENV {
+ setenv_ok = FALSE;
+ if (printmatches == TRUE && host_matches == TRUE &&
+ user_matches == TRUE)
+ cm_list[cm_list_len].setenv = FALSE;
+ }
;
cmnd : ALL {
}
}
+ efree(safe_cmnd);
+ safe_cmnd = NULL;
$$ = TRUE;
-
- if (safe_cmnd)
- free(safe_cmnd);
- safe_cmnd = estrdup(user_cmnd);
}
| ALIAS {
aliasinfo *aip;
}
$$ = NOMATCH;
}
- free($1);
+ efree($1);
}
| COMMAND {
if (printmatches == TRUE) {
else
$$ = NOMATCH;
- free($1.cmnd);
- if ($1.args)
- free($1.args);
+ efree($1.cmnd);
+ efree($1.args);
}
;
YYERROR;
}
pop;
- free($1);
+ efree($1);
if (printmatches == TRUE)
in_alias = FALSE;
yyerror(NULL);
YYERROR;
}
- free($1);
+ efree($1);
if (printmatches == TRUE)
in_alias = FALSE;
YYERROR;
}
pop;
- free($1);
+ efree($1);
}
;
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
}
| USERGROUP {
if (usergr_matches($1, user_name, sudo_user.pw))
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
}
| NETGROUP {
if (netgr_matches($1, NULL, NULL, user_name))
$$ = TRUE;
else
$$ = NOMATCH;
- free($1);
+ efree($1);
}
| ALIAS {
aliasinfo *aip = find_alias($1, USER_ALIAS);
}
$$ = NOMATCH;
}
- free($1);
+ efree($1);
}
| ALL {
$$ = TRUE;
size_t onaliases;
char s[512];
- if (naliases >= nslots && !more_aliases()) {
- (void) snprintf(s, sizeof(s), "Out of memory defining alias `%s'",
- alias);
- yyerror(s);
- return(FALSE);
- }
+ if (naliases >= nslots)
+ more_aliases();
ai.type = type;
ai.val = val;
/*
* Allocates more space for the aliases list.
*/
-static int
+static void
more_aliases()
{
nslots += MOREALIASES;
- if (nslots == MOREALIASES)
- aliases = (aliasinfo *) malloc(nslots * sizeof(aliasinfo));
- else
- aliases = (aliasinfo *) realloc(aliases, nslots * sizeof(aliasinfo));
-
- return(aliases != NULL);
+ aliases = (aliasinfo *) erealloc3(aliases, nslots, sizeof(aliasinfo));
}
/*
else if (cm_list[count].nopasswd == FALSE && !def_authenticate)
(void) fputs("PASSWD: ", stdout);
+ /* Is setenv enabled? */
+ if (cm_list[count].setenv == TRUE && !def_setenv)
+ (void) fputs("SETENV: ", stdout);
+ else if (cm_list[count].setenv == FALSE && def_setenv)
+ (void) fputs("NOSETENV: ", stdout);
+
/* Print the actual command or expanded Cmnd_Alias. */
key.alias = cm_list[count].cmnd;
key.type = CMND_ALIAS;
/* Be nice and free up space now that we are done. */
for (count = 0; count < ga_list_len; count++) {
- free(ga_list[count].alias);
- free(ga_list[count].entries);
+ efree(ga_list[count].alias);
+ efree(ga_list[count].entries);
}
- free(ga_list);
+ efree(ga_list);
ga_list = NULL;
for (count = 0; count < cm_list_len; count++) {
- free(cm_list[count].runas);
- free(cm_list[count].cmnd);
+ efree(cm_list[count].runas);
+ efree(cm_list[count].cmnd);
}
- free(cm_list);
+ efree(cm_list);
cm_list = NULL;
cm_list_len = 0;
cm_list_size = 0;
if (aliases) {
for (n = 0; n < naliases; n++)
- free(aliases[n].name);
- free(aliases);
+ efree(aliases[n].name);
+ efree(aliases);
aliases = NULL;
}
naliases = nslots = 0;
cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
cm_list[cm_list_len].nopasswd = FALSE;
cm_list[cm_list_len].noexecve = FALSE;
+ cm_list[cm_list_len].setenv = FALSE;
}
/*
/* Free up old data structures if we run the parser more than once. */
if (match) {
- free(match);
+ efree(match);
match = NULL;
top = 0;
parse_error = FALSE;