/* * Replacement for krb5_kuserok for testing. * * This is a reimplementation of krb5_kuserok that uses the replacement * getpwnam function and the special passwd struct internal to the fake PAM * module to locate .k5login. The default Kerberos krb5_kuserok always calls * the system getpwnam, which we may not be able to intercept, and will * therefore fail because it can't locate the .k5login file for the test user * (or succeed oddly because it finds some random file on the testing system). * * This implementation is drastically simplified from the Kerberos library * version, and much less secure (which shouldn't matter since it's only * acting on test data). * * This is an optional part of the fake PAM library and can be omitted when * testing modules that don't use Kerberos. * * The canonical version of this file is maintained in the rra-c-util package, * which can be found at . * * Written by Russ Allbery * Copyright 2011 * The Board of Trustees of the Leland Stanford Junior University * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * SPDX-License-Identifier: MIT */ #include #include #include #include #include #include #include /* * Given a Kerberos principal representing the authenticated identity and the * username of the local account, return true if that principal is authorized * to log on to that account. The principal is authorized if the .k5login * file does not exist and the user matches the localname form of the * principal, or if the file does exist and the principal is listed in it. * * This version retrieves the home directory from the internal fake PAM * library path. */ krb5_boolean krb5_kuserok(krb5_context ctx, krb5_principal princ, const char *user) { char *principal, *path; struct passwd *pwd; FILE *file; krb5_error_code code; char buffer[BUFSIZ]; bool found = false; #ifdef HAVE_PAM_MODUTIL_GETPWNAM struct pam_handle pamh; #endif /* * Find .k5login and confirm if it exists. If it doesn't, fall back on * krb5_aname_to_localname. */ #ifdef HAVE_PAM_MODUTIL_GETPWNAM memset(&pamh, 0, sizeof(pamh)); pwd = pam_modutil_getpwnam(&pamh, user); #else pwd = getpwnam(user); #endif if (pwd == NULL) return false; basprintf(&path, "%s/.k5login", pwd->pw_dir); if (access(path, R_OK) < 0) { free(path); code = krb5_aname_to_localname(ctx, princ, sizeof(buffer), buffer); return (code == 0 && strcmp(buffer, user) == 0); } file = fopen(path, "r"); if (file == NULL) { free(path); return false; } free(path); /* .k5login exists. Scan it for the principal. */ if (krb5_unparse_name(ctx, princ, &principal) != 0) { fclose(file); return false; } while (!found && (fgets(buffer, sizeof(buffer), file) != NULL)) { if (buffer[strlen(buffer) - 1] == '\n') buffer[strlen(buffer) - 1] = '\0'; if (strcmp(buffer, principal) == 0) found = true; } fclose(file); krb5_free_unparsed_name(ctx, principal); return found; }