permsfile.c revision 225736
1/* permsfile.c: implement SunOS /etc/fbtab and Solaris /etc/logindevperm
2   functionality to set device permissions on login
3
4%%% portions-copyright-cmetz-96
5Portions of this software are Copyright 1996-1999 by Craig Metz, All Rights
6Reserved. The Inner Net License Version 2 applies to these portions of
7the software.
8You should have received a copy of the license with this software. If
9you didn't get a copy, you may request one from <license@inner.net>.
10
11Portions of this software are Copyright 1995 by Randall Atkinson and Dan
12McDonald, All Rights Reserved. All Rights under this copyright are assigned
13to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
14License Agreement applies to this software.
15
16	History:
17
18	Modified by cmetz for OPIE 2.31. Include unistd.h.
19	Modified by cmetz for OPIE 2.3. Check for NULL return from
20	    ftpglob(), combine some expressions, fix a typo. Made file
21	    selection a bit more generic.
22	Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
23            Add opie.h. Ifdef around a header.
24	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, 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