]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libutil/login_ok.c
libpfctl: remove unused field from struct pfctl_states
[FreeBSD/FreeBSD.git] / lib / libutil / login_ok.c
1 /*-
2  * Copyright (c) 1996 by
3  * David Nugent <davidn@blaze.net.au>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, is permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice immediately at the beginning of the file, without modification,
11  *    this list of conditions, and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. This work was done expressly for inclusion into FreeBSD.  Other use
16  *    is permitted provided this notation is included.
17  * 4. Absolutely no warranty of function or purpose is made by the authors.
18  * 5. Modifications may be freely made to this file providing the above
19  *    conditions are met.
20  *
21  * Support allow/deny lists in login class capabilities
22  */
23
24 #include <sys/cdefs.h>
25 #include <sys/types.h>
26 #include <sys/time.h>
27 #include <sys/resource.h>
28 #include <sys/param.h>
29 #include <errno.h>
30 #include <fnmatch.h>
31 #include <login_cap.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ttyent.h>
35 #include <unistd.h>
36
37
38 /* -- support functions -- */
39
40 /*
41  * login_strinlist()
42  * This function is intentionally public - reused by TAS.
43  * Returns TRUE (non-zero) if a string matches a pattern
44  * in a given array of patterns. 'flags' is passed directly
45  * to fnmatch(3).
46  */
47
48 int
49 login_strinlist(const char **list, char const *str, int flags)
50 {
51     int rc = 0;
52
53     if (str != NULL && *str != '\0') {
54         int     i = 0;
55
56         while (rc == 0 && list[i] != NULL)
57             rc = fnmatch(list[i++], str, flags) == 0;
58     }
59     return rc;
60 }
61
62
63 /*
64  * login_str2inlist()
65  * Locate either or two strings in a given list
66  */
67
68 int
69 login_str2inlist(const char **ttlst, const char *str1, const char *str2, int flags)
70 {
71     int     rc = 0;
72
73     if (login_strinlist(ttlst, str1, flags))
74         rc = 1;
75     else if (login_strinlist(ttlst, str2, flags))
76         rc = 1;
77     return rc;
78 }
79
80
81 /*
82  * login_timelist()
83  * This function is intentionally public - reused by TAS.
84  * Returns an allocated list of time periods given an array
85  * of time periods in ascii form.
86  */
87
88 login_time_t *
89 login_timelist(login_cap_t *lc, char const *cap, int *ltno,
90                login_time_t **ltptr)
91 {
92     int                 j = 0;
93     struct login_time   *lt = NULL;
94     const char          **tl;
95
96     if ((tl = login_getcaplist(lc, cap, NULL)) != NULL) {
97
98         while (tl[j++] != NULL)
99             ;
100         if (*ltno >= j)
101             lt = *ltptr;
102         else if ((lt = realloc(*ltptr, j * sizeof(struct login_time))) != NULL) {
103             *ltno = j;
104             *ltptr = lt;
105         }
106         if (lt != NULL) {
107             int     i = 0;
108
109             for (--j; i < j; i++)
110                 lt[i] = parse_lt(tl[i]);
111             lt[i].lt_dow = LTM_NONE;
112         }
113     }
114     return lt;
115 }
116
117
118 /*
119  * login_ttyok()
120  * This function is a variation of auth_ttyok(), but it checks two
121  * arbitrary capability lists not necessarily related to access.
122  * This hook is provided for the accounted/exclude accounting lists.
123  */
124
125 int
126 login_ttyok(login_cap_t *lc, const char *tty, const char *allowcap,
127             const char *denycap)
128 {
129     int     rc = 1;
130
131     if (lc != NULL && tty != NULL && *tty != '\0') {
132         struct ttyent   *te;
133         char            *grp;
134         const char      **ttl;
135
136         te = getttynam(tty);  /* Need group name */
137         grp = te ? te->ty_group : NULL;
138         ttl = login_getcaplist(lc, allowcap, NULL);
139
140         if (ttl != NULL && !login_str2inlist(ttl, tty, grp, 0))
141             rc = 0;     /* tty or ttygroup not in allow list */
142         else {
143
144             ttl = login_getcaplist(lc, denycap, NULL);
145             if (ttl != NULL && login_str2inlist(ttl, tty, grp, 0))
146                 rc = 0; /* tty or ttygroup in deny list */
147         }
148     }
149
150     return rc;
151 }
152
153
154 /*
155  * auth_ttyok()
156  * Determine whether or not login on a tty is accessible for
157  * a login class
158  */
159
160 int
161 auth_ttyok(login_cap_t *lc, const char * tty)
162 {
163     return login_ttyok(lc, tty, "ttys.allow", "ttys.deny");
164 }
165
166
167 /*
168  * login_hostok()
169  * This function is a variation of auth_hostok(), but it checks two
170  * arbitrary capability lists not necessarily related to access.
171  * This hook is provided for the accounted/exclude accounting lists.
172  */
173
174 int
175 login_hostok(login_cap_t *lc, const char *host, const char *ip,
176              const char *allowcap, const char *denycap)
177 {
178     int     rc = 1; /* Default is ok */
179
180     if (lc != NULL &&
181         ((host != NULL && *host != '\0') || (ip != NULL && *ip != '\0'))) {
182         const char **hl;
183
184         hl = login_getcaplist(lc, allowcap, NULL);
185         if (hl != NULL && !login_str2inlist(hl, host, ip, FNM_CASEFOLD))
186             rc = 0;     /* host or IP not in allow list */
187         else {
188
189             hl = login_getcaplist(lc, denycap, NULL);
190             if (hl != NULL && login_str2inlist(hl, host, ip, FNM_CASEFOLD))
191                 rc = 0; /* host or IP in deny list */
192         }
193     }
194
195     return rc;
196 }
197
198
199 /*
200  * auth_hostok()
201  * Determine whether or not login from a host is ok
202  */
203
204 int
205 auth_hostok(login_cap_t *lc, const char *host, const char *ip)
206 {
207     return login_hostok(lc, host, ip, "host.allow", "host.deny");
208 }
209
210
211 /*
212  * auth_timeok()
213  * Determine whether or not login is ok at a given time
214  */
215
216 int
217 auth_timeok(login_cap_t *lc, time_t t)
218 {
219     int     rc = 1; /* Default is ok */
220
221     if (lc != NULL && t != (time_t)0 && t != (time_t)-1) {
222         struct tm       *tptr;
223
224         static int      ltimesno = 0;
225         static struct login_time *ltimes = NULL;
226
227         if ((tptr = localtime(&t)) != NULL) {
228             struct login_time   *lt;
229
230           lt = login_timelist(lc, "times.allow", &ltimesno, &ltimes);
231           if (lt != NULL && in_ltms(lt, tptr, NULL) == -1)
232               rc = 0;     /* not in allowed times list */
233           else {
234
235               lt = login_timelist(lc, "times.deny", &ltimesno, &ltimes);
236               if (lt != NULL && in_ltms(lt, tptr, NULL) != -1)
237                   rc = 0; /* in deny times list */
238           }
239           if (ltimes) {
240               free(ltimes);
241               ltimes = NULL;
242               ltimesno = 0;
243           }
244         }
245     }
246
247     return rc;
248 }