From 607937a4e1c4cdb3da09617fa7bfda536278ca95 Mon Sep 17 00:00:00 2001 From: mdw Date: Thu, 7 Aug 1997 09:49:39 +0000 Subject: [PATCH] Extensive modifications to handle netgroups. Also sanitise user and group names before adding them to the symbol table. --- src/check.c | 8 +- src/class.c | 38 +++++---- src/daemon.c | 13 ++- src/dbutils.h | 12 ++- src/name.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 260 insertions(+), 63 deletions(-) diff --git a/src/check.c b/src/check.c index 1d1eba8..34d1e52 100644 --- a/src/check.c +++ b/src/check.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: check.c,v 1.2 1997/08/04 10:24:20 mdw Exp $ + * $Id: check.c,v 1.3 1997/08/07 09:49:38 mdw Exp $ * * Check validity of requests * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: check.c,v $ + * Revision 1.3 1997/08/07 09:49:38 mdw + * Extensive modifications to handle netgroups. Also sanitise user and group + * names before adding them to the symbol table. + * * Revision 1.2 1997/08/04 10:24:20 mdw * Sources placed under CVS control. * @@ -69,6 +73,7 @@ #include "idea.h" #include "lexer.h" #include "name.h" +#include "netg.h" #include "rule.h" #include "parser.h" #include "tx.h" @@ -521,6 +526,7 @@ int check(request *rq) userdb_init(); userdb_local(); userdb_yp(); + netg_init(); name_init(); rule_init(); lexer_scan(fp); diff --git a/src/class.c b/src/class.c index 7a7d016..3ee5f7d 100644 --- a/src/class.c +++ b/src/class.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: class.c,v 1.2 1997/08/04 10:24:21 mdw Exp $ + * $Id: class.c,v 1.3 1997/08/07 09:49:38 mdw Exp $ * * Handling classes of things nicely * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: class.c,v $ + * Revision 1.3 1997/08/07 09:49:38 mdw + * Extensive modifications to handle netgroups. Also sanitise user and group + * names before adding them to the symbol table. + * * Revision 1.2 1997/08/04 10:24:21 mdw * Sources placed under CVS control. * @@ -251,10 +255,9 @@ int class_hostMatch(classdef *c, struct in_addr addr) T( trace(TRACE_CHECK, "check: couldn't translate address (erk!)"); ) return (0); } - if ((he = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)) == 0) { + + if ((he = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)) == 0) T( trace(TRACE_CHECK, "check: couldn't resolve hostname for %s", a); ) - return (0); - } /* --- Now search the list for a match --- * * @@ -271,22 +274,25 @@ int class_hostMatch(classdef *c, struct in_addr addr) return (1); } - /* --- Now try the host's main name --- */ - - if (class__wildMatch(s->name, he->h_name)) { - T( trace(TRACE_CHECK, "check: host name `%s' matched by `%s'", - he->h_name, s->name); ) - return (1); - } + if (he) { - /* --- Now go through all the names --- */ + /* --- Now try the host's main name --- */ - for (p = he->h_aliases; *p; p++) { - if (class__wildMatch(s->name, *p)) { - T( trace(TRACE_CHECK, "check: host alias `%s' matched by `%s'", - *p, s->name); ) + if (class__wildMatch(s->name, he->h_name)) { + T( trace(TRACE_CHECK, "check: host name `%s' matched by `%s'", + he->h_name, s->name); ) return (1); } + + /* --- Now go through all the names --- */ + + for (p = he->h_aliases; *p; p++) { + if (class__wildMatch(s->name, *p)) { + T( trace(TRACE_CHECK, "check: host alias `%s' matched by `%s'", + *p, s->name); ) + return (1); + } + } } } diff --git a/src/daemon.c b/src/daemon.c index 3f1fa93..d2bf8df 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: daemon.c,v 1.2 1997/08/04 10:24:21 mdw Exp $ + * $Id: daemon.c,v 1.3 1997/08/07 09:49:39 mdw Exp $ * * Running a `become' daemon * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: daemon.c,v $ + * Revision 1.3 1997/08/07 09:49:39 mdw + * Extensive modifications to handle netgroups. Also sanitise user and group + * names before adding them to the symbol table. + * * Revision 1.2 1997/08/04 10:24:21 mdw * Sources placed under CVS control. * @@ -71,6 +75,7 @@ #include "idea.h" #include "lexer.h" #include "name.h" +#include "netg.h" #include "parser.h" #include "rule.h" #include "tx.h" @@ -79,7 +84,7 @@ /*----- Arbitrary constants -----------------------------------------------*/ -#define daemon__awakeEvery (5 * 60) /* Awaken this often to rescan */ +#define daemon__awakeEvery (30 * 60) /* Awaken this often to rescan */ /*----- Static variables --------------------------------------------------*/ @@ -286,7 +291,7 @@ void daemon_init(const char *cf, int port) * user wants me to start on a funny port. */ - seteuid(getuid()); + setuid(getuid()); /* --- Initialise bits of the program --- */ @@ -295,6 +300,7 @@ void daemon_init(const char *cf, int port) userdb_init(); userdb_local(); userdb_yp(); + netg_init(); name_init(); rule_init(); openlog(quis(), 0, LOG_DAEMON); @@ -423,6 +429,7 @@ void daemon_init(const char *cf, int port) userdb_reinit(); userdb_local(); userdb_yp(); + netg_reinit(); rule_reinit(); name_reinit(); if (daemon__readConfig(cf)) diff --git a/src/dbutils.h b/src/dbutils.h index 89dff81..07fa275 100644 --- a/src/dbutils.h +++ b/src/dbutils.h @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: dbutils.h,v 1.2 1997/08/04 10:24:22 mdw Exp $ + * $Id: dbutils.h,v 1.3 1997/08/07 09:49:39 mdw Exp $ * * Debugging things * * (c) 1996 Straylight */ -/*----- Licencing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of `become' * @@ -22,13 +22,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with `become'; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*----- Revision history --------------------------------------------------* * * $Log: dbutils.h,v $ + * Revision 1.3 1997/08/07 09:49:39 mdw + * Extensive modifications to handle netgroups. Also sanitise user and group + * names before adding them to the symbol table. + * * Revision 1.2 1997/08/04 10:24:22 mdw * Sources placed under CVS control. * diff --git a/src/name.c b/src/name.c index fe61272..aaf7491 100644 --- a/src/name.c +++ b/src/name.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: name.c,v 1.2 1997/08/04 10:24:24 mdw Exp $ + * $Id: name.c,v 1.3 1997/08/07 09:49:39 mdw Exp $ * * Looking up of names in symbol tables * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: name.c,v $ + * Revision 1.3 1997/08/07 09:49:39 mdw + * Extensive modifications to handle netgroups. Also sanitise user and group + * names before adding them to the symbol table. + * * Revision 1.2 1997/08/04 10:24:24 mdw * Sources placed under CVS control. * @@ -41,27 +45,32 @@ /* --- ANSI headers --- */ +#include #include #include #include /* --- Unix headers --- */ -#include "config.h" +#include +#include -#ifdef HAVE_YP -# include -# include -#endif +#include +#include + +#include #include #include /* --- Local headers --- */ +#include "config.h" + #include "become.h" #include "class.h" #include "name.h" +#include "netg.h" #include "sym.h" #include "userdb.h" #include "utils.h" @@ -72,6 +81,59 @@ static sym_table name__table; /* Symbol table for everything */ /*----- Main code ---------------------------------------------------------*/ +/* --- @name__get@ --- * + * + * Arguments: @const char *p@ = pointer to the name we want + * @unsigned type@ = type of class it should have + * + * Returns: A pointer to a name ready to use, or zero if there's a type + * conflict. + * + * Use: Creates a name of the appropriate type all ready to use. + */ + +static name *name__get(const char *p, unsigned type) +{ + unsigned f; + name *n = sym_find(&name__table, p, -1, sizeof(*n), &f); + if (!f) { + sym_table *t = xmalloc(sizeof(*t)); + sym_createTable(t); + n->c = class_create(type, t); + } + return (n->c->type == type ? n : 0); +} + +/* --- @name__sanitise@ --- * + * + * Arguments: @const char *n@ = pointer to a name + * @char *buf@ = pointer to a buffer of space + * @size_t sz@ = size of the buffer + * + * Returns: A pointer to the transformed name in the buffer, or null + * if there wasn't enough space. + * + * Use: Transforms a name so that it only contains nice characters. + */ + +static char *name__sanitise(const char *n, char *buf, size_t sz) +{ + char *p = buf; + + if (strlen(n) + 1 > sz) + return (0); + + while (*n) { + if (isalnum((unsigned char)*n)) + *p++ = *n; + else + *p++ = '_'; + n++; + } + *p++ = 0; + return (buf); +} + /* --- @name__users@ --- * * * Arguments: --- @@ -86,35 +148,27 @@ static void name__users(void) { struct passwd *pw; struct group *gr; + char buf[32]; userdb_iterateUsers(); while ((pw = userdb_nextUser()) != 0) { - unsigned f; name *n; - int u; + int u = pw->pw_uid; + + /* --- Make the name into something nice --- */ /* --- First, add the user to the table --- */ - n = sym_find(&name__table, pw->pw_name, -1, sizeof(name), &f); - if (!f) { - sym_table *t = xmalloc(sizeof(*t)); - sym_createTable(t); - n->c = class_create(clType_user, t); - } - u = pw->pw_uid; - sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0); + if (name__sanitise(pw->pw_name, buf, sizeof(buf)) && + (n = name__get(buf, clType_user)) != 0) + sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0); /* --- Now handle the user's default group --- */ - if ((gr = userdb_groupById(pw->pw_gid)) != 0) { - n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f); - if (!f) { - sym_table *t = xmalloc(sizeof(*t)); - sym_createTable(t); - n->c = class_create(clType_user, t); - } + if ((gr = userdb_groupById(pw->pw_gid)) != 0 && + name__sanitise(gr->gr_name, buf, sizeof(buf)) && + (n = name__get(buf, clType_user)) != 0) sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0); - } } } @@ -132,30 +186,147 @@ static void name__groups(void) struct group *gr; struct passwd *pw; char **p; + char buf[32]; userdb_iterateGroups(); while ((gr = userdb_nextGroup()) != 0) { - unsigned f; name *n; int u; - /* --- Add the group name to the table --- */ + if (name__sanitise(gr->gr_name, buf, sizeof(buf)) && + (n = name__get(buf, clType_user)) != 0) { - n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f); - if (!f) { - sym_table *t = xmalloc(sizeof(*t)); - sym_createTable(t); - n->c = class_create(clType_user, t); + /* --- Now add all of the members --- */ + + for (p = gr->gr_mem; *p; p++) { + if ((pw = userdb_userByName(*p)) != 0) { + u = pw->pw_uid; + sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0); + } + } } + } +} - /* --- Now add all of the members --- */ +/* --- @name__scan@ --- * + * + * Arguments: @netg *n@ = the netgroup handle we're scanning + * @const char *host@ = the host name + * @const char *user@ = the user name + * @const char *domain@ = the (NIS?) domain name + * @void *ctx@ = some context pointer + * + * Returns: Zero to continue scanning. + * + * Use: Scans a netgroup, adding items to the name table. + */ + +/* --- A data type --- */ + +typedef struct name__scanctx { + char *name; /* Netgroup name prefixed with `?_'*/ + unsigned f; /* Various interesting flags */ + name *h; /* Name entry for hosts */ + name *u; /* Name entry for users */ +} name__scanctx; + +enum { f_host = 1, f_user = 2 }; + +/* --- And now for the real code --- */ + +static int name__scan(netg *n, const char *host, const char *user, + const char *domain, void *ctx) +{ + name__scanctx *sc = ctx; + + /* --- Add the host to the hosts class --- */ + + if (sc->f & f_host && host) { + struct hostent *h; + struct in_addr in; + const char *a; + + /* --- First ensure that I have a host class --- */ + + if (!sc->h) { + sc->name[0] = 'h'; + sc->h = name__get(sc->name, clType_host); + if (!sc->h) { + sc->f &= ~f_host; + goto done_host; + } + } + + /* --- Now that I've done that, try to add the host --- * + * + * I'll turn it into an IP address. There's less chance of confusion + * that way. + */ + + if ((h = gethostbyname(host)) == 0) + goto done_host; + memcpy(&in, h->h_addr, sizeof(in)); + if ((a = inet_ntoa(in)) == 0) + goto done_host; + sym_find(sc->h->c->t, a, -1, sizeof(sym_base), 0); + done_host:; + } + + /* --- Add the user to the users class --- */ - for (p = gr->gr_mem; *p; p++) { - if ((pw = userdb_userByName(*p)) != 0) { - u = pw->pw_uid; - sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0); + if (sc->f & f_user && user) { + struct passwd *pw; + int u; + + /* --- First ensure that I have a user class --- */ + + if (!sc->u) { + sc->name[0] = 'u'; + sc->u = name__get(sc->name, clType_user); + if (!sc->u) { + sc->f &= ~f_user; + goto done_user; } } + + /* --- Add the user to the list --- */ + + if ((pw = userdb_userByName(user)) == 0) + goto done_user; + u = pw->pw_uid; + sym_find(sc->u->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0); + done_user:; + } + + return (0); +} + +/* --- @name__netgroups@ --- * + * + * Arguments: --- + * + * Returns: --- + * + * Use: Populates the name table with netgroup information. + */ + +void name__netgroups(void) +{ + netg *n; + char buf[32]; + const char *p; + name__scanctx sc; + + netg_iterate(); + buf[1] = '_'; + while ((n = netg_next()) != 0) { + p = netg_name(n); + if (name__sanitise(p, buf + 2, sizeof(buf) - 2) == 0) + continue; + sc.name = buf; + sc.u = sc.h = 0; + sc.f = f_host | f_user; + netg_scan(n, name__scan, &sc); } } @@ -166,7 +337,8 @@ static void name__groups(void) * Returns: --- * * Use: Initialises the name table. Requires the user database to - * be populated (see @userdb_local@ and @userdb_yp@). + * be populated (see @userdb_local@ and @userdb_yp@, and + * @netg_init@). */ void name_init(void) @@ -179,6 +351,7 @@ void name_init(void) name__users(); name__groups(); + name__netgroups(); /* --- Finally add in the `all' class --- * * @@ -275,11 +448,12 @@ void name_dump(void) int main(void) { + ego("name-test"); + traceon(stdout, TRACE_ALL); userdb_init(); userdb_local(); userdb_yp(); - ego("name-test"); - traceon(stdout, TRACE_DEBUG); + netg_init(); name_init(); name_dump(); return (0); -- 2.11.0