Extensive modifications to handle netgroups. Also sanitise user and group
authormdw <mdw>
Thu, 7 Aug 1997 09:49:39 +0000 (09:49 +0000)
committermdw <mdw>
Thu, 7 Aug 1997 09:49:39 +0000 (09:49 +0000)
names before adding them to the symbol table.

src/check.c
src/class.c
src/daemon.c
src/dbutils.h
src/name.c

index 1d1eba8..34d1e52 100644 (file)
@@ -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
  *
 /*----- 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);
index 7a7d016..3ee5f7d 100644 (file)
@@ -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
  *
 /*----- 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);
+         }
+       }
       }
     }
 
index 3f1fa93..d2bf8df 100644 (file)
@@ -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
  *
 /*----- 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))
index 89dff81..07fa275 100644 (file)
@@ -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'
  *
  * 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.
  *
index fe61272..aaf7491 100644 (file)
@@ -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
  *
 /*----- 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.
  *
 
 /* --- ANSI headers --- */
 
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 /* --- Unix headers --- */
 
-#include "config.h"
+#include <sys/types.h>
+#include <sys/socket.h>
 
-#ifdef HAVE_YP
-#  include <rpcsvc/ypclnt.h>
-#  include <rpcsvc/yp_prot.h>
-#endif
+#include <netinet/in.h>
 
+#include <arpa/inet.h>
+
+#include <netdb.h>
 #include <grp.h>
 #include <pwd.h>
 
 /* --- 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);