permsfile.c revision 73569
1143880Spjd/* permsfile.c: implement SunOS /etc/fbtab and Solaris /etc/logindevperm
2143880Spjd   functionality to set device permissions on login
3143880Spjd
4143880Spjd%%% portions-copyright-cmetz-96
5143880SpjdPortions of this software are Copyright 1996-1998 by Craig Metz, All Rights
6143880SpjdReserved. The Inner Net License Version 2 applies to these portions of
7143880Spjdthe software.
8143880SpjdYou should have received a copy of the license with this software. If
9143880Spjdyou didn't get a copy, you may request one from <license@inner.net>.
10143880Spjd
11143880SpjdPortions of this software are Copyright 1995 by Randall Atkinson and Dan
12143880SpjdMcDonald, All Rights Reserved. All Rights under this copyright are assigned
13143880Spjdto the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
14143880SpjdLicense Agreement applies to this software.
15143880Spjd
16143880Spjd	History:
17143880Spjd
18143880Spjd	Modified by cmetz for OPIE 2.31. Include unistd.h.
19143880Spjd	Modified by cmetz for OPIE 2.3. Check for NULL return from
20143880Spjd	    ftpglob(), combine some expressions, fix a typo. Made file
21143880Spjd	    selection a bit more generic.
22143880Spjd	Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
23143880Spjd            Add opie.h. Ifdef around a header.
24143880Spjd	Written at NRL for OPIE 2.0.
25*/
26
27#include "opie_cfg.h"
28#ifdef HAVE_LOGIN_PERMFILE
29#include <stdio.h>
30#include <sys/types.h>
31#if HAVE_STRING_H
32#include <string.h>
33#endif /* HAVE_STRING_H */
34#if HAVE_UNISTD_H
35#include <unistd.h>
36#endif /* HAVE_UNISTD_H */
37#include <syslog.h>
38#include "opie.h"
39
40/* Line buffer size (one more than max line length) */
41#define BUFSIZE 128
42/* Maximum number of list items in a field */
43#define LISTSIZE 10
44
45static char buf[BUFSIZE], buf2[8];
46
47char **ftpglob __P((char *));
48
49VOIDRET opiefatal FUNCTION((x), char *x)
50{
51  fprintf(stderr, "%s", x);
52  exit(1);
53}
54
55#include "glob.c"
56
57static int getalist FUNCTION((string, list), char **string AND char **list)
58{
59  char *s = *string;
60  int i = 0;
61
62  while (*s && (*s != '\n') && (*s != ' ') && (*s != '\t'))
63    if ((*s == ':') || (*s == ',')) {
64      *(s++) = 0;
65      list[i++] = *string;
66      *string = s;
67      if (i == LISTSIZE)
68	return i;
69    } else
70      s++;
71
72  if ((int) (s) - (int) (*string)) {
73    *s = 0;
74    list[i++] = *string;
75  }
76  *string = ++s;
77
78  return i;
79}
80
81static VOIDRET doaline FUNCTION((line, name, ttyn, uid, gid), char *line AND char *name AND char *ttyn AND uid_t uid AND gid_t gid)
82{
83  char *ptr;
84  int i;
85  int applies, llen;
86  char *listbuf[LISTSIZE], **globlist;
87
88  if (ptr = strchr(buf, '#'))
89    *ptr = 0;
90
91  /* Skip whitespace */
92  for (ptr = buf; *ptr && ((*ptr == ' ') || (*ptr == '\t'));
93       ptr++);
94
95  if (!*ptr)
96    return;
97
98  /* (Optional) Field 1: user name(s) */
99  if ((*ptr != '/') && (*ptr != '~')) {
100    llen = getalist(&ptr, listbuf);
101    for (applies = i = 0; (i < llen) && !applies; i++)
102      if (!strcmp(listbuf[i], name))
103	applies++;
104    while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
105      ptr++;
106    if (!applies || !*ptr)
107      return;
108  }
109  /* Field 2: terminal(s) */
110  llen = getalist(&ptr, listbuf);
111  for (applies = i = 0; (i < llen) && !applies; i++)
112    if (!strcmp(listbuf[i], ttyn))
113      applies++;
114
115  while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
116    ptr++;
117
118  if (!applies || !*ptr)
119    return;
120
121  /* Field 3: mode */
122  for (applies = 0; *ptr && (*ptr >= '0') && (*ptr <= '7');
123       applies = (applies << 3) | (*(ptr++) - '0'));
124
125  while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
126    ptr++;
127
128  if (!*ptr)
129    return;
130
131  /* Field 4: devices (the fun part...) */
132  llen = getalist(&ptr, listbuf);
133  for (i = 0; i < llen; i++) {
134    if (globlist = ftpglob(listbuf[i]))
135      while (*globlist) {
136#ifdef DEBUG
137        syslog(LOG_DEBUG, "setting %s to %d/%d %o", *globlist, uid, gid, applies);
138#endif /* DEBUG */
139        if ((chown(*globlist, uid, gid) < 0) && (errno != ENOENT))
140	  perror("chown");
141        if ((chmod(*(globlist++), applies) < 0) && (errno != ENOENT))
142	  perror("chmod");
143    }
144  }
145}
146
147VOIDRET permsfile FUNCTION((name, ttyn, uid, gid), char *name AND char *ttyn AND uid_t uid AND gid_t gid)
148{
149  FILE *fh;
150
151  if (!(fh = fopen(HAVE_LOGIN_PERMFILE, "r"))) {
152    syslog(LOG_ERR, "Can't open %s!", HAVE_LOGIN_PERMFILE);
153    fprintf(stderr, "Warning: Can't set device permissions.\n");
154    return;
155  }
156  do {
157    if (feof(fh))
158      return;
159    if (fgets(buf, BUFSIZE, fh) == NULL)
160      return;
161    buf[BUFSIZE] = 0;
162
163    doaline(buf, name, ttyn, uid, gid);
164  }
165  while (1);
166}
167#endif /* HAVE_LOGIN_PERMFILE */
168