# 2.11BSD#431 - /usr/src/libexec/tcpd/inetcf.c

##### Functions

    inet_cfg          X
    inet_get          X
    inet_set          X

##### Variables

    inet_files        X

##### struct's

    inet_ent          X

       1:  /*
       2:   * Routines to parse an inetd.conf or tlid.conf file. This would be a great
       3:   * job for a PERL script.
       4:   *
       5:   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
       6:   */
       7:
       8: #ifndef lint
       9: static char sccsid[] = "@(#) inetcf.c 1.5 95/01/30 19:51:48";
      10: #endif
      11:
      12: #include <sys/types.h>
      13: #include <sys/stat.h>
      14: #include <stdio.h>
      15: #include <errno.h>
      16: #include <string.h>
      17:
      18: extern int errno;
      19: extern void exit();
      20:
      21: #include "tcpd.h"
      22: #include "inetcf.h"
      23:
      24:  /*
      25:   * Network configuration files may live in unusual places. Here are some
      26:   * guesses. Shorter names follow longer ones.
      27:   */
      28: char   *inet_files[] = {
      29:     "/private/etc/inetd.conf",      /* NEXT */
      30:     "/etc/inet/inetd.conf",     /* SYSV4 */
      31:     "/usr/etc/inetd.conf",      /* IRIX?? */
      32:     "/etc/inetd.conf",          /* BSD */
      33:     "/etc/net/tlid.conf",       /* SYSV4?? */
      34:     "/etc/saf/tlid.conf",       /* SYSV4?? */
      35:     "/etc/tlid.conf",           /* SYSV4?? */
      36:     0,
      37: };
      38:
      39: static void inet_chk();
      40: static char *base_name();
      41:
      42:  /*
      43:   * Structure with everything we know about a service.
      44:   */
      45: struct inet_ent {
      46:     struct inet_ent *next;
      47:     int     type;
      48:     char    name[1];
      49: };
      50:
      51: static struct inet_ent *inet_list = 0;
      52:
      53: static char whitespace[] = " \t\r\n";
      54:
      55: /* inet_conf - read in and examine inetd.conf (or tlid.conf) entries */
      56:
      57: char   *inet_cfg(conf)
      58: char   *conf;
      59: {
      60:     char    buf[BUFSIZ];
      61:     FILE   *fp;
      62:     char   *service;
      63:     char   *protocol;
      64:     char   *user;
      65:     char   *path;
      66:     char   *arg0;
      67:     char   *arg1;
      68:     struct tcpd_context saved_context;
      69:     char   *percent_m();
      70:     int     i;
      71:     struct stat st;
      72:
      73:     saved_context = tcpd_context;
      74:
      75:     /*
      76:      * The inetd.conf (or tlid.conf) information is so useful that we insist
      77:      * on its availability. When no file is given run a series of educated
      78:      * guesses.
      79:      */
      80:     if (conf != 0) {
      81:     if ((fp = fopen(conf, "r")) == 0) {
      82:         fprintf(stderr, percent_m(buf, "open %s: %m\n"), conf);
      83:         exit(1);
      84:     }
      85:     } else {
      86:     for (i = 0; inet_files[i] && (fp = fopen(inet_files[i], "r")) == 0; i++)
      87:          /* void */ ;
      88:     if (fp == 0) {
      89:         fprintf(stderr, "Cannot find your inetd.conf or tlid.conf file.\n");
      90:         fprintf(stderr, "Please specify its location.\n");
      91:         exit(1);
      92:     }
      93:     conf = inet_files[i];
      94:     check_path(conf, &st);
      95:     }
      96:
      97:     /*
      98:      * Process the file. After the 7.0 wrapper release it became clear that
      99:      * there are many more inetd.conf formats than the 8 systems that I had
     100:      * studied. EP/IX uses a two-line specification for rpc services; HP-UX
     101:      * permits long lines to be broken with backslash-newline.
     102:      */
     103:     tcpd_context.file = conf;
     104:     tcpd_context.line = 0;
     105:     while (xgets(buf, sizeof(buf), fp)) {
     106:     service = strtok(buf, whitespace);  /* service */
     107:     if (service == 0 || *service == '#')
     108:         continue;
     109:     if (STR_NE(service, "stream") && STR_NE(service, "dgram"))
     110:         strtok((char *) 0, whitespace); /* endpoint */
     111:     protocol = strtok((char *) 0, whitespace);
     112:     (void) strtok((char *) 0, whitespace);  /* wait */
     113:     if ((user = strtok((char *) 0, whitespace)) == 0)
     114:         continue;
     115:     if (user[0] == '/') {           /* user */
     116:         path = user;
     117:     } else {                /* path */
     118:         if ((path = strtok((char *) 0, whitespace)) == 0)
     119:         continue;
     120:     }
     121:     if (STR_EQ(path, "internal"))
     122:         continue;
     123:     if (path[strspn(path, "-0123456789")] == 0) {
     124:
     125:         /*
     126: 	     * ConvexOS puts RPC version numbers before path names. Jukka
     127: 	     * Ukkonen <ukkonen@csc.fi>.
     128: 	     */
     129:         if ((path = strtok((char *) 0, whitespace)) == 0)
     130:         continue;
     131:     }
     132:     if ((arg0 = strtok((char *) 0, whitespace)) == 0) {
     133:         tcpd_warn("incomplete line");
     134:         continue;
     135:     }
     136:     if (arg0[strspn(arg0, "0123456789")] == 0) {
     137:
     138:         /*
     139: 	     * We're reading a tlid.conf file, the format is:
     140: 	     *
     141: 	     * ...stuff... path arg_count arguments mod_count modules
     142: 	     */
     143:         if ((arg0 = strtok((char *) 0, whitespace)) == 0) {
     144:         tcpd_warn("incomplete line");
     145:         continue;
     146:         }
     147:     }
     148:     if ((arg1 = strtok((char *) 0, whitespace)) == 0)
     149:         arg1 = "";
     150:
     151:     inet_chk(protocol, path, arg0, arg1);
     152:     }
     153:     fclose(fp);
     154:     tcpd_context = saved_context;
     155:     return (conf);
     156: }
     157:
     158: /* inet_chk - examine one inetd.conf (tlid.conf?) entry */
     159:
     160: static void inet_chk(protocol, path, arg0, arg1)
     161: char   *protocol;
     162: char   *path;
     163: char   *arg0;
     164: char   *arg1;
     165: {
     166:     char    daemon[BUFSIZ];
     167:     struct stat st;
     168:     int     wrap_status = WR_MAYBE;
     169:     char   *base_name_path = base_name(path);
     170:     char   *tcpd_proc_name = (arg0[0] == '/' ? base_name(arg0) : arg0);
     171:
     172:     /*
     173:      * Always warn when the executable does not exist or when it is not
     174:      * executable.
     175:      */
     176:     if (check_path(path, &st) < 0) {
     177:     tcpd_warn("%s: not found: %m", path);
     178:     } else if ((st.st_mode & 0100) == 0) {
     179:     tcpd_warn("%s: not executable", path);
     180:     }
     181:
     182:     /*
     183:      * Cheat on the miscd tests, nobody uses it anymore.
     184:      */
     185:     if (STR_EQ(base_name_path, "miscd")) {
     186:     inet_set(arg0, WR_YES);
     187:     return;
     188:     }
     189:
     190:     /*
     191:      * While we are here...
     192:      */
     193:     if (STR_EQ(tcpd_proc_name, "rexd") || STR_EQ(tcpd_proc_name, "rpc.rexd"))
     194:     tcpd_warn("%s may be an insecure service", tcpd_proc_name);
     195:
     196:     /*
     197:      * The tcpd program gets most of the attention.
     198:      */
     199:     if (STR_EQ(base_name_path, "tcpd")) {
     200:
     201:     wrap_status = WR_YES;
     202:
     203:     /*
     204: 	 * Check: some sites install the wrapper set-uid.
     205: 	 */
     206:     if ((st.st_mode & 06000) != 0)
     207:         tcpd_warn("%s: file is set-uid or set-gid", path);
     208:
     209:     /*
     210: 	 * Check: some sites insert tcpd in inetd.conf, instead of replacing
     211: 	 * the daemon pathname.
     212: 	 */
     213:     if (arg0[0] == '/' && STR_EQ(tcpd_proc_name, base_name(arg1)))
     214:         tcpd_warn("%s inserted before %s", path, arg0);
     215:
     216:     /*
     217: 	 * Check: make sure files exist and are executable. On some systems
     218: 	 * the network daemons are set-uid so we cannot complain. Note that
     219: 	 * tcpd takes the basename only in case of absolute pathnames.
     220: 	 */
     221:     if (arg0[0] == '/') {           /* absolute path */
     222:         if (check_path(arg0, &st) < 0) {
     223:         tcpd_warn("%s: not found: %m", arg0);
     224:         } else if ((st.st_mode & 0100) == 0) {
     225:         tcpd_warn("%s: not executable", arg0);
     226:         }
     227:     } else {                /* look in REAL_DAEMON_DIR */
     228:         sprintf(daemon, "%s/%s", REAL_DAEMON_DIR, arg0);
     229:         if (check_path(daemon, &st) < 0) {
     230:         tcpd_warn("%s: not found in %s: %m",
     231:               arg0, REAL_DAEMON_DIR);
     232:         } else if ((st.st_mode & 0100) == 0) {
     233:         tcpd_warn("%s: not executable", daemon);
     234:         }
     235:     }
     236:
     237:     } else {
     238:
     239:     /*
     240: 	 * No tcpd program found. Perhaps they used the "simple installation"
     241: 	 * recipe. Look for a file with the same basename in REAL_DAEMON_DIR.
     242: 	 * Draw some conservative conclusions when a distinct file is found.
     243: 	 */
     244:     sprintf(daemon, "%s/%s", REAL_DAEMON_DIR, arg0);
     245:     if (STR_EQ(path, daemon)) {
     246:         wrap_status = WR_NOT;
     247:     } else if (check_path(daemon, &st) >= 0) {
     248:         wrap_status = WR_MAYBE;
     249:     } else if (errno == ENOENT) {
     250:         wrap_status = WR_NOT;
     251:     } else {
     252:         tcpd_warn("%s: file lookup: %m", daemon);
     253:         wrap_status = WR_MAYBE;
     254:     }
     255:     }
     256:
     257:     /*
     258:      * Alas, we cannot wrap rpc/tcp services.
     259:      */
     260:     if (wrap_status == WR_YES && STR_EQ(protocol, "rpc/tcp"))
     261:     tcpd_warn("%s: cannot wrap rpc/tcp services", tcpd_proc_name);
     262:
     263:     inet_set(tcpd_proc_name, wrap_status);
     264: }
     265:
     266: /* inet_set - remember service status */
     267:
     268: void    inet_set(name, type)
     269: char   *name;
     270: int     type;
     271: {
     272:     struct inet_ent *ip =
     273:     (struct inet_ent *) malloc(sizeof(struct inet_ent) + strlen(name));
     274:
     275:     if (ip == 0) {
     276:     fprintf(stderr, "out of memory\n");
     277:     exit(1);
     278:     }
     279:     ip->next = inet_list;
     280:     strcpy(ip->name, name);
     281:     ip->type = type;
     282:     inet_list = ip;
     283: }
     284:
     285: /* inet_get - look up service status */
     286:
     287: int     inet_get(name)
     288: char   *name;
     289: {
     290:     struct inet_ent *ip;
     291:
     292:     if (inet_list == 0)
     293:     return (WR_MAYBE);
     294:
     295:     for (ip = inet_list; ip; ip = ip->next)
     296:     if (STR_EQ(ip->name, name))
     297:         return (ip->type);
     298:
     299:     return (-1);
     300: }
     301:
     302: /* base_name - compute last pathname component */
     303:
     304: static char *base_name(path)
     305: char   *path;
     306: {
     307:     char   *cp;
     308:
     309:     if ((cp = strrchr(path, '/')) != 0)
     310:     path = cp + 1;
     311:     return (path);
     312: }

