View | Details | Raw Unified | Return to bug 225451 | Differences between
and this patch

Collapse All | Expand All

(-)openssh-7.4p1/auth-krb5.c (-2 / +18 lines)
Lines 54-59 Link Here
54
54
55
extern ServerOptions	 options;
55
extern ServerOptions	 options;
56
56
57
int
58
ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client,
59
                 int k5login_exists)
60
{
61
	if (options.use_kuserok || !k5login_exists)
62
		return krb5_kuserok(krb5_ctx, krb5_user, client);
63
	else {
64
		char kuser[65];
65
66
		if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser))
67
			return 0;
68
		return strcmp(kuser, client) == 0;
69
	}
70
}
71
57
static int
72
static int
58
krb5_init(void *context)
73
krb5_init(void *context)
59
{
74
{
Lines 157-164 auth_krb5_password(Authctxt *authctxt, c Link Here
157
	if (problem)
172
	if (problem)
158
		goto out;
173
		goto out;
159
174
160
	if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
175
	/* Use !options.use_kuserok here to make ssh_krb5_kuserok() not
161
	    authctxt->pw->pw_name)) {
176
	 * depend on the existance of .k5login */
177
	if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name, !options.use_kuserok)) {
162
		problem = -1;
178
		problem = -1;
163
		goto out;
179
		goto out;
164
	}
180
	}
(-)openssh-7.4p1/gss-serv-krb5.c (-4 / +102 lines)
Lines 67-72 static int ssh_gssapi_krb5_cmdok(krb5_pr Link Here
67
    int);
67
    int);
68
68
69
static krb5_context krb_context = NULL;
69
static krb5_context krb_context = NULL;
70
extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *, int);
70
71
71
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
72
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
72
73
Lines 92-97 ssh_gssapi_krb5_init(void) Link Here
92
 * Returns true if the user is OK to log in, otherwise returns 0
93
 * Returns true if the user is OK to log in, otherwise returns 0
93
 */
94
 */
