c8e880c1386b032ac975c61826ba3bc0d8dce5acmj/*
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * CDDL HEADER START
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj *
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * The contents of this file are subject to the terms of the
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * Common Development and Distribution License (the "License").
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * You may not use this file except in compliance with the License.
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj *
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * or http://www.opensolaris.org/os/licensing.
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * See the License for the specific language governing permissions
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * and limitations under the License.
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj *
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * When distributing Covered Code, include this CDDL HEADER in each
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * If applicable, add the following below this CDDL HEADER, with the
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * fields enclosed by brackets "[]" replaced with your own identifying
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * information: Portions Copyright [yyyy] [name of copyright owner]
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj *
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * CDDL HEADER END
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj */
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj/*
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * Use is subject to license terms.
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj */
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <stdio.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <string.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <sys/types.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <sys/stat.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <syslog.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <netdb.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <malloc.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <unistd.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <errno.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <security/pam_appl.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <security/pam_modules.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj#include <security/pam_impl.h>
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik#define ILLEGAL_COMBINATION "pam_list: illegal combination of options"
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Juriktypedef enum {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik LIST_EXTERNAL_FILE,
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik LIST_PLUS_CHECK,
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik LIST_COMPAT_MODE
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik} pam_list_mode_t;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurikstatic const char *
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurikstring_mode_type(pam_list_mode_t op_mode, boolean_t allow)
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik{
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik return ((op_mode == LIST_COMPAT_MODE) ? "compat" :
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik (allow ? "allow" : "deny"));
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik}
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurikstatic void
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Juriklog_illegal_combination(const char *s1, const char *s2)
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik{
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik __pam_log(LOG_AUTH | LOG_ERR, ILLEGAL_COMBINATION
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik " %s and %s", s1, s2);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik}
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj/*ARGSUSED*/
c8e880c1386b032ac975c61826ba3bc0d8dce5acmjint
c8e880c1386b032ac975c61826ba3bc0d8dce5acmjpam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj{
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj FILE *fd;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj const char *allowdeny_filename = PF_PATH;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj char buf[BUFSIZ];
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj char hostname[MAXHOSTNAMELEN];
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj char *username = NULL;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj char *bufp;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj char *rhost;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj char *limit;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj int userok = 0;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj int hostok = 0;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj int i;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj int allow_deny_test = 0;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj boolean_t debug = B_FALSE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj boolean_t allow = B_FALSE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj boolean_t matched = B_FALSE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj boolean_t check_user = B_TRUE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj boolean_t check_host = B_FALSE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj boolean_t check_exact = B_FALSE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik pam_list_mode_t op_mode = LIST_PLUS_CHECK;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj for (i = 0; i < argc; ++i) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (strncasecmp(argv[i], "debug", sizeof ("debug")) == 0) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj debug = B_TRUE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else if (strncasecmp(argv[i], "user", sizeof ("user")) == 0) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj check_user = B_TRUE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else if (strncasecmp(argv[i], "nouser",
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj sizeof ("nouser")) == 0) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj check_user = B_FALSE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else if (strncasecmp(argv[i], "host", sizeof ("host")) == 0) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj check_host = B_TRUE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else if (strncasecmp(argv[i], "nohost",
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj sizeof ("nohost")) == 0) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj check_host = B_FALSE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else if (strncasecmp(argv[i], "user_host_exact",
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj sizeof ("user_host_exact")) == 0) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj check_exact = B_TRUE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik } else if (strcasecmp(argv[i], "compat") == 0) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (op_mode == LIST_PLUS_CHECK) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik op_mode = LIST_COMPAT_MODE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik } else {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik log_illegal_combination("compat",
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik string_mode_type(op_mode, allow));
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik return (PAM_SERVICE_ERR);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else if (strncasecmp(argv[i], "allow=",
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj sizeof ("allow=") - 1) == 0) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (op_mode == LIST_PLUS_CHECK) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allowdeny_filename = argv[i] +
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik sizeof ("allow=") - 1;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow = B_TRUE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik op_mode = LIST_EXTERNAL_FILE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow_deny_test++;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik } else {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik log_illegal_combination("allow",
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik string_mode_type(op_mode, allow));
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik return (PAM_SERVICE_ERR);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else if (strncasecmp(argv[i], "deny=",
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj sizeof ("deny=") - 1) == 0) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (op_mode == LIST_PLUS_CHECK) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allowdeny_filename = argv[i] +
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik sizeof ("deny=") - 1;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow = B_FALSE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik op_mode = LIST_EXTERNAL_FILE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow_deny_test++;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik } else {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik log_illegal_combination("deny",
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik string_mode_type(op_mode, allow));
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik return (PAM_SERVICE_ERR);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj __pam_log(LOG_AUTH | LOG_ERR,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj "pam_list: illegal option %s", argv[i]);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj return (PAM_SERVICE_ERR);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (((check_user || check_host || check_exact) == B_FALSE) ||
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (allow_deny_test > 1)) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik __pam_log(LOG_AUTH | LOG_ERR, ILLEGAL_COMBINATION);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik return (PAM_SERVICE_ERR);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if ((op_mode == LIST_COMPAT_MODE) && (check_user == B_FALSE)) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik log_illegal_combination("compat", "nouser");
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj return (PAM_SERVICE_ERR);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (debug) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj __pam_log(LOG_AUTH | LOG_DEBUG,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj "pam_list: check_user = %d, check_host = %d,"
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj "check_exact = %d\n",
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj check_user, check_host, check_exact);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj __pam_log(LOG_AUTH | LOG_DEBUG,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj "pam_list: auth_file: %s, %s\n", allowdeny_filename,
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik (op_mode == LIST_COMPAT_MODE) ? "compat mode" :
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik (allow ? "allow file" : "deny file"));
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (void) pam_get_item(pamh, PAM_USER, (void**)&username);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if ((check_user || check_exact) && ((username == NULL) ||
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (*username == '\0'))) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj __pam_log(LOG_AUTH | LOG_ERR,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj "pam_list: username not supplied, critical error");
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj return (PAM_USER_UNKNOWN);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (void) pam_get_item(pamh, PAM_RHOST, (void**)&rhost);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if ((check_host || check_exact) && ((rhost == NULL) ||
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (*rhost == '\0'))) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj rhost = hostname;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj __pam_log(LOG_AUTH | LOG_ERR,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj "pam_list: error by gethostname - %m");
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj return (PAM_SERVICE_ERR);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (debug) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj __pam_log(LOG_AUTH | LOG_DEBUG,
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik "pam_list: pam_sm_acct_mgmt for (%s,%s,)",
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (rhost != NULL) ? rhost : "", username);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (strlen(allowdeny_filename) == 0) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik __pam_log(LOG_AUTH | LOG_ERR,
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik "pam_list: file name not specified");
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik return (PAM_SERVICE_ERR);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if ((fd = fopen(allowdeny_filename, "rF")) == NULL) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik __pam_log(LOG_AUTH | LOG_ERR, "pam_list: fopen of %s: %s",
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allowdeny_filename, strerror(errno));
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj return (PAM_SERVICE_ERR);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj while (fgets(buf, BUFSIZ, fd) != NULL) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj /* lines longer than BUFSIZ-1 */
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if ((strlen(buf) == (BUFSIZ - 1)) &&
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (buf[BUFSIZ - 2] != '\n')) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj while ((fgetc(fd) != '\n') && (!feof(fd))) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj continue;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj __pam_log(LOG_AUTH | LOG_DEBUG,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj "pam_list: long line in file,"
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj "more than %d chars, the rest ignored", BUFSIZ - 1);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj /* remove unneeded colons if necessary */
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if ((limit = strpbrk(buf, ":\n")) != NULL) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj *limit = '\0';
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj /* ignore free values */
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (buf[0] == '\0') {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj continue;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj bufp = buf;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj /* test for interesting lines = +/- in /etc/passwd */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (op_mode == LIST_COMPAT_MODE) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik /* simple + matches all */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if ((buf[0] == '+') && (buf[1] == '\0')) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik matched = B_TRUE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow = B_TRUE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik break;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik /* simple - is not defined */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if ((buf[0] == '-') && (buf[1] == '\0')) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik __pam_log(LOG_AUTH | LOG_ERR,
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik "pam_list: simple minus unknown, "
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik "illegal line in " PF_PATH);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik (void) fclose(fd);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik return (PAM_SERVICE_ERR);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik /* @ is not allowed on the first position */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (buf[0] == '@') {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik __pam_log(LOG_AUTH | LOG_ERR,
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik "pam_list: @ is not allowed on the first "
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik "position in " PF_PATH);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik (void) fclose(fd);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik return (PAM_SERVICE_ERR);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik /* -user or -@netgroup */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (buf[0] == '-') {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow = B_FALSE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik bufp++;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik /* +user or +@netgroup */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik } else if (buf[0] == '+') {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow = B_TRUE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik bufp++;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik /* user */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik } else {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow = B_TRUE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik } else if (op_mode == LIST_PLUS_CHECK) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (((buf[0] != '+') && (buf[0] != '-')) ||
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (buf[1] == '\0')) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj continue;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (buf[0] == '+') {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj allow = B_TRUE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj allow = B_FALSE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj bufp++;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj /*
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * if -> netgroup line
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj * else -> user line
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj */
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if ((bufp[0] == '@') && (bufp[1] != '\0')) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj bufp++;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (check_exact) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (innetgr(bufp, rhost, username,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj NULL) == 1) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj matched = B_TRUE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj break;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (check_user) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj userok = innetgr(bufp, NULL, username,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj NULL);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj userok = 1;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (check_host) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj hostok = innetgr(bufp, rhost, NULL,
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj NULL);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj hostok = 1;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (userok && hostok) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj matched = B_TRUE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj break;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj } else {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (check_user) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (strcmp(bufp, username) == 0) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj matched = B_TRUE;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj break;
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik /*
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik * No match found in /etc/passwd yet. For compat mode
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik * a failure to match should result in a return of
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik * PAM_PERM_DENIED which is achieved below if 'matched'
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik * is false and 'allow' is true.
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (op_mode == LIST_COMPAT_MODE) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow = B_TRUE;
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj (void) fclose(fd);
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (debug) {
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik __pam_log(LOG_AUTH | LOG_DEBUG,
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik "pam_list: %s for %s", matched ? "matched" : "no match",
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik allow ? "allow" : "deny");
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj if (matched) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj return (allow ? PAM_SUCCESS : PAM_PERM_DENIED);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik /*
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik * For compatibility with passwd_compat mode to prevent root access
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik * denied.
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik */
ce0ce47a28e767d5bf7dec161e16b4f621aa39a1Milan Jurik if (op_mode == LIST_PLUS_CHECK) {
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj return (PAM_IGNORE);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj }
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj return (allow ? PAM_PERM_DENIED : PAM_SUCCESS);
c8e880c1386b032ac975c61826ba3bc0d8dce5acmj}