Merge branch 'vendor/OPENSSH'
[dragonfly.git] / contrib / opie / permsfile.c
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 */