94
95
96
/* The purpose of the function is to find out if a Kerberos principal is
97
 * allowed to log in as the given local user. This is a general problem with
98
 * Kerberized services because by design the Kerberos principals are
99
 * completely independent from the local user names. This is one of the
100
 * reasons why Kerberos is working well on different operating systems like
101
 * Windows and UNIX/Linux. Nevertheless a relationship between a Kerberos
102
 * principal and a local user name must be established because otherwise every
103
 * access would be granted for every principal with a valid ticket.
104
 *
105
 * Since it is a general issue libkrb5 provides some functions for
106
 * applications to find out about the relationship between the Kerberos
107
 * principal and a local user name. They are krb5_kuserok() and
108
 * krb5_aname_to_localname().
109
 *
110
 * krb5_kuserok() can be used to "Determine if a principal is authorized to
111
 * log in as a local user" (from the MIT Kerberos documentation of this
112
 * function). Which is exactly what we are looking for and should be the
113
 * preferred choice. It accepts the Kerberos principal and a local user name
114
 * and let libkrb5 or its plugins determine if they relate to each other or
115
 * not.
116
 *
117
 * krb5_aname_to_localname() can use used to "Convert a principal name to a
118
 * local name" (from the MIT Kerberos documentation of this function). It
119
 * accepts a Kerberos principle and returns a local name and it is up to the
120
 * application to do any additional checks. There are two issues using
121
 * krb5_aname_to_localname(). First, since POSIX user names are case
122
 * sensitive, the calling application in general has no other choice than
123
 * doing a case-sensitive string comparison between the name returned by
124
 * krb5_aname_to_localname() and the name used at the login prompt. When the
125
 * users are provided by a case in-sensitive server, e.g. Active Directory,
126
 * this might lead to login failures because the user typing the name at the
127
 * login prompt might not be aware of the right case. Another issue might be
128
 * caused if there are multiple alias names available for a single user. E.g.
129
 * the canonical name of a user is user@group.department.example.com but there
130
 * exists a shorter login name, e.g. user@example.com, to safe typing at the
131
 * login prompt. Here krb5_aname_to_localname() can only return the canonical
132
 * name, but if the short alias is used at the login prompt authentication
133
 * will fail as well. All this can be avoided by using krb5_kuserok() and
134
 * configuring krb5.conf or using a suitable plugin to meet the needs of the
135
 * given environment.
136
 *
137
 * The Fedora and RHEL version of openssh contain two patches which modify the
138
 * access control behavior:
139
 *  - openssh-6.6p1-kuserok.patch
140
 *  - openssh-6.6p1-force_krb.patch
141
 *
142
 * openssh-6.6p1-kuserok.patch adds a new option KerberosUseKuserok for
143
 * sshd_config which controls if krb5_kuserok() is used to check if the
144
 * principle is authorized or if krb5_aname_to_localname() should be used.
145
 * The reason to add this patch was that krb5_kuserok() by default checks if
146
 * a .k5login file exits in the users home-directory. With this the user can
147
 * give access to his account for any given principal which might be
148
 * in violation with company policies and it would be useful if this can be
149
 * rejected. Nevertheless the patch ignores the fact that krb5_kuserok() does
150
 * no only check .k5login but other sources as well and checking .k5login can
151
 * be disabled for all applications in krb5.conf as well. With this new
152
 * option KerberosUseKuserok set to 'no' (and this is the default for RHEL7
153
 * and Fedora 21) openssh can only use krb5_aname_to_localname() with the
154
 * restrictions mentioned above.
155
 *
156
 * openssh-6.6p1-force_krb.patch adds a ksu like behaviour to ssh, i.e. when
157
 * using GSSAPI authentication only commands configured in the .k5user can be
158
 * executed. Here the wrong assumption that krb5_kuserok() only checks
159
 * .k5login is made as well. In contrast ksu checks .k5login directly and
160
 * does not use krb5_kuserok() which might be more useful for the given
161
 * purpose. Additionally this patch is not synced with
162
 * openssh-6.6p1-kuserok.patch.
163
 *
164
 * The current patch tries to restore the usage of krb5_kuserok() so that e.g.
165
 * localauth plugins can be used. It does so by adding a forth parameter to
166
 * ssh_krb5_kuserok() which indicates whether .k5login exists or not. If it
167
 * does not exists krb5_kuserok() is called even if KerberosUseKuserok is set
168
 * to 'no' because the intent of the option is to not check .k5login and if it
169
 * does not exists krb5_kuserok() returns a result without checking .k5login.
170
 * If .k5login does exists and KerberosUseKuserok is 'no' we fall back to
171
 * krb5_aname_to_localname(). This is in my point of view an acceptable
172
 * limitation and does not break the current behaviour.
173
 *
174
 * Additionally with this patch ssh_krb5_kuserok() is called in
175
 * ssh_gssapi_krb5_cmdok() instead of only krb5_aname_to_localname() is
176
 * neither .k5login nor .k5users exists to allow plugin evaluation via
177
 * krb5_kuserok() as well.
178
 *
179
 * I tried to keep the patch as minimal as possible, nevertheless I see some
180
 * areas for improvement which, if they make sense, have to be evaluated
181
 * carefully because they might change existing behaviour and cause breaks
182
 * during upgrade:
183
 * - I wonder if disabling .k5login usage make sense in sshd or if it should
184
 *   be better disabled globally in krb5.conf
185
 * - if really needed openssh-6.6p1-kuserok.patch should be fixed to really
186
 *   only disable checking .k5login and maybe .k5users
187
 * - the ksu behaviour should be configurable and maybe check the .k5login and
188
 *   .k5users files directly like ksu itself does
189
 * - to make krb5_aname_to_localname() more useful an option for sshd to use
190
 *   the canonical name (the one returned by getpwnam()) instead of the name
191
 *   given at the login prompt might be useful */
