From a81e03693aa179416b55870a16ee6c22c4ac7a5c Mon Sep 17 00:00:00 2001 From: Cuison Date: Fri, 22 Sep 2017 01:34:13 -0400 Subject: [PATCH] Make username case sensitivity configurable --- auth.c | 20 +++++++++++++++----- servconf.c | 8 ++++++++ servconf.h | 1 + sshd_config | 10 ++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/auth.c b/auth.c index a449061741a..2653975d985 100644 --- a/auth.c +++ b/auth.c @@ -580,12 +580,22 @@ getpwnamallow(const char *user) #endif #ifdef HAVE_CYGWIN /* - * Windows usernames are case-insensitive. To avoid later problems - * when trying to match the username, the user is only allowed to - * login if the username is given in the same case as stored in the - * user database. + * The method getpwnam in Cygwin does not return the username in + * the same case all the time e.g. active directory username = + * "jediknight", a day or days after the username is returned as + * "JediKnight" but the active directory case for that user stays + * the same. Then on other days it can be "JEDIknight". Somehow the + * username is saved/cached in the case with which it was typed in + * during login but not all the time. An option (username_case_sensitive) + * was introduced to enable users to turn on/off username case + * sensitivity to mitigate the issue that was described above without + * doing anything to Cygwin or Windows. By default the username is + * case sensitive. */ - if (pw != NULL && strcmp(user, pw->pw_name) != 0) { + int userNameComparisonResult = options.username_case_sensitive == -1 ? + strcmp(user, pw->pw_name) : strcasecmp(user, pw->pw_name); + + if (pw != NULL && userNameComparisonResult != 0) { logit("Login name %.100s does not match stored username %.100s", user, pw->pw_name); pw = NULL; diff --git a/servconf.c b/servconf.c index 16436512e0f..3b94faebba5 100644 --- a/servconf.c +++ b/servconf.c @@ -165,6 +165,7 @@ initialize_server_options(ServerOptions *options) options->fingerprint_hash = -1; options->disable_forwarding = -1; options->expose_userauth_info = -1; + options->username_case_sensitive = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ @@ -422,6 +423,7 @@ typedef enum { sStreamLocalBindMask, sStreamLocalBindUnlink, sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, + sUserNameCaseSensitive, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; @@ -566,6 +568,7 @@ static struct { { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, + { "usernamecasesensitive", sUserNameCaseSensitive, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; @@ -1882,6 +1885,10 @@ process_server_config_line(ServerOptions *options, char *line, case sExposeAuthInfo: intptr = &options->expose_userauth_info; goto parse_flag; + + case sUserNameCaseSensitive: + intptr = &options->username_case_sensitive; + goto parse_flag; case sDeprecated: case sIgnore: @@ -2322,6 +2329,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); + dump_cfg_fmtint(sUserNameCaseSensitive, o->username_case_sensitive); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); diff --git a/servconf.h b/servconf.h index ffcbc33191f..72dfc139a82 100644 --- a/servconf.h +++ b/servconf.h @@ -198,6 +198,7 @@ typedef struct { int fingerprint_hash; int expose_userauth_info; + int username_case_sensitive; } ServerOptions; /* Information about the incoming connection as used by Match */ diff --git a/sshd_config b/sshd_config index 4eb2e02e044..f07bbc4de47 100644 --- a/sshd_config +++ b/sshd_config @@ -116,3 +116,13 @@ Subsystem sftp /usr/libexec/sftp-server # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server + +# This flag if set to "no" makes sshd ignore the username case. +# By default the usernames are compared by sshd case sensitively. +# The option to turn off username case sensitivity is mainly +# applicable to sshd running in Cygwin/Windows since for some reason +# the usernames on the specified platform return the username +# case differently to that of Active Directory intermittently. +# Suffice to say, the username case is inconsistent in Windows +# and auth fails when it happens thus the option to turn it off. +# UserNameCaseSensitive yes \ No newline at end of file