#### Defined functions

base_name defined in line 304; used 4 times

- in line 40, 169-170(2), 213

inet_cfg defined in line 57; used 3 times

- in /usr/src/libexec/tcpd/inetcf.h line 7
- in /usr/src/libexec/tcpd/tcpdchk.c line 126
- in /usr/src/libexec/tcpd/tcpdmatch.c line 127

inet_chk defined in line 160; used 2 times

- in line 39, 151

inet_get defined in line 287; used 3 times

- in /usr/src/libexec/tcpd/inetcf.h line 9
- in /usr/src/libexec/tcpd/tcpdchk.c line 350
- in /usr/src/libexec/tcpd/tcpdmatch.c line 130

inet_set defined in line 268; used 9 times

- in line 186, 263
- in /usr/src/libexec/tcpd/inetcf.h line 8
- in /usr/src/libexec/tcpd/tcpdchk.c line 133-134(2), 353-357(2)
- in /usr/src/libexec/tcpd/tcpdmatch.c line 128-129(2)

#### Defined variables

inet_files defined in line 28; used 3 times

- in line 86(2), 93

inet_list defined in line 51; used 4 times

- in line 279-282(2), 292-295(2)

sccsid defined in line 9; never used
whitespace defined in line 53; used 10 times

- in line 106-118(6), 129-132(2), 143-148(2)

#### Defined struct's

inet_ent defined in line 45; used 12 times

- in line 46-51(4), 272-273(6), 290(2)

Last modified: 1995-01-30 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 886 |