source: branches/fc15-dev/server/common/patches/krb5-kuserok-scripts.patch @ 1989

Last change on this file since 1989 was 1820, checked in by achernya, 13 years ago
(Hopefully) final version of the Scripts krb5 patch, that removes the function into which the .k5login filename generating code was refactored into
File size: 5.0 KB
  • krb5-1.9/src/lib/krb5/os/kuserok.c

    # scripts.mit.edu krb5 kuserok patch
    # Copyright (C) 2006  Tim Abbott <tabbott@mit.edu>
    #               2011  Alexander Chernyakhovsky <achernya@mit.edu>
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
    #
    # See /COPYRIGHT in this repository for more information.
    #
    old new  
    3232#if !defined(_WIN32)            /* Not yet for Windows */
    3333#include <stdio.h>
    3434#include <pwd.h>
     35#include <sys/wait.h>
    3536
    3637#if defined(_AIX) && defined(_IBMR2)
    3738#include <sys/access.h>
     
    5152enum result { ACCEPT, REJECT, PASS };
    5253
    5354/*
    54  * Find the k5login filename for luser, either in the user's homedir or in a
    55  * configured directory under the username.
    56  */
    57 static krb5_error_code
    58 get_k5login_filename(krb5_context context, const char *luser,
    59                      const char *homedir, char **filename_out)
    60 {
    61     krb5_error_code ret;
    62     char *dir, *filename;
    63 
    64     *filename_out = NULL;
    65     ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
    66                              KRB5_CONF_K5LOGIN_DIRECTORY, NULL, NULL, &dir);
    67     if (ret != 0)
    68         return ret;
    69 
    70     if (dir == NULL) {
    71         /* Look in the user's homedir. */
    72         if (asprintf(&filename, "%s/.k5login", homedir) < 0)
    73             return ENOMEM;
    74     } else {
    75         /* Look in the configured directory. */
    76         if (asprintf(&filename, "%s/%s", dir, luser) < 0)
    77             ret = ENOMEM;
    78         profile_release_string(dir);
    79         if (ret)
    80             return ret;
    81     }
    82     *filename_out = filename;
    83     return 0;
    84 }
    85 
    86 /*
    8755 * Determine whether principal is authorized to log in as luser according to
    8856 * the user's k5login file.  Return ACCEPT if the k5login file authorizes the
    8957 * principal, PASS if the k5login file does not exist, or REJECT if the k5login
     
    9361static enum result
    9462k5login_ok(krb5_context context, krb5_principal principal, const char *luser)
    9563{
    96     int authoritative = TRUE, gobble;
     64    int authoritative = TRUE;
    9765    enum result result = REJECT;
    98     char *filename = NULL, *princname = NULL;
    99     char *newline, linebuf[BUFSIZ], pwbuf[BUFSIZ];
    100     struct stat sbuf;
     66    char *princname = NULL;
     67    char pwbuf[BUFSIZ];
    10168    struct passwd pwx, *pwd;
    102     FILE *fp = NULL;
     69    int pid, status;
    10370
    10471    if (profile_get_boolean(context->profile, KRB5_CONF_LIBDEFAULTS,
    10572                            KRB5_CONF_K5LOGIN_AUTHORITATIVE, NULL, TRUE,
     
    11077    if (k5_getpwnam_r(luser, &pwx, pwbuf, sizeof(pwbuf), &pwd) != 0)
    11178        goto cleanup;
    11279
    113     if (get_k5login_filename(context, luser, pwd->pw_dir, &filename) != 0)
    114         goto cleanup;
    115 
    116     if (access(filename, F_OK) != 0) {
    117         result = PASS;
    118         goto cleanup;
    119     }
    120 
    12180    if (krb5_unparse_name(context, principal, &princname) != 0)
    12281        goto cleanup;
    12382
    124     fp = fopen(filename, "r");
    125     if (fp == NULL)
     83    if ((pid = fork()) == -1)
    12684        goto cleanup;
    127     set_cloexec_file(fp);
    128 
    129     /* For security reasons, the .k5login file must be owned either by
    130      * the user or by root. */
    131     if (fstat(fileno(fp), &sbuf))
    132         goto cleanup;
    133     if (sbuf.st_uid != pwd->pw_uid && !FILE_OWNER_OK(sbuf.st_uid))
    134         goto cleanup;
    135 
    136     /* Check each line. */
    137     while (result != ACCEPT && (fgets(linebuf, sizeof(linebuf), fp) != NULL)) {
    138         newline = strrchr(linebuf, '\n');
    139         if (newline != NULL)
    140             *newline = '\0';
    141         if (strcmp(linebuf, princname) == 0)
    142             result = ACCEPT;
    143         /* Clean up the rest of the line if necessary. */
    144         if (newline == NULL)
    145             while (((gobble = getc(fp)) != EOF) && gobble != '\n');
     85   
     86    if (pid == 0) {
     87        char *args[4];
     88#define ADMOF_PATH "/usr/local/sbin/ssh-admof"
     89        args[0] = ADMOF_PATH;
     90        args[1] = (char *) luser;
     91        args[2] = princname;
     92        args[3] = NULL;
     93        execv(ADMOF_PATH, args);
     94        exit(1);
    14695    }
    14796
     97    if (waitpid(pid, &status, 0) > 0 && WIFEXITED(status) && WEXITSTATUS(status) == 33) {
     98        result = ACCEPT;
     99    }
     100   
    148101cleanup:
    149102    free(princname);
    150     free(filename);
    151     if (fp != NULL)
    152         fclose(fp);
    153103    /* If k5login files are non-authoritative, never reject. */
    154104    return (!authoritative && result == REJECT) ? PASS : result;
    155105}
Note: See TracBrowser for help on using the repository browser.