xref: /NextBSD/contrib/opie/permsfile.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
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
5 Portions of this software are Copyright 1996-1999 by Craig Metz, All Rights
6 Reserved. The Inner Net License Version 2 applies to these portions of
7 the software.
8 You should have received a copy of the license with this software. If
9 you didn't get a copy, you may request one from <license@inner.net>.
10 
11 Portions of this software are Copyright 1995 by Randall Atkinson and Dan
12 McDonald, All Rights Reserved. All Rights under this copyright are assigned
13 to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
14 License 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 
45 static char buf[BUFSIZE], buf2[8];
46 
47 char **ftpglob __P((char *));
48 
49 VOIDRET opiefatal FUNCTION((x), char *x)
50 {
51   fprintf(stderr, x);
52   exit(1);
53 }
54 
55 #include "glob.c"
56 
57 static 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 
81 static 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 
147 VOIDRET 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