diff --git a/krb5-trunk-k5login.patch b/krb5-trunk-k5login.patch deleted file mode 100644 index e3bfc94..0000000 --- a/krb5-trunk-k5login.patch +++ /dev/null @@ -1,333 +0,0 @@ -commit 3ec524d3aa8f92b150a02062ae8faf0bb2ffaa9d -Author: ghudson -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}. - -+@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. -+ -+@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 -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;