/*
- * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
+ * Copyright (c) 1996, 1998-2004 Todd C. Miller <Todd.Miller@courtesan.com>
*
- * This code is derived from software contributed by Chris Jepeway.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * 4. Products derived from this software may not be called "Sudo" nor
- * may "Sudo" appear in their names without specific prior written
- * permission from the author.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
+#define _SUDO_MAIN
+
#include "config.h"
#include <sys/param.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_FNMATCH
# include <fnmatch.h>
-#endif /* HAVE_FNMATCH_H */
+#endif /* HAVE_FNMATCH */
#ifdef HAVE_NETGROUP_H
# include <netgroup.h>
#endif /* HAVE_NETGROUP_H */
+#ifdef HAVE_ERR_H
+# include <err.h>
+#else
+# include "emul/err.h"
+#endif /* HAVE_ERR_H */
#include <ctype.h>
#include <pwd.h>
#include <grp.h>
#endif /* HAVE_FNMATCH */
#ifndef lint
-static const char rcsid[] = "$Sudo: testsudoers.c,v 1.76 2002/03/16 00:44:48 millert Exp $";
+static const char rcsid[] = "$Sudo: testsudoers.c,v 1.88 2004/08/02 18:44:58 millert Exp $";
#endif /* lint */
*/
void init_parser __P((void));
void dumpaliases __P((void));
-void set_perms_dummy __P((int, int));
+void set_perms_dummy __P((int));
/*
* Globals
*/
-char **Argv, **NewArgv;
int Argc, NewArgc;
+char **Argv, **NewArgv;
int parse_error = FALSE;
int num_interfaces;
struct interface *interfaces;
struct sudo_user sudo_user;
-void (*set_perms) __P((int, int)) = set_perms_dummy;
extern int clearaliases;
extern int pedantic;
+void (*set_perms) __P((int)) = set_perms_dummy;
/*
* Returns TRUE if "s" has shell meta characters in it,
char *s;
{
char *t;
-
+
for (t = s; *t; t++) {
if (*t == '\\' || *t == '?' || *t == '*' || *t == '[' || *t == ']')
return(TRUE);
}
/*
- * Returns TRUE if cmnd matches, in the sudo sense,
+ * Returns TRUE if user_cmnd matches, in the sudo sense,
* the pathname in path; otherwise, return FALSE
*/
int
-command_matches(cmnd, cmnd_args, path, sudoers_args)
- char *cmnd;
- char *cmnd_args;
+command_matches(path, sudoers_args)
char *path;
char *sudoers_args;
{
int clen, plen;
char *args;
- if (cmnd == NULL)
+ if (user_cmnd == NULL)
return(FALSE);
- if ((args = strchr(path, ' ')))
+ if ((args = strchr(path, ' ')))
*args++ = '\0';
if (has_meta(path)) {
- if (fnmatch(path, cmnd, FNM_PATHNAME))
+ if (fnmatch(path, user_cmnd, FNM_PATHNAME))
return(FALSE);
if (!sudoers_args)
return(TRUE);
- else if (!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args))
+ else if (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args))
return(TRUE);
else if (sudoers_args)
- return((fnmatch(sudoers_args, cmnd_args ? cmnd_args : "", 0) == 0));
+ return((fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0));
else
return(FALSE);
} else {
plen = strlen(path);
if (path[plen - 1] != '/') {
- if (strcmp(cmnd, path))
+ if (strcmp(user_cmnd, path))
return(FALSE);
if (!sudoers_args)
return(TRUE);
- else if (!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args))
+ else if (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args))
return(TRUE);
else if (sudoers_args)
- return((fnmatch(sudoers_args, cmnd_args ? cmnd_args : "", 0) == 0));
+ return((fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0));
else
return(FALSE);
}
- clen = strlen(cmnd);
+ clen = strlen(user_cmnd);
if (clen < plen + 1)
- /* path cannot be the parent dir of cmnd */
+ /* path cannot be the parent dir of user_cmnd */
return(FALSE);
- if (strchr(cmnd + plen + 1, '/') != NULL)
- /* path could only be an anscestor of cmnd -- */
+ if (strchr(user_cmnd + plen + 1, '/') != NULL)
+ /* path could only be an anscestor of user_cmnd -- */
/* ignoring, of course, things like // & /./ */
return(FALSE);
- /* see whether path is the prefix of cmnd */
- return((strncmp(cmnd, path, plen) == 0));
+ /* see whether path is the prefix of user_cmnd */
+ return((strncmp(user_cmnd, path, plen) == 0));
}
}
mask.s_addr <<= i;
mask.s_addr = htonl(mask.s_addr);
}
- *(m - 1) = '/';
+ *(m - 1) = '/';
for (i = 0; i < num_interfaces; i++)
if ((interfaces[i].addr.s_addr & mask.s_addr) == addr.s_addr)
char *lhost;
char *pattern;
{
- if (has_meta(pattern)) {
- if (strchr(pattern, '.'))
+ if (has_meta(pattern)) {
+ if (strchr(pattern, '.'))
return(fnmatch(pattern, lhost, FNM_CASEFOLD));
else
return(fnmatch(pattern, shost, FNM_CASEFOLD));
}
int
-usergr_matches(group, user)
+userpw_matches(sudoers_user, user, pw)
+ char *sudoers_user;
+ char *user;
+ struct passwd *pw;
+{
+ if (pw != NULL && *sudoers_user == '#') {
+ uid_t uid = atoi(sudoers_user + 1);
+ if (uid == pw->pw_uid)
+ return(1);
+ }
+ return(strcmp(sudoers_user, user) == 0);
+}
+
+int
+usergr_matches(group, user, pw)
char *group;
char *user;
+ struct passwd *pw;
{
struct group *grp;
char **cur;
if (*group++ != '%')
return(FALSE);
- if ((grp = getgrnam(group)) == NULL)
+ if ((grp = getgrnam(group)) == NULL)
return(FALSE);
/*
}
void
-set_perms_dummy(i, j)
- int i, j;
+set_perms_dummy(i)
+ int i;
{
return;
}
return;
}
+int
+set_runaspw(user)
+ char *user;
+{
+ return(TRUE);
+}
+
void
init_envtables()
{
NewArgc = Argc - 3;
} else {
(void) fprintf(stderr,
- "usage: %s [-u user] <user> <host> <command> [args]\n", Argv[0]);
+ "usage: sudo [-u user] <user> <host> <command> [args]\n");
exit(1);
}
user_shost = user_host;
}
- /* Fill in cmnd_args from NewArgv. */
+ /* Fill in user_args from NewArgv. */
if (NewArgc > 1) {
- size_t size;
char *to, **from;
+ size_t size, n;
- size = (size_t) NewArgv[NewArgc-1] + strlen(NewArgv[NewArgc-1]) -
- (size_t) NewArgv[1] + 1;
+ size = (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) +
+ strlen(NewArgv[NewArgc-1]) + 1;
user_args = (char *) emalloc(size);
- for (to = user_args, from = &NewArgv[1]; *from; from++) {
+ for (to = user_args, from = NewArgv + 1; *from; from++) {
+ n = strlcpy(to, *from, size - (to - user_args));
+ if (n >= size - (to - user_args))
+ errx(1, "internal error, init_vars() overflow");
+ to += n;
*to++ = ' ';
- (void) strcpy(to, *from);
- to += strlen(*from);
}
+ *--to = '\0';
}
/* Initialize default values. */