diff --git a/openssh-6.3p1-kuserok.patch b/openssh-6.3p1-kuserok.patch deleted file mode 100644 index 60688db..0000000 --- a/openssh-6.3p1-kuserok.patch +++ /dev/null @@ -1,167 +0,0 @@ -diff -up openssh-6.3p1/auth-krb5.c.kuserok openssh-6.3p1/auth-krb5.c ---- openssh-6.3p1/auth-krb5.c.kuserok 2013-10-11 21:41:42.889087613 +0200 -+++ openssh-6.3p1/auth-krb5.c 2013-10-11 21:41:42.905087537 +0200 -@@ -55,6 +55,20 @@ - - extern ServerOptions options; - -+int -+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client) -+{ -+ if (options.use_kuserok) -+ return krb5_kuserok(krb5_ctx, krb5_user, client); -+ else { -+ char kuser[65]; -+ -+ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) -+ return 0; -+ return strcmp(kuser, client) == 0; -+ } -+} -+ - static int - krb5_init(void *context) - { -@@ -159,7 +173,7 @@ auth_krb5_password(Authctxt *authctxt, c - if (problem) - goto out; - -- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { -+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { - problem = -1; - goto out; - } -diff -up openssh-6.3p1/gss-serv-krb5.c.kuserok openssh-6.3p1/gss-serv-krb5.c ---- openssh-6.3p1/gss-serv-krb5.c.kuserok 2013-10-11 21:41:42.901087556 +0200 -+++ openssh-6.3p1/gss-serv-krb5.c 2013-10-11 21:46:42.898673597 +0200 -@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr - int); - - static krb5_context krb_context = NULL; -+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *); - - /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ - -@@ -116,7 +117,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - /* NOTE: .k5login and .k5users must opened as root, not the user, - * because if they are on a krb5-protected filesystem, user credentials - * to access these files aren't available yet. */ -- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { -+ if (ssh_krb5_kuserok(krb_context, princ, name) && k5login_exists) { - retval = 1; - logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", - name, (char *)client->displayname.value); -diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c ---- openssh-6.3p1/servconf.c.kuserok 2013-10-11 21:41:42.896087580 +0200 -+++ openssh-6.3p1/servconf.c 2013-10-11 21:48:24.664194016 +0200 -@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions - options->ip_qos_interactive = -1; - options->ip_qos_bulk = -1; - options->version_addendum = NULL; -+ options->use_kuserok = -1; - } - - void -@@ -310,6 +311,8 @@ fill_default_server_options(ServerOption - options->version_addendum = xstrdup(""); - if (options->show_patchlevel == -1) - options->show_patchlevel = 0; -+ if (options->use_kuserok == -1) -+ options->use_kuserok = 1; - - /* Turn privilege separation on by default */ - if (use_privsep == -1) -@@ -336,7 +339,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, -+ sKerberosGetAFSToken, sKerberosUseKuserok, - sKerberosTgtPassing, sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, -@@ -409,11 +412,13 @@ static struct { - #else - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, - #endif -+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, - #else - { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, - { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, -+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, - #endif - { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, - { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1515,6 +1520,10 @@ process_server_config_line(ServerOptions - *activep = value; - break; - -+ case sKerberosUseKuserok: -+ intptr = &options->use_kuserok; -+ goto parse_flag; -+ - case sPermitOpen: - arg = strdelim(&cp); - if (!arg || *arg == '\0') -@@ -1815,6 +1824,7 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(max_authtries); - M_CP_INTOPT(ip_qos_interactive); - M_CP_INTOPT(ip_qos_bulk); -+ M_CP_INTOPT(use_kuserok); - M_CP_INTOPT(rekey_limit); - M_CP_INTOPT(rekey_interval); - -@@ -2055,6 +2065,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); -+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-6.3p1/servconf.h.kuserok openssh-6.3p1/servconf.h ---- openssh-6.3p1/servconf.h.kuserok 2013-10-11 21:41:42.896087580 +0200 -+++ openssh-6.3p1/servconf.h 2013-10-11 21:41:42.907087528 +0200 -@@ -174,6 +174,7 @@ typedef struct { - - int num_permitted_opens; - -+ int use_kuserok; - char *chroot_directory; - char *revoked_keys_file; - char *trusted_user_ca_keys; -diff -up openssh-6.3p1/sshd_config.5.kuserok openssh-6.3p1/sshd_config.5 ---- openssh-6.3p1/sshd_config.5.kuserok 2013-10-11 21:41:42.898087571 +0200 -+++ openssh-6.3p1/sshd_config.5 2013-10-11 21:41:42.907087528 +0200 -@@ -675,6 +675,10 @@ Specifies whether to automatically destr - file on logout. - The default is - .Dq yes . -+.It Cm KerberosUseKuserok -+Specifies whether to look at .k5login file for user's aliases. -+The default is -+.Dq yes . - .It Cm KexAlgorithms - Specifies the available KEX (Key Exchange) algorithms. - Multiple algorithms must be comma-separated. -@@ -833,6 +837,7 @@ Available keywords are - .Cm HostbasedUsesNameFromPacketOnly , - .Cm KbdInteractiveAuthentication , - .Cm KerberosAuthentication , -+.Cm KerberosUseKuserok , - .Cm MaxAuthTries , - .Cm MaxSessions , - .Cm PasswordAuthentication , -diff -up openssh-6.3p1/sshd_config.kuserok openssh-6.3p1/sshd_config ---- openssh-6.3p1/sshd_config.kuserok 2013-10-11 21:41:42.898087571 +0200 -+++ openssh-6.3p1/sshd_config 2013-10-11 21:41:42.907087528 +0200 -@@ -86,6 +86,7 @@ ChallengeResponseAuthentication no - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok yes - - # GSSAPI options - #GSSAPIAuthentication no diff --git a/openssh-6.4p1-kuserok.patch b/openssh-6.4p1-kuserok.patch new file mode 100644 index 0000000..4a5b7f8 --- /dev/null +++ b/openssh-6.4p1-kuserok.patch @@ -0,0 +1,291 @@ +diff --git a/auth-krb5.c b/auth-krb5.c +index 7c83f59..966b4cb 100644 +--- a/auth-krb5.c ++++ b/auth-krb5.c +@@ -54,6 +54,21 @@ + + extern ServerOptions options; + ++int ++ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client, ++ int k5login_exists) ++{ ++ if (options.use_kuserok || !k5login_exists) ++ return krb5_kuserok(krb5_ctx, krb5_user, client); ++ else { ++ char kuser[65]; ++ ++ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) ++ return 0; ++ return strcmp(kuser, client) == 0; ++ } ++} ++ + static int + krb5_init(void *context) + { +@@ -157,7 +172,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password) + if (problem) + goto out; + +- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { ++ /* Use !options.use_kuserok here to make ssh_krb5_kuserok() not ++ * depend on the existance of .k5login */ ++ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client, !options.use_kuserok)) { + problem = -1; + goto out; + } +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index b4d479e..a9326a7 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, + int); + + static krb5_context krb_context = NULL; ++extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *, int); + + /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ + +@@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void) + * Returns true if the user is OK to log in, otherwise returns 0 + */ + ++/* The purpose of the function is to find out if a Kerberos principal is ++ * allowed to log in as the given local user. This is a general problem with ++ * Kerberized services because by design the Kerberos principals are ++ * completely independent from the local user names. This is one of the ++ * reasons why Kerberos is working well on different operating systems like ++ * Windows and UNIX/Linux. Nevertheless a relationship between a Kerberos ++ * principal and a local user name must be established because otherwise every ++ * access would be granted for every principal with a valid ticket. ++ * ++ * Since it is a general issue libkrb5 provides some functions for ++ * applications to find out about the relationship between the Kerberos ++ * principal and a local user name. They are krb5_kuserok() and ++ * krb5_aname_to_localname(). ++ * ++ * krb5_kuserok() can be used to "Determine if a principal is authorized to ++ * log in as a local user" (from the MIT Kerberos documentation of this ++ * function). Which is exactly what we are looking for and should be the ++ * preferred choice. It accepts the Kerberos principal and a local user name ++ * and let libkrb5 or its plugins determine if they relate to each other or ++ * not. ++ * ++ * krb5_aname_to_localname() can use used to "Convert a principal name to a ++ * local name" (from the MIT Kerberos documentation of this function). It ++ * accepts a Kerberos principle and returns a local name and it is up to the ++ * application to do any additional checks. There are two issues using ++ * krb5_aname_to_localname(). First, since POSIX user names are case ++ * sensitive, the calling application in general has no other choice than ++ * doing a case-sensitive string comparison between the name returned by ++ * krb5_aname_to_localname() and the name used at the login prompt. When the ++ * users are provided by a case in-sensitive server, e.g. Active Directory, ++ * this might lead to login failures because the user typing the name at the ++ * login prompt might not be aware of the right case. Another issue might be ++ * caused if there are multiple alias names available for a single user. E.g. ++ * the canonical name of a user is user@group.department.example.com but there ++ * exists a shorter login name, e.g. user@example.com, to safe typing at the ++ * login prompt. Here krb5_aname_to_localname() can only return the canonical ++ * name, but if the short alias is used at the login prompt authentication ++ * will fail as well. All this can be avoided by using krb5_kuserok() and ++ * configuring krb5.conf or using a suitable plugin to meet the needs of the ++ * given environment. ++ * ++ * The Fedora and RHEL version of openssh contain two patches which modify the ++ * access control behavior: ++ * - openssh-6.6p1-kuserok.patch ++ * - openssh-6.6p1-force_krb.patch ++ * ++ * openssh-6.6p1-kuserok.patch adds a new option KerberosUseKuserok for ++ * sshd_config which controls if krb5_kuserok() is used to check if the ++ * principle is authorized or if krb5_aname_to_localname() should be used. ++ * The reason to add this patch was that krb5_kuserok() by default checks if ++ * a .k5login file exits in the users home-directory. With this the user can ++ * give access to his account for any given principal which might be ++ * in violation with company policies and it would be useful if this can be ++ * rejected. Nevertheless the patch ignores the fact that krb5_kuserok() does ++ * no only check .k5login but other sources as well and checking .k5login can ++ * be disabled for all applications in krb5.conf as well. With this new ++ * option KerberosUseKuserok set to 'no' (and this is the default for RHEL7 ++ * and Fedora 21) openssh can only use krb5_aname_to_localname() with the ++ * restrictions mentioned above. ++ * ++ * openssh-6.6p1-force_krb.patch adds a ksu like behaviour to ssh, i.e. when ++ * using GSSAPI authentication only commands configured in the .k5user can be ++ * executed. Here the wrong assumption that krb5_kuserok() only checks ++ * .k5login is made as well. In contrast ksu checks .k5login directly and ++ * does not use krb5_kuserok() which might be more useful for the given ++ * purpose. Additionally this patch is not synced with ++ * openssh-6.6p1-kuserok.patch. ++ * ++ * The current patch tries to restore the usage of krb5_kuserok() so that e.g. ++ * localauth plugins can be used. It does so by adding a forth parameter to ++ * ssh_krb5_kuserok() which indicates whether .k5login exists or not. If it ++ * does not exists krb5_kuserok() is called even if KerberosUseKuserok is set ++ * to 'no' because the intent of the option is to not check .k5login and if it ++ * does not exists krb5_kuserok() returns a result without checking .k5login. ++ * If .k5login does exists and KerberosUseKuserok is 'no' we fall back to ++ * krb5_aname_to_localname(). This is in my point of view an acceptable ++ * limitation and does not break the current behaviour. ++ * ++ * Additionally with this patch ssh_krb5_kuserok() is called in ++ * ssh_gssapi_krb5_cmdok() instead of only krb5_aname_to_localname() is ++ * neither .k5login nor .k5users exists to allow plugin evaluation via ++ * krb5_kuserok() as well. ++ * ++ * I tried to keep the patch as minimal as possible, nevertheless I see some ++ * areas for improvement which, if they make sense, have to be evaluated ++ * carefully because they might change existing behaviour and cause breaks ++ * during upgrade: ++ * - I wonder if disabling .k5login usage make sense in sshd or if it should ++ * be better disabled globally in krb5.conf ++ * - if really needed openssh-6.6p1-kuserok.patch should be fixed to really ++ * only disable checking .k5login and maybe .k5users ++ * - the ksu behaviour should be configurable and maybe check the .k5login and ++ * .k5users files directly like ksu itself does ++ * - to make krb5_aname_to_localname() more useful an option for sshd to use ++ * the canonical name (the one returned by getpwnam()) instead of the name ++ * given at the login prompt might be useful */ ++ + static int + ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) + { +@@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) + /* NOTE: .k5login and .k5users must opened as root, not the user, + * because if they are on a krb5-protected filesystem, user credentials + * to access these files aren't available yet. */ +- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { ++ if (ssh_krb5_kuserok(krb_context, princ, name, k5login_exists) ++ && k5login_exists) { + retval = 1; + logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", + name, (char *)client->displayname.value); +@@ -171,9 +270,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, + snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); + /* If both .k5login and .k5users DNE, self-login is ok. */ + if (!k5login_exists && (access(file, F_OK) == -1)) { +- return (krb5_aname_to_localname(krb_context, principal, +- sizeof(kuser), kuser) == 0) && +- (strcmp(kuser, luser) == 0); ++ return ssh_krb5_kuserok(krb_context, principal, luser, ++ k5login_exists); + } + if ((fp = fopen(file, "r")) == NULL) { + int saved_errno = errno; +diff --git a/servconf.c b/servconf.c +index 277b2bd..1e88905 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions *options) + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->version_addendum = NULL; ++ options->use_kuserok = -1; + } + + void +@@ -310,6 +311,8 @@ fill_default_server_options(ServerOptions *options) + options->version_addendum = xstrdup(""); + if (options->show_patchlevel == -1) + options->show_patchlevel = 0; ++ if (options->use_kuserok == -1) ++ options->use_kuserok = 1; + + /* Turn privilege separation on by default */ + if (use_privsep == -1) +@@ -336,7 +339,7 @@ typedef enum { + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsRSAAuthentication, sRSAAuthentication, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +- sKerberosGetAFSToken, ++ sKerberosGetAFSToken, sKerberosUseKuserok, + sKerberosTgtPassing, sChallengeResponseAuthentication, + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, +@@ -409,11 +412,13 @@ static struct { + #else + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, + #endif ++ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, + #else + { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, + { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, ++ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, + #endif + { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, + { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, +@@ -1515,6 +1520,10 @@ process_server_config_line(ServerOptions *options, char *line, + *activep = value; + break; + ++ case sKerberosUseKuserok: ++ intptr = &options->use_kuserok; ++ goto parse_flag; ++ + case sPermitOpen: + arg = strdelim(&cp); + if (!arg || *arg == '\0') +@@ -1815,6 +1824,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + M_CP_INTOPT(max_authtries); + M_CP_INTOPT(ip_qos_interactive); + M_CP_INTOPT(ip_qos_bulk); ++ M_CP_INTOPT(use_kuserok); + M_CP_INTOPT(rekey_limit); + M_CP_INTOPT(rekey_interval); + +@@ -2055,6 +2065,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sUseDNS, o->use_dns); + dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); ++ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); +diff --git a/servconf.h b/servconf.h +index 57752cb..615aaba 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -174,6 +174,7 @@ typedef struct { + + int num_permitted_opens; + ++ int use_kuserok; + char *chroot_directory; + char *revoked_keys_file; + char *trusted_user_ca_keys; +diff -up openssh-6.3p1/sshd_config.5.kuserok openssh-6.3p1/sshd_config.5 +--- openssh-6.3p1/sshd_config.5.kuserok 2013-10-11 21:41:42.898087571 +0200 ++++ openssh-6.3p1/sshd_config.5 2013-10-11 21:41:42.907087528 +0200 +@@ -675,6 +675,10 @@ Specifies whether to automatically destr + file on logout. + The default is + .Dq yes . ++.It Cm KerberosUseKuserok ++Specifies whether to look at .k5login file for user's aliases. ++The default is ++.Dq yes . + .It Cm KexAlgorithms + Specifies the available KEX (Key Exchange) algorithms. + Multiple algorithms must be comma-separated. +@@ -833,6 +837,7 @@ Available keywords are + .Cm HostbasedUsesNameFromPacketOnly , + .Cm KbdInteractiveAuthentication , + .Cm KerberosAuthentication , ++.Cm KerberosUseKuserok , + .Cm MaxAuthTries , + .Cm MaxSessions , + .Cm PasswordAuthentication , +diff -up openssh-6.3p1/sshd_config.kuserok openssh-6.3p1/sshd_config +--- openssh-6.3p1/sshd_config.kuserok 2013-10-11 21:41:42.898087571 +0200 ++++ openssh-6.3p1/sshd_config 2013-10-11 21:41:42.907087528 +0200 +@@ -86,6 +86,7 @@ ChallengeResponseAuthentication no + #KerberosOrLocalPasswd yes + #KerberosTicketCleanup yes + #KerberosGetAFSToken no ++#KerberosUseKuserok yes + + # GSSAPI options + #GSSAPIAuthentication no diff --git a/openssh.spec b/openssh.spec index 2c035f3..2befa21 100644 --- a/openssh.spec +++ b/openssh.spec @@ -177,7 +177,7 @@ Patch800: openssh-6.3p1-gsskex.patch Patch801: openssh-6.3p1-force_krb.patch Patch900: openssh-6.1p1-gssapi-canohost.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 -Patch901: openssh-6.3p1-kuserok.patch +Patch901: openssh-6.4p1-kuserok.patch # use default_ccache_name from /etc/krb5.conf (#991186) Patch902: openssh-6.3p1-krb5-use-default_ccache_name.patch # increase the size of the Diffie-Hellman groups (#1010607)