login_ok.c revision 26694
121288Sdavidn/*- 221288Sdavidn * Copyright (c) 1996 by 321288Sdavidn * David Nugent <davidn@blaze.net.au> 421288Sdavidn * All rights reserved. 521288Sdavidn * 621288Sdavidn * Redistribution and use in source and binary forms, with or without 721288Sdavidn * modification, is permitted provided that the following conditions 821288Sdavidn * are met: 921288Sdavidn * 1. Redistributions of source code must retain the above copyright 1021288Sdavidn * notice immediately at the beginning of the file, without modification, 1121288Sdavidn * this list of conditions, and the following disclaimer. 1221288Sdavidn * 2. Redistributions in binary form must reproduce the above copyright 1321288Sdavidn * notice, this list of conditions and the following disclaimer in the 1421288Sdavidn * documentation and/or other materials provided with the distribution. 1521288Sdavidn * 3. This work was done expressly for inclusion into FreeBSD. Other use 1621288Sdavidn * is permitted provided this notation is included. 1721288Sdavidn * 4. Absolutely no warranty of function or purpose is made by the authors. 1821288Sdavidn * 5. Modifications may be freely made to this file providing the above 1921288Sdavidn * conditions are met. 2021288Sdavidn * 2121288Sdavidn * Support allow/deny lists in login class capabilities 2221288Sdavidn * 2326694Sdavidn * $Id: login_ok.c,v 1.4 1997/05/10 18:55:38 davidn Exp $ 2421288Sdavidn */ 2521288Sdavidn 2621288Sdavidn#include <stdio.h> 2721288Sdavidn#include <stdlib.h> 2821288Sdavidn#include <string.h> 2921288Sdavidn#include <errno.h> 3021288Sdavidn#include <unistd.h> 3121288Sdavidn#include <ttyent.h> 3221288Sdavidn#include <fnmatch.h> 3321288Sdavidn 3421288Sdavidn#include <sys/types.h> 3521288Sdavidn#include <sys/time.h> 3621288Sdavidn#include <sys/resource.h> 3721288Sdavidn#include <sys/param.h> 3821288Sdavidn#include <login_cap.h> 3921288Sdavidn 4021288Sdavidn 4121288Sdavidn/* -- support functions -- */ 4221288Sdavidn 4325670Sdavidn/* 4425670Sdavidn * login_strinlist() 4521288Sdavidn * This function is intentionally public - reused by TAS. 4621288Sdavidn * Returns TRUE (non-zero) if a string matches a pattern 4721288Sdavidn * in a given array of patterns. 'flags' is passed directly 4821288Sdavidn * to fnmatch(3). 4921288Sdavidn */ 5021288Sdavidn 5121288Sdavidnint 5221288Sdavidnlogin_strinlist(char **list, char const *str, int flags) 5321288Sdavidn{ 5425670Sdavidn int rc = 0; 5521288Sdavidn 5625670Sdavidn if (str != NULL && *str != '\0') { 5725670Sdavidn int i = 0; 5825670Sdavidn 5925670Sdavidn while (rc == 0 && list[i] != NULL) 6026694Sdavidn rc = fnmatch(list[i++], str, flags) == 0; 6125670Sdavidn } 6225670Sdavidn return rc; 6321288Sdavidn} 6421288Sdavidn 6521288Sdavidn 6625670Sdavidn/* 6725670Sdavidn * login_str2inlist() 6821288Sdavidn * Locate either or two strings in a given list 6921288Sdavidn */ 7021288Sdavidn 7121288Sdavidnint 7221288Sdavidnlogin_str2inlist(char **ttlst, const char *str1, const char *str2, int flags) 7321288Sdavidn{ 7425670Sdavidn int rc = 0; 7521288Sdavidn 7625670Sdavidn if (login_strinlist(ttlst, str1, flags)) 7725670Sdavidn rc = 1; 7825670Sdavidn else if (login_strinlist(ttlst, str2, flags)) 7925670Sdavidn rc = 1; 8025670Sdavidn return rc; 8121288Sdavidn} 8221288Sdavidn 8321288Sdavidn 8425670Sdavidn/* 8525670Sdavidn * login_timelist() 8621288Sdavidn * This function is intentinoally public - reused by TAS. 8721288Sdavidn * Returns an allocated list of time periods given an array 8821288Sdavidn * of time periods in ascii form. 8921288Sdavidn */ 9021288Sdavidn 9121288Sdavidnlogin_time_t * 9225670Sdavidnlogin_timelist(login_cap_t *lc, char const *cap, int *ltno, 9325670Sdavidn login_time_t **ltptr) 9421288Sdavidn{ 9525670Sdavidn int j = 0; 9625670Sdavidn struct login_time *lt = NULL; 9725670Sdavidn char **tl; 9821288Sdavidn 9925670Sdavidn if ((tl = login_getcaplist(lc, cap, NULL)) != NULL) { 10025670Sdavidn 10125670Sdavidn while (tl[j++] != NULL) 10225670Sdavidn ; 10325670Sdavidn if (*ltno >= j) 10425670Sdavidn lt = *ltptr; 10525670Sdavidn else if ((lt = realloc(*ltptr, j)) != NULL) { 10625670Sdavidn *ltno = j; 10725670Sdavidn *ltptr = lt; 10825670Sdavidn } 10925670Sdavidn if (lt != NULL) { 11025670Sdavidn int i = 0; 11125670Sdavidn 11225670Sdavidn for (--j; i < j; i++) 11325670Sdavidn lt[i] = parse_lt(tl[i]); 11425670Sdavidn lt[i].lt_dow = LTM_NONE; 11525670Sdavidn } 11621288Sdavidn } 11725670Sdavidn return lt; 11821288Sdavidn} 11921288Sdavidn 12021288Sdavidn 12125670Sdavidn/* 12225670Sdavidn * login_ttyok() 12321288Sdavidn * This function is a variation of auth_ttyok(), but it checks two 12421288Sdavidn * arbitrary capability lists not necessarily related to access. 12521288Sdavidn * This hook is provided for the accounted/exclude accounting lists. 12621288Sdavidn */ 12721288Sdavidn 12821288Sdavidnint 12925670Sdavidnlogin_ttyok(login_cap_t *lc, const char *tty, const char *allowcap, 13025670Sdavidn const char *denycap) 13121288Sdavidn{ 13225670Sdavidn int rc = 1; 13321288Sdavidn 13425670Sdavidn if (lc != NULL && tty != NULL && *tty != '\0') { 13525670Sdavidn struct ttyent *te; 13625670Sdavidn char *grp; 13725670Sdavidn char **ttl; 13821288Sdavidn 13925670Sdavidn te = getttynam(tty); /* Need group name */ 14025670Sdavidn grp = te ? te->ty_group : NULL; 14125670Sdavidn ttl = login_getcaplist(lc, allowcap, NULL); 14225670Sdavidn 14325670Sdavidn if (ttl != NULL && !login_str2inlist(ttl, tty, grp, 0)) 14425670Sdavidn rc = 0; /* tty or ttygroup not in allow list */ 14525670Sdavidn else { 14625670Sdavidn 14725670Sdavidn ttl = login_getcaplist(lc, denycap, NULL); 14825670Sdavidn if (ttl != NULL && login_str2inlist(ttl, tty, grp, 0)) 14925670Sdavidn rc = 0; /* tty or ttygroup in deny list */ 15025670Sdavidn } 15121288Sdavidn } 15225670Sdavidn 15325670Sdavidn return rc; 15421288Sdavidn} 15521288Sdavidn 15621288Sdavidn 15725670Sdavidn/* 15825670Sdavidn * auth_ttyok() 15921288Sdavidn * Determine whether or not login on a tty is accessible for 16021288Sdavidn * a login class 16121288Sdavidn */ 16221288Sdavidn 16321288Sdavidnint 16421288Sdavidnauth_ttyok(login_cap_t *lc, const char * tty) 16521288Sdavidn{ 16625670Sdavidn return login_ttyok(lc, tty, "ttys.allow", "ttys.deny"); 16721288Sdavidn} 16821288Sdavidn 16921288Sdavidn 17025670Sdavidn/* 17125670Sdavidn * login_hostok() 17221288Sdavidn * This function is a variation of auth_hostok(), but it checks two 17321288Sdavidn * arbitrary capability lists not necessarily related to access. 17421288Sdavidn * This hook is provided for the accounted/exclude accounting lists. 17521288Sdavidn */ 17621288Sdavidn 17721288Sdavidnint 17825670Sdavidnlogin_hostok(login_cap_t *lc, const char *host, const char *ip, 17925670Sdavidn const char *allowcap, const char *denycap) 18021288Sdavidn{ 18125670Sdavidn int rc = 1; /* Default is ok */ 18221288Sdavidn 18325670Sdavidn if (lc != NULL && 18425670Sdavidn ((host != NULL && *host != '\0') || (ip != NULL && *ip != '\0'))) { 18525670Sdavidn char **hl; 18621288Sdavidn 18725670Sdavidn hl = login_getcaplist(lc, allowcap, NULL); 18825670Sdavidn if (hl != NULL && !login_str2inlist(hl, host, ip, FNM_CASEFOLD)) 18925670Sdavidn rc = 0; /* host or IP not in allow list */ 19025670Sdavidn else { 19125670Sdavidn 19225670Sdavidn hl = login_getcaplist(lc, "host.deny", NULL); 19325670Sdavidn if (hl != NULL && login_str2inlist(hl, host, ip, FNM_CASEFOLD)) 19425670Sdavidn rc = 0; /* host or IP in deny list */ 19525670Sdavidn } 19621288Sdavidn } 19725670Sdavidn 19825670Sdavidn return rc; 19921288Sdavidn} 20021288Sdavidn 20121288Sdavidn 20225670Sdavidn/* 20325670Sdavidn * auth_hostok() 20421288Sdavidn * Determine whether or not login from a host is ok 20521288Sdavidn */ 20621288Sdavidn 20721288Sdavidnint 20821288Sdavidnauth_hostok(login_cap_t *lc, const char *host, const char *ip) 20921288Sdavidn{ 21025670Sdavidn return login_hostok(lc, host, ip, "host.allow", "host.deny"); 21121288Sdavidn} 21221288Sdavidn 21321288Sdavidn 21425670Sdavidn/* 21525670Sdavidn * auth_timeok() 21621288Sdavidn * Determine whether or not login is ok at a given time 21721288Sdavidn */ 21821288Sdavidn 21921288Sdavidnint 22021288Sdavidnauth_timeok(login_cap_t *lc, time_t t) 22121288Sdavidn{ 22225670Sdavidn int rc = 1; /* Default is ok */ 22321288Sdavidn 22425670Sdavidn if (lc != NULL && t != (time_t)0 && t != (time_t)-1) { 22525670Sdavidn struct tm *tptr; 22621288Sdavidn 22725670Sdavidn static int ltimesno = 0; 22825670Sdavidn static struct login_time *ltimes = NULL; 22921288Sdavidn 23025670Sdavidn if ((tptr = localtime(&t)) != NULL) { 23125670Sdavidn struct login_time *lt; 23221288Sdavidn 23325670Sdavidn lt = login_timelist(lc, "times.allow", <imesno, <imes); 23425670Sdavidn if (lt != NULL && in_ltms(lt, tptr, NULL) == -1) 23525670Sdavidn rc = 0; /* not in allowed times list */ 23625670Sdavidn else { 23721288Sdavidn 23825670Sdavidn lt = login_timelist(lc, "times.deny", <imesno, <imes); 23925670Sdavidn if (lt != NULL && in_ltms(lt, tptr, NULL) != -1) 24025670Sdavidn rc = 0; /* in deny times list */ 24125670Sdavidn } 24225670Sdavidn if (ltimes) { 24325670Sdavidn free(ltimes); 24425670Sdavidn ltimes = NULL; 24525670Sdavidn ltimesno = 0; 24625670Sdavidn } 24725670Sdavidn } 24821288Sdavidn } 24925670Sdavidn 25025670Sdavidn return rc; 25121288Sdavidn} 252