permsfile.c revision 92906
1230479Snetchild/* permsfile.c: implement SunOS /etc/fbtab and Solaris /etc/logindevperm
2230479Snetchild   functionality to set device permissions on login
3230479Snetchild
4230479Snetchild%%% portions-copyright-cmetz-96
5230479SnetchildPortions of this software are Copyright 1996-1999 by Craig Metz, All Rights
6230479SnetchildReserved. The Inner Net License Version 2 applies to these portions of
7230479Snetchildthe software.
8230479SnetchildYou should have received a copy of the license with this software. If
9230479Snetchildyou didn't get a copy, you may request one from <license@inner.net>.
10230479Snetchild
11230479SnetchildPortions of this software are Copyright 1995 by Randall Atkinson and Dan
12230479SnetchildMcDonald, All Rights Reserved. All Rights under this copyright are assigned
13230479Snetchildto the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
14230479SnetchildLicense Agreement applies to this software.
15230479Snetchild
16230479Snetchild	History:
17230479Snetchild
18230479Snetchild	Modified by cmetz for OPIE 2.31. Include unistd.h.
19230479Snetchild	Modified by cmetz for OPIE 2.3. Check for NULL return from
20230479Snetchild	    ftpglob(), combine some expressions, fix a typo. Made file
21230479Snetchild	    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