source: trunk/server/common/patches/krb5-kuserok-scripts.patch @ 2581

Last change on this file since 2581 was 2066, checked in by achernya, 13 years ago
Merge branches/fc15-dev to trunk
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.