[krb5] - pull down patches from trunk to implement k5login_authoritative and k5login_directory settings f

Nalin Dahyabhai nalin at fedoraproject.org
Mon Oct 4 22:57:17 UTC 2010


commit 0d4651fac9141255523bde51cf3f23d66cafc9d8
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date:   Mon Oct 4 15:34:24 2010 -0400

    - pull down patches from trunk to implement k5login_authoritative and
      k5login_directory settings for krb5.conf (#539423)

 krb5-trunk-k5login.patch |  333 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 333 insertions(+), 0 deletions(-)
---
diff --git a/krb5-trunk-k5login.patch b/krb5-trunk-k5login.patch
new file mode 100644
index 0000000..e3bfc94
--- /dev/null
+++ b/krb5-trunk-k5login.patch
@@ -0,0 +1,333 @@
+commit 3ec524d3aa8f92b150a02062ae8faf0bb2ffaa9d
+Author: ghudson <ghudson at dc483132-0cff-0310-8789-dd5450dbe970>
+Date:   Fri Oct 1 15:56:30 2010 +0000
+
+    ticket: 6792
+    subject: Implement k5login_directory and k5login_authoritative options
+    
+    Add and document two new options for controlling k5login behavior.
+    
+    
+    git-svn-id: svn://anonsvn.mit.edu:/krb5/trunk@24402 dc483132-0cff-0310-8789-dd5450dbe970
+
+diff --git a/doc/admin.texinfo b/doc/admin.texinfo
+index 8603b93..2a811de 100644
+--- a/doc/admin.texinfo
++++ b/doc/admin.texinfo
+@@ -468,6 +468,20 @@ Sets the maximum allowable amount of clockskew in seconds that the
+ library  will tolerate before assuming that a Kerberos message is
+ invalid.  The default value is @value{DefaultClockskew}.
+ 
++ at itemx k5login_authoritative
++If the value of this relation is true (the default), principals must
++be listed in a local user's k5login file to be granted login access,
++if a k5login file exists.  If the value of this relation is false, a
++principal may still be granted login access through other mechanisms
++even if a k5login file exists but does not list the principal.
++
++ at itemx k5login_directory
++If set, the library will look for a local user's k5login file within the
++named directory, with a filename corresponding to the local username.
++If not set, the library will look for k5login files in the user's home
++directory, with the filename @code{.k5login}.  For security reasons,
++k5login files must be owned by the local user or by root.
++
+ @itemx kdc_timesync
+ If this is set to 1 (for true), then client machines will compute the
+ difference between their time and the time returned by the KDC in the
+diff --git a/src/config-files/krb5.conf.M b/src/config-files/krb5.conf.M
+index 2995aa2..e658e89 100644
+--- a/src/config-files/krb5.conf.M
++++ b/src/config-files/krb5.conf.M
+@@ -155,6 +155,20 @@ This relation sets the maximum allowable amount of clockskew in seconds
+ that the library will tolerate before assuming that a Kerberos message
+ is invalid.  The default value is 300 seconds, or five minutes.
+ 
++.IP k5login_authoritative
++If the value of this relation is true (the default), principals must
++be listed in a local user's k5login file to be granted login access,
++if a k5login file exists.  If the value of this relation is false, a
++principal may still be granted login access through other mechanisms
++even if a k5login file exists but does not list the principal.
++
++.IP k5login_directory
++If set, the library will look for a local user's k5login file within
++the named directory, with a filename corresponding to the local
++username.  If not set, the library will look for k5login files in the
++user's home directory, with the filename .k5login.  For security
++reasons, k5login files must be owned by the local user or by root.
++
+ .IP kdc_timesync 
+ If the value of this relation is non-zero (the default), the library
+ will compute the difference between the system clock and the time
+diff --git a/src/include/k5-int.h b/src/include/k5-int.h
+index 750f989..f2a037c 100644
+--- a/src/include/k5-int.h
++++ b/src/include/k5-int.h
+@@ -222,6 +222,8 @@ typedef INT64_TYPE krb5_int64;
+ #define KRB5_CONF_IPROP_PORT                  "iprop_port"
+ #define KRB5_CONF_IPROP_SLAVE_POLL            "iprop_slave_poll"
+ #define KRB5_CONF_IPROP_LOGFILE               "iprop_logfile"
++#define KRB5_CONF_K5LOGIN_AUTHORITATIVE       "k5login_authoritative"
++#define KRB5_CONF_K5LOGIN_DIRECTORY           "k5login_directory"
+ #define KRB5_CONF_KADMIND_PORT                "kadmind_port"
+ #define KRB5_CONF_KRB524_SERVER               "krb524_server"
+ #define KRB5_CONF_KDC                         "kdc"
+diff --git a/src/lib/krb5/os/kuserok.c b/src/lib/krb5/os/kuserok.c
+index 1bc7505..985bb14 100644
+--- a/src/lib/krb5/os/kuserok.c
++++ b/src/lib/krb5/os/kuserok.c
+@@ -48,105 +48,138 @@
+ #define FILE_OWNER_OK(UID)  ((UID) == 0)
+ #endif
+ 
++enum result { ACCEPT, REJECT, PASS };
++
+ /*
+- * Given a Kerberos principal "principal", and a local username "luser",
+- * determine whether user is authorized to login according to the
+- * authorization file ("~luser/.k5login" by default).  Returns TRUE
+- * if authorized, FALSE if not authorized.
+- *
+- * If there is no account for "luser" on the local machine, returns
+- * FALSE.  If there is no authorization file, and the given Kerberos
+- * name "server" translates to the same name as "luser" (using
+- * krb5_aname_to_lname()), returns TRUE.  Otherwise, if the authorization file
+- * can't be accessed, returns FALSE.  Otherwise, the file is read for
+- * a matching principal name, instance, and realm.  If one is found,
+- * returns TRUE, if none is found, returns FALSE.
+- *
+- * The file entries are in the format produced by krb5_unparse_name(),
+- * one entry per line.
+- *
++ * Find the k5login filename for luser, either in the user's homedir or in a
++ * configured directory under the username.
+  */
++static krb5_error_code
++get_k5login_filename(krb5_context context, const char *luser,
++                     const char *homedir, char **filename_out)
++{
++    krb5_error_code ret;
++    char *dir, *filename;
+ 
+-krb5_boolean KRB5_CALLCONV
+-krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
++    *filename_out = NULL;
++    ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
++                             KRB5_CONF_K5LOGIN_DIRECTORY, NULL, NULL, &dir);
++    if (ret != 0)
++        return ret;
++
++    if (dir == NULL) {
++        /* Look in the user's homedir. */
++        if (asprintf(&filename, "%s/.k5login", homedir) < 0)
++            return ENOMEM;
++    } else {
++        /* Look in the configured directory. */
++        if (asprintf(&filename, "%s/%s", dir, luser) < 0)
++            ret = ENOMEM;
++        profile_release_string(dir);
++        if (ret)
++            return ret;
++    }
++    *filename_out = filename;
++    return 0;
++}
++
++/*
++ * Determine whether principal is authorized to log in as luser according to
++ * the user's k5login file.  Return ACCEPT if the k5login file authorizes the
++ * principal, PASS if the k5login file does not exist, or REJECT if the k5login
++ * file exists but does not authorize the principal.  If k5login files are
++ * configured to be non-authoritative, pass instead of rejecting.
++ */
++static enum result
++k5login_ok(krb5_context context, krb5_principal principal, const char *luser)
+ {
++    int authoritative = TRUE;
++    enum result result = REJECT;
++    char *filename = NULL, *princname = NULL;
++    char gobble, *newline, linebuf[BUFSIZ], pwbuf[BUFSIZ];
+     struct stat sbuf;
+-    struct passwd *pwd;
+-    char pbuf[MAXPATHLEN];
+-    krb5_boolean isok = FALSE;
+-    FILE *fp;
+-    char kuser[MAX_USERNAME];
+-    char *princname;
+-    char linebuf[BUFSIZ];
+-    char *newline;
+-    int gobble;
+-    char pwbuf[BUFSIZ];
+-    struct passwd pwx;
+-    int result;
+-
+-    /* no account => no access */
++    struct passwd pwx, *pwd;
++    FILE *fp = NULL;
++
++    if (profile_get_boolean(context->profile, KRB5_CONF_LIBDEFAULTS,
++                            KRB5_CONF_K5LOGIN_AUTHORITATIVE, NULL, TRUE,
++                            &authoritative) != 0)
++        goto cleanup;
++
++    /* Get the local user's homedir and uid. */
+     if (k5_getpwnam_r(luser, &pwx, pwbuf, sizeof(pwbuf), &pwd) != 0)
+-        return(FALSE);
+-    result = snprintf(pbuf, sizeof(pbuf), "%s/.k5login", pwd->pw_dir);
+-    if (SNPRINTF_OVERFLOW(result, sizeof(pbuf)))
+-        return(FALSE);
+-
+-    if (access(pbuf, F_OK)) {    /* not accessible */
+-        /*
+-         * if he's trying to log in as himself, and there is no .k5login file,
+-         * let him.  To find out, call
+-         * krb5_aname_to_localname to convert the principal to a name
+-         * which we can string compare.
+-         */
+-        if (!(krb5_aname_to_localname(context, principal,
+-                                      sizeof(kuser), kuser))
+-            && (strcmp(kuser, luser) == 0)) {
+-            return(TRUE);
+-        }
+-    }
+-    if (krb5_unparse_name(context, principal, &princname))
+-        return(FALSE);                  /* no hope of matching */
++        goto cleanup;
++
++    if (get_k5login_filename(context, luser, pwd->pw_dir, &filename) != 0)
++        goto cleanup;
+ 
+-    /* open ~/.k5login */
+-    if ((fp = fopen(pbuf, "r")) == NULL) {
+-        free(princname);
+-        return(FALSE);
++    if (access(filename, F_OK) != 0) {
++        result = PASS;
++        goto cleanup;
+     }
++
++    if (krb5_unparse_name(context, principal, &princname) != 0)
++        goto cleanup;
++
++    fp = fopen(filename, "r");
++    if (fp == NULL)
++        goto cleanup;
+     set_cloexec_file(fp);
+-    /*
+-     * For security reasons, the .k5login file must be owned either by
+-     * the user himself, or by root.  Otherwise, don't grant access.
+-     */
+-    if (fstat(fileno(fp), &sbuf)) {
+-        fclose(fp);
+-        free(princname);
+-        return(FALSE);
+-    }
+-    if (sbuf.st_uid != pwd->pw_uid && !FILE_OWNER_OK(sbuf.st_uid)) {
+-        fclose(fp);
+-        free(princname);
+-        return(FALSE);
+-    }
+ 
+-    /* check each line */
+-    while (!isok && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
+-        /* null-terminate the input string */
+-        linebuf[BUFSIZ-1] = '\0';
+-        newline = NULL;
+-        /* nuke the newline if it exists */
+-        if ((newline = strchr(linebuf, '\n')))
++    /* For security reasons, the .k5login file must be owned either by
++     * the user or by root. */
++    if (fstat(fileno(fp), &sbuf))
++        goto cleanup;
++    if (sbuf.st_uid != pwd->pw_uid && !FILE_OWNER_OK(sbuf.st_uid))
++        goto cleanup;
++
++    /* Check each line. */
++    while (result != ACCEPT && (fgets(linebuf, sizeof(linebuf), fp) != NULL)) {
++        newline = strrchr(linebuf, '\n');
++        if (newline != NULL)
+             *newline = '\0';
+-        if (!strcmp(linebuf, princname)) {
+-            isok = TRUE;
+-            continue;
+-        }
+-        /* clean up the rest of the line if necessary */
+-        if (!newline)
++        if (strcmp(linebuf, princname) == 0)
++            result = ACCEPT;
++        /* Clean up the rest of the line if necessary. */
++        if (newline == NULL)
+             while (((gobble = getc(fp)) != EOF) && gobble != '\n');
+     }
++
++cleanup:
+     free(princname);
+-    fclose(fp);
+-    return(isok);
++    free(filename);
++    if (fp != NULL)
++        fclose(fp);
++    /* If k5login files are non-authoritative, never reject. */
++    return (!authoritative && result == REJECT) ? PASS : result;
++}
++
++/*
++ * Determine whether principal is authorized to log in as luser according to
++ * aname-to-localname translation.  Return ACCEPT if principal translates to
++ * luser or PASS if it does not.
++ */
++static enum result
++an2ln_ok(krb5_context context, krb5_principal principal, const char *luser)
++{
++    krb5_error_code ret;
++    char kuser[MAX_USERNAME];
++
++    ret = krb5_aname_to_localname(context, principal, sizeof(kuser), kuser);
++    if (ret != 0)
++        return PASS;
++    return (strcmp(kuser, luser) == 0) ? ACCEPT : PASS;
++}
++
++krb5_boolean KRB5_CALLCONV
++krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
++{
++    enum result result;
++
++    result = k5login_ok(context, principal, luser);
++    if (result == PASS)
++        result = an2ln_ok(context, principal, luser);
++    return (result == ACCEPT) ? TRUE : FALSE;
+ }
+ 
+ #else /* _WIN32 */
+commit 6f46ab42b718410aee67a888b3fefe7df8ce2062
+Author: ghudson <ghudson at dc483132-0cff-0310-8789-dd5450dbe970>
+Date:   Sat Oct 2 11:48:06 2010 +0000
+
+    ticket: 6792
+    
+    In the krb5_kuserok implementation, fix an unintentional type change
+    to "gobble" (was an int, was accidentally changed to a char) which
+    could result in an infinite loop.
+    
+    
+    git-svn-id: svn://anonsvn.mit.edu:/krb5/trunk@24413 dc483132-0cff-0310-8789-dd5450dbe970
+
+diff --git a/src/lib/krb5/os/kuserok.c b/src/lib/krb5/os/kuserok.c
+index 985bb14..e1619f3 100644
+--- a/src/lib/krb5/os/kuserok.c
++++ b/src/lib/krb5/os/kuserok.c
+@@ -93,10 +93,10 @@ get_k5login_filename(krb5_context context, const char *luser,
+ static enum result
+ k5login_ok(krb5_context context, krb5_principal principal, const char *luser)
+ {
+-    int authoritative = TRUE;
++    int authoritative = TRUE, gobble;
+     enum result result = REJECT;
+     char *filename = NULL, *princname = NULL;
+-    char gobble, *newline, linebuf[BUFSIZ], pwbuf[BUFSIZ];
++    char *newline, linebuf[BUFSIZ], pwbuf[BUFSIZ];
+     struct stat sbuf;
+     struct passwd pwx, *pwd;
+     FILE *fp = NULL;


More information about the scm-commits mailing list