12256d369SDag-Erling Smørgrav /*- 22256d369SDag-Erling Smørgrav * Copyright (c) 2001 Networks Associates Technology, Inc. 32256d369SDag-Erling Smørgrav * All rights reserved. 42256d369SDag-Erling Smørgrav * 52256d369SDag-Erling Smørgrav * This software was developed for the FreeBSD Project by ThinkSec AS and 62256d369SDag-Erling Smørgrav * NAI Labs, the Security Research Division of Network Associates, Inc. 72256d369SDag-Erling Smørgrav * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 82256d369SDag-Erling Smørgrav * DARPA CHATS research program. 92256d369SDag-Erling Smørgrav * 102256d369SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 112256d369SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 122256d369SDag-Erling Smørgrav * are met: 132256d369SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 142256d369SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 152256d369SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 162256d369SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 172256d369SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 182256d369SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote 192256d369SDag-Erling Smørgrav * products derived from this software without specific prior written 202256d369SDag-Erling Smørgrav * permission. 212256d369SDag-Erling Smørgrav * 222256d369SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 232256d369SDag-Erling Smørgrav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 242256d369SDag-Erling Smørgrav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 252256d369SDag-Erling Smørgrav * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 262256d369SDag-Erling Smørgrav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 272256d369SDag-Erling Smørgrav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 282256d369SDag-Erling Smørgrav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 292256d369SDag-Erling Smørgrav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 302256d369SDag-Erling Smørgrav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 312256d369SDag-Erling Smørgrav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 322256d369SDag-Erling Smørgrav * SUCH DAMAGE. 332256d369SDag-Erling Smørgrav */ 342256d369SDag-Erling Smørgrav 352256d369SDag-Erling Smørgrav #include <sys/cdefs.h> 362256d369SDag-Erling Smørgrav __FBSDID("$FreeBSD$"); 372256d369SDag-Erling Smørgrav 382256d369SDag-Erling Smørgrav #include <ctype.h> 392256d369SDag-Erling Smørgrav #include <grp.h> 402256d369SDag-Erling Smørgrav #include <paths.h> 412256d369SDag-Erling Smørgrav #include <pwd.h> 422256d369SDag-Erling Smørgrav #include <stdio.h> 432256d369SDag-Erling Smørgrav #include <stdlib.h> 442256d369SDag-Erling Smørgrav #include <string.h> 452256d369SDag-Erling Smørgrav 462256d369SDag-Erling Smørgrav #define PAM_SM_ACCOUNT 472256d369SDag-Erling Smørgrav 482256d369SDag-Erling Smørgrav #include <security/pam_appl.h> 492256d369SDag-Erling Smørgrav #include <security/pam_modules.h> 502256d369SDag-Erling Smørgrav #include <security/pam_mod_misc.h> 512256d369SDag-Erling Smørgrav #include <security/openpam.h> 522256d369SDag-Erling Smørgrav 532256d369SDag-Erling Smørgrav PAM_EXTERN int 542256d369SDag-Erling Smørgrav pam_sm_acct_mgmt(pam_handle_t *pamh, int flags __unused, 552256d369SDag-Erling Smørgrav int argc __unused, const char *argv[] __unused) 562256d369SDag-Erling Smørgrav { 572256d369SDag-Erling Smørgrav struct passwd *pwd; 582256d369SDag-Erling Smørgrav struct group *grp; 592256d369SDag-Erling Smørgrav const char *user; 602256d369SDag-Erling Smørgrav int pam_err, found, allow; 612256d369SDag-Erling Smørgrav char *line, *name, **mem; 622256d369SDag-Erling Smørgrav size_t len, ulen; 632256d369SDag-Erling Smørgrav FILE *f; 642256d369SDag-Erling Smørgrav 652256d369SDag-Erling Smørgrav pam_err = pam_get_user(pamh, &user, NULL); 662256d369SDag-Erling Smørgrav if (pam_err != PAM_SUCCESS) 672256d369SDag-Erling Smørgrav return (pam_err); 682256d369SDag-Erling Smørgrav if (user == NULL || (pwd = getpwnam(user)) == NULL) 692256d369SDag-Erling Smørgrav return (PAM_SERVICE_ERR); 702256d369SDag-Erling Smørgrav 712256d369SDag-Erling Smørgrav found = 0; 722256d369SDag-Erling Smørgrav ulen = strlen(user); 732256d369SDag-Erling Smørgrav if ((f = fopen(_PATH_FTPUSERS, "r")) == NULL) { 742256d369SDag-Erling Smørgrav PAM_LOG("%s: %m", _PATH_FTPUSERS); 752256d369SDag-Erling Smørgrav goto done; 762256d369SDag-Erling Smørgrav } 772256d369SDag-Erling Smørgrav while (!found && (line = fgetln(f, &len)) != NULL) { 782256d369SDag-Erling Smørgrav if (*line == '#') 792256d369SDag-Erling Smørgrav continue; 802256d369SDag-Erling Smørgrav while (len > 0 && isspace(line[len - 1])) 812256d369SDag-Erling Smørgrav --len; 822256d369SDag-Erling Smørgrav if (len == 0) 832256d369SDag-Erling Smørgrav continue; 842256d369SDag-Erling Smørgrav /* simple case first */ 852256d369SDag-Erling Smørgrav if (*line != '@') { 862256d369SDag-Erling Smørgrav if (len == ulen && strncmp(user, line, len) == 0) 872256d369SDag-Erling Smørgrav found = 1; 882256d369SDag-Erling Smørgrav continue; 892256d369SDag-Erling Smørgrav } 902256d369SDag-Erling Smørgrav /* member of specified group? */ 912256d369SDag-Erling Smørgrav asprintf(&name, "%.*s", (int)len - 1, line + 1); 922256d369SDag-Erling Smørgrav if (name == NULL) { 932256d369SDag-Erling Smørgrav fclose(f); 942256d369SDag-Erling Smørgrav return (PAM_BUF_ERR); 952256d369SDag-Erling Smørgrav } 962256d369SDag-Erling Smørgrav grp = getgrnam(name); 972256d369SDag-Erling Smørgrav free(name); 982256d369SDag-Erling Smørgrav if (grp == NULL) 992256d369SDag-Erling Smørgrav continue; 1002256d369SDag-Erling Smørgrav for (mem = grp->gr_mem; mem && *mem && !found; ++mem) 1012256d369SDag-Erling Smørgrav if (strcmp(user, *mem) == 0) 1022256d369SDag-Erling Smørgrav found = 1; 1032256d369SDag-Erling Smørgrav } 1042256d369SDag-Erling Smørgrav done: 1052256d369SDag-Erling Smørgrav allow = (openpam_get_option(pamh, "disallow") == NULL); 1062256d369SDag-Erling Smørgrav if (found) 1072256d369SDag-Erling Smørgrav pam_err = allow ? PAM_SUCCESS : PAM_AUTH_ERR; 1082256d369SDag-Erling Smørgrav else 1092256d369SDag-Erling Smørgrav pam_err = allow ? PAM_AUTH_ERR : PAM_SUCCESS; 1102256d369SDag-Erling Smørgrav if (f != NULL) 1112256d369SDag-Erling Smørgrav fclose(f); 1122256d369SDag-Erling Smørgrav return (pam_err); 1132256d369SDag-Erling Smørgrav } 1142256d369SDag-Erling Smørgrav 1152256d369SDag-Erling Smørgrav PAM_MODULE_ENTRY("pam_ftpusers"); 116