192
95
static int
193
static int
96
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
194
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
97
{
195
{
Lines 116-122 ssh_gssapi_krb5_userok(ssh_gssapi_client Link Here
116
	/* NOTE: .k5login and .k5users must opened as root, not the user,
214
	/* NOTE: .k5login and .k5users must opened as root, not the user,
117
	 * because if they are on a krb5-protected filesystem, user credentials
215
	 * because if they are on a krb5-protected filesystem, user credentials
118
	 * to access these files aren't available yet. */
216
	 * to access these files aren't available yet. */
119
	if (krb5_kuserok(krb_context, princ, name) && k5login_exists) {
217
	if (ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)
218
			&& k5login_exists) {
120
		retval = 1;
219
		retval = 1;
121
		logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
220
		logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
122
		    name, (char *)client->displayname.value);
221
		    name, (char *)client->displayname.value);
Lines 171-179 ssh_gssapi_krb5_cmdok(krb5_principal pri Link Here
171
	snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
270
	snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
172
	/* If both .k5login and .k5users DNE, self-login is ok. */
271
	/* If both .k5login and .k5users DNE, self-login is ok. */
173
	if (!k5login_exists && (access(file, F_OK) == -1)) {
272
	if (!k5login_exists && (access(file, F_OK) == -1)) {
174
		return (krb5_aname_to_localname(krb_context, principal,
273
                return ssh_krb5_kuserok(krb_context, principal, luser,
175
		    sizeof(kuser), kuser) == 0) &&
274
                                        k5login_exists);
176
		    (strcmp(kuser, luser) == 0);
177
	}
275
	}
178
	if ((fp = fopen(file, "r")) == NULL) {
276
	if ((fp = fopen(file, "r")) == NULL) {
179
		int saved_errno = errno;
277
		int saved_errno = errno;
(-)openssh-7.4p1/servconf.c (-1 / +12 lines)
Lines 165-170 initialize_server_options(ServerOptions Link Here
165
	options->ip_qos_interactive = -1;
165
	options->ip_qos_interactive = -1;
166
	options->ip_qos_bulk = -1;
166
	options->ip_qos_bulk = -1;
167
	options->version_addendum = NULL;
167
	options->version_addendum = NULL;
168
	options->use_kuserok = -1;
168
	options->fingerprint_hash = -1;
169
	options->fingerprint_hash = -1;
169
	options->disable_forwarding = -1;
170
	options->disable_forwarding = -1;
170
}
171
}
Lines 334-339 fill_default_server_options(ServerOption Link Here
334
		options->version_addendum = xstrdup("");
335
		options->version_addendum = xstrdup("");
335
	if (options->show_patchlevel == -1)
336
	if (options->show_patchlevel == -1)
336
		options->show_patchlevel = 0;
337
		options->show_patchlevel = 0;
338
	if (options->use_kuserok == -1)
339
		options->use_kuserok = 1;
337
	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
340
	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
338
		options->fwd_opts.streamlocal_bind_mask = 0177;
341
		options->fwd_opts.streamlocal_bind_mask = 0177;
339
	if (options->fwd_opts.streamlocal_bind_unlink == -1)
342
	if (options->fwd_opts.streamlocal_bind_unlink == -1)
Lines 399-405 typedef enum { Link Here
399
	sPermitRootLogin, sLogFacility, sLogLevel,
402
	sPermitRootLogin, sLogFacility, sLogLevel,
400
	sRhostsRSAAuthentication, sRSAAuthentication,
403
	sRhostsRSAAuthentication, sRSAAuthentication,
401
	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
404
	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
402
	sKerberosGetAFSToken,
405
	sKerberosGetAFSToken, sKerberosUseKuserok,
403
	sKerberosTgtPassing, sChallengeResponseAuthentication,
406
	sKerberosTgtPassing, sChallengeResponseAuthentication,
404
	sPasswordAuthentication, sKbdInteractiveAuthentication,
407
	sPasswordAuthentication, sKbdInteractiveAuthentication,
405
	sListenAddress, sAddressFamily,
408
	sListenAddress, sAddressFamily,
Lines 478-488 static struct { Link Here
478
#else
481
#else
479
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
482
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
480
#endif
483
#endif
484
	{ "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL },
481
#else
485
#else
482
	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
486
	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
483
	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
487
	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
484
	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
488
	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
485
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
489
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
490
	{ "kerberosusekuserok", sUnsupported, SSHCFG_ALL },
486
#endif
491
#endif
487
	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
492
	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
488
	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
493
	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
Lines 1644-1649 process_server_config_line(ServerOptions Link Here
1644
		*activep = value;
1649
		*activep = value;
1645
		break;
1650
		break;
1646
1651
1652
	case sKerberosUseKuserok:
1653
		intptr = &options->use_kuserok;
1654
		goto parse_flag;
1655
1647
	case sPermitOpen:
1656
	case sPermitOpen:
1648
		arg = strdelim(&cp);
1657
		arg = strdelim(&cp);
1649
		if (!arg || *arg == '\0')
1658
		if (!arg || *arg == '\0')
Lines 2016-2021 copy_set_server_options(ServerOptions *d Link Here
2016
	M_CP_INTOPT(client_alive_interval);
2025
	M_CP_INTOPT(client_alive_interval);
2017
	M_CP_INTOPT(ip_qos_interactive);
2026
	M_CP_INTOPT(ip_qos_interactive);
2018
	M_CP_INTOPT(ip_qos_bulk);
2027
	M_CP_INTOPT(ip_qos_bulk);
2028
	M_CP_INTOPT(use_kuserok);
2019
	M_CP_INTOPT(rekey_limit);
2029
	M_CP_INTOPT(rekey_limit);
2020
	M_CP_INTOPT(rekey_interval);
2030
	M_CP_INTOPT(rekey_interval);
2021
2031
Lines 2308-2313 dump_config(ServerOptions *o) Link Here
2308
	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2318
	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2309
	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2319
	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2310
	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
2320
	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
2321
	dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
2311
	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2322
	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2312
2323
2313
	/* string arguments */
2324
	/* string arguments */
(-)openssh-7.4p1/servconf.h (+1 lines)
Lines 174-179 typedef struct { Link Here
174
174
175
	int	num_permitted_opens;
175
	int	num_permitted_opens;
176
176
177
	int	use_kuserok;
177
	char   *chroot_directory;
178
	char   *chroot_directory;
178
	char   *revoked_keys_file;
179
	char   *revoked_keys_file;
179
	char   *trusted_user_ca_keys;
180
	char   *trusted_user_ca_keys;
(-)openssh-7.4p1/sshd_config.5 (+5 lines)
Lines 846-851 Specifies whether to automatically destr Link Here
846
file on logout.
846
file on logout.
847
The default is
847
The default is
848
.Cm yes .
848
.Cm yes .
849
.It Cm KerberosUseKuserok
850
Specifies whether to look at .k5login file for user's aliases.
851
The default is
852
.Cm yes .
849
.It Cm KexAlgorithms
853
.It Cm KexAlgorithms
850
Specifies the available KEX (Key Exchange) algorithms.
854
Specifies the available KEX (Key Exchange) algorithms.
851
Multiple algorithms must be comma-separated.
855
Multiple algorithms must be comma-separated.
Lines 1074-1079 Available keywords are Link Here
1074
.Cm IPQoS ,
1078
.Cm IPQoS ,
1075
.Cm KbdInteractiveAuthentication ,
1079
.Cm KbdInteractiveAuthentication ,
1076
.Cm KerberosAuthentication ,
1080
.Cm KerberosAuthentication ,
1081
.Cm KerberosUseKuserok ,
1077
.Cm MaxAuthTries ,
1082
.Cm MaxAuthTries ,
1078
.Cm MaxSessions ,
1083
.Cm MaxSessions ,
1079
.Cm PasswordAuthentication ,
1084
.Cm PasswordAuthentication ,
(-)openssh-7.4p1/sshd_config (+1 lines)
Lines 73-78 ChallengeResponseAuthentication no Link Here
73
#KerberosOrLocalPasswd yes
73
#KerberosOrLocalPasswd yes
74
#KerberosTicketCleanup yes
74
#KerberosTicketCleanup yes
75
#KerberosGetAFSToken no
75
#KerberosGetAFSToken no
76
#KerberosUseKuserok yes
76
77
77
# GSSAPI options
78
# GSSAPI options
78
GSSAPIAuthentication yes
79
GSSAPIAuthentication yes

Return to bug 225451