login_ok.c revision 21673
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 * $FreeBSD: head/lib/libutil/login_ok.c 21673 1997-01-14 07:20:47Z jkh $ 24 */ 25 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29#include <errno.h> 30#include <unistd.h> 31#include <ttyent.h> 32#include <fnmatch.h> 33 34#include <sys/types.h> 35#include <sys/time.h> 36#include <sys/resource.h> 37#include <sys/param.h> 38#include <login_cap.h> 39 40 41/* -- support functions -- */ 42 43/* login_strinlist() 44 * This function is intentionally public - reused by TAS. 45 * Returns TRUE (non-zero) if a string matches a pattern 46 * in a given array of patterns. 'flags' is passed directly 47 * to fnmatch(3). 48 */ 49 50int 51login_strinlist(char **list, char const *str, int flags) 52{ 53 int rc = 0; 54 55 if (str != NULL && *str != '\0') 56 { 57 int i = 0; 58 while (rc == 0 && list[i] != NULL) 59 rc = fnmatch(list[i], str, flags) == 0; 60 } 61 return rc; 62} 63 64 65/* login_str2inlist() 66 * Locate either or two strings in a given list 67 */ 68 69int 70login_str2inlist(char **ttlst, const char *str1, const char *str2, int flags) 71{ 72 int rc = 0; 73 74 if (login_strinlist(ttlst, str1, flags)) 75 rc = 1; 76 else if (login_strinlist(ttlst, str2, flags)) 77 rc = 1; 78 return rc; 79} 80 81 82/* login_timelist() 83 * This function is intentinoally public - reused by TAS. 84 * Returns an allocated list of time periods given an array 85 * of time periods in ascii form. 86 */ 87 88login_time_t * 89login_timelist(login_cap_t *lc, char const *cap, int *ltno, login_time_t **ltptr) 90{ 91 int j = 0; 92 struct login_time * lt = NULL; 93 char **tl = login_getcaplist(lc, cap, NULL); 94 95 if (tl) 96 { 97 while (tl[j++] != NULL) 98 ; 99 if (*ltno >= j) 100 lt = *ltptr; 101 else if ((lt = realloc(*ltptr, j)) != NULL) 102 { 103 *ltno = j; 104 *ltptr = lt; 105 } 106 if (lt != NULL) 107 { 108 int i = 0; 109 --j; 110 while (i < j) 111 { 112 lt[i] = parse_lt(tl[i]); 113 ++i; 114 } 115 lt[i].lt_dow = LTM_NONE; 116 } 117 } 118 return lt; 119} 120 121 122/* login_ttyok() 123 * This function is a variation of auth_ttyok(), but it checks two 124 * arbitrary capability lists not necessarily related to access. 125 * This hook is provided for the accounted/exclude accounting lists. 126 */ 127 128int 129login_ttyok(login_cap_t *lc, const char *tty, const char *allowcap, const char *denycap) 130{ 131 int rc = 1; 132 133 if (lc != NULL && tty != NULL && *tty != '\0') 134 { 135 struct ttyent * te = getttynam(tty); /* Need group name */ 136 char * grp = te ? te->ty_group : NULL; 137 char **ttl = login_getcaplist(lc, allowcap, NULL); 138 139 if (ttl != NULL && !login_str2inlist(ttl, tty, grp, 0)) 140 rc = 0; /* tty or ttygroup not in allow list */ 141 else 142 { 143 ttl = login_getcaplist(lc, denycap, NULL); 144 if (ttl != NULL && login_str2inlist(ttl, tty, grp, 0)) 145 rc = 0; /* tty or ttygroup in deny list */ 146 } 147 } 148 return rc; 149} 150 151 152/* auth_ttyok() 153 * Determine whether or not login on a tty is accessible for 154 * a login class 155 */ 156 157int 158auth_ttyok(login_cap_t *lc, const char * tty) 159{ 160 return login_ttyok(lc, tty, "ttys.allow", "ttys.deny"); 161} 162 163 164/* login_hostok() 165 * This function is a variation of auth_hostok(), but it checks two 166 * arbitrary capability lists not necessarily related to access. 167 * This hook is provided for the accounted/exclude accounting lists. 168 */ 169 170int 171login_hostok(login_cap_t *lc, const char *host, const char *ip, const char *allowcap, const char *denycap) 172{ 173 int rc = 1; /* Default is ok */ 174 175 if (lc != NULL && ((host != NULL && *host != '\0') || (ip != NULL && *ip != '\0'))) 176 { 177 char **hl = login_getcaplist(lc, allowcap, NULL); 178 179 if (hl != NULL && !login_str2inlist(hl, host, ip, FNM_CASEFOLD)) 180 rc = 0; /* host or IP not in allow list */ 181 else 182 { 183 hl = login_getcaplist(lc, "host.deny", NULL); 184 if (hl != NULL && login_str2inlist(hl, host, ip, FNM_CASEFOLD)) 185 rc = 0; /* host or IP in deny list */ 186 } 187 } 188 return rc; 189} 190 191 192/* auth_hostok() 193 * Determine whether or not login from a host is ok 194 */ 195 196int 197auth_hostok(login_cap_t *lc, const char *host, const char *ip) 198{ 199 return login_hostok(lc, host, ip, "host.allow", "host.deny"); 200} 201 202 203/* auth_timeok() 204 * Determine whether or not login is ok at a given time 205 */ 206 207int 208auth_timeok(login_cap_t *lc, time_t t) 209{ 210 int rc = 1; /* Default is ok */ 211 212 if (lc != NULL && t != (time_t)0 && t != (time_t)-1) 213 { 214 struct tm * tptr = localtime(&t); 215 216 static int ltimesno = 0; 217 static struct login_time * ltimes = NULL; 218 219 if (tptr != NULL) 220 { 221 struct login_time *lt = login_timelist(lc, "times.allow", <imesno, <imes); 222 223 if (lt != NULL && in_ltms(lt, tptr, NULL) == -1) 224 rc = 0; /* not in allowed times list */ 225 else 226 { 227 lt = login_timelist(lc, "times.deny", <imesno, <imes); 228 229 if (lt != NULL && in_ltms(lt, tptr, NULL) != -1) 230 rc = 0; /* in deny times list */ 231 } 232 if (ltimes) 233 { 234 free(ltimes); 235 ltimes = NULL; 236 ltimesno = 0; 237 } 238 } 239 } 240 return rc; 241} 242 243