12256d369SDag-Erling Smørgrav /*-
2*5e53a4f9SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
3*5e53a4f9SPedro F. Giffuni *
42256d369SDag-Erling Smørgrav * Copyright (c) 2001 Networks Associates Technology, Inc.
52256d369SDag-Erling Smørgrav * All rights reserved.
62256d369SDag-Erling Smørgrav *
72256d369SDag-Erling Smørgrav * This software was developed for the FreeBSD Project by ThinkSec AS and
82256d369SDag-Erling Smørgrav * NAI Labs, the Security Research Division of Network Associates, Inc.
92256d369SDag-Erling Smørgrav * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
102256d369SDag-Erling Smørgrav * DARPA CHATS research program.
112256d369SDag-Erling Smørgrav *
122256d369SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without
132256d369SDag-Erling Smørgrav * modification, are permitted provided that the following conditions
142256d369SDag-Erling Smørgrav * are met:
152256d369SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright
162256d369SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer.
172256d369SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright
182256d369SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the
192256d369SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution.
202256d369SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote
212256d369SDag-Erling Smørgrav * products derived from this software without specific prior written
222256d369SDag-Erling Smørgrav * permission.
232256d369SDag-Erling Smørgrav *
242256d369SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
252256d369SDag-Erling Smørgrav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
262256d369SDag-Erling Smørgrav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
272256d369SDag-Erling Smørgrav * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
282256d369SDag-Erling Smørgrav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
292256d369SDag-Erling Smørgrav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
302256d369SDag-Erling Smørgrav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
312256d369SDag-Erling Smørgrav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
322256d369SDag-Erling Smørgrav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
332256d369SDag-Erling Smørgrav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
342256d369SDag-Erling Smørgrav * SUCH DAMAGE.
352256d369SDag-Erling Smørgrav */
362256d369SDag-Erling Smørgrav
372256d369SDag-Erling Smørgrav #include <sys/cdefs.h>
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
pam_sm_acct_mgmt(pam_handle_t * pamh,int flags __unused,int argc __unused,const char * argv[]__unused)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