View | Details | Raw Unified | Return to bug 2775
Collapse All | Expand All

(-)a/auth-krb5.c (-33 / +233 lines)
Lines 51-56 Link Here
51
#include <unistd.h>
51
#include <unistd.h>
52
#include <string.h>
52
#include <string.h>
53
#include <krb5.h>
53
#include <krb5.h>
54
#include <profile.h>
54
55
55
extern ServerOptions	 options;
56
extern ServerOptions	 options;
56
57
Lines 77-83 auth_krb5_password(Authctxt *authctxt, const char *password) Link Here
77
#endif
78
#endif
78
	krb5_error_code problem;
79
	krb5_error_code problem;
79
	krb5_ccache ccache = NULL;
80
	krb5_ccache ccache = NULL;
80
	int len;
81
	char *ticket_name = NULL;
81
	char *client, *platform_client;
82
	char *client, *platform_client;
82
	const char *errmsg;
83
	const char *errmsg;
83
84
Lines 163-169 auth_krb5_password(Authctxt *authctxt, const char *password) Link Here
163
		goto out;
164
		goto out;
164
	}
165
	}
165
166
166
	problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache);
167
	problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx,
168
	     &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env);
167
	if (problem)
169
	if (problem)
168
		goto out;
170
		goto out;
169
171
Lines 172-192 auth_krb5_password(Authctxt *authctxt, const char *password) Link Here
172
	if (problem)
174
	if (problem)
173
		goto out;
175
		goto out;
174
176
175
	problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
177
	problem = krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
176
				 &creds);
178
				 &creds);
177
	if (problem)
179
	if (problem)
178
		goto out;
180
		goto out;
179
#endif
181
#endif
180
182
181
	authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
183
	problem = krb5_cc_get_full_name(authctxt->krb5_ctx,
184
	    authctxt->krb5_fwd_ccache, &ticket_name);
182
185
183
	len = strlen(authctxt->krb5_ticket_file) + 6;
186
	authctxt->krb5_ccname = xstrdup(ticket_name);
184
	authctxt->krb5_ccname = xmalloc(len);
187
	krb5_free_string(authctxt->krb5_ctx, ticket_name);
185
	snprintf(authctxt->krb5_ccname, len, "FILE:%s",
186
	    authctxt->krb5_ticket_file);
187
188
188
#ifdef USE_PAM
189
#ifdef USE_PAM
189
	if (options.use_pam)
190
	if (options.use_pam && authctxt->krb5_set_env)
190
		do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
191
		do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
191
#endif
192
#endif
192
193
Lines 222-231 auth_krb5_password(Authctxt *authctxt, const char *password) Link Here
222
void
223
void
223
krb5_cleanup_proc(Authctxt *authctxt)
224
krb5_cleanup_proc(Authctxt *authctxt)
224
{
225
{
226
	struct stat krb5_ccname_stat;
227
	char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end;
228
225
	debug("krb5_cleanup_proc called");
229
	debug("krb5_cleanup_proc called");
226
	if (authctxt->krb5_fwd_ccache) {
230
	if (authctxt->krb5_fwd_ccache) {
227
		krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
231
		krb5_context ctx = authctxt->krb5_ctx;
232
		krb5_cccol_cursor cursor;
233
		krb5_ccache ccache;
234
		int ret;
235
236
		/* Avoid race conditions with other processes touching the same collection */
237
		//krb5_cccol_lock(ctx);
238
239
		krb5_cc_destroy(ctx, authctxt->krb5_fwd_ccache);
228
		authctxt->krb5_fwd_ccache = NULL;
240
		authctxt->krb5_fwd_ccache = NULL;
241
242
		ret = krb5_cccol_cursor_new(ctx, &cursor);
243
		if (ret)
244
			goto unlock;
245
246
		ret = krb5_cccol_cursor_next(ctx, cursor, &ccache);
247
		if (ret == 0 && ccache != NULL) {
248
			/* There is at least one other ccache in collection
249
			 * we can switch to */
250
			krb5_cc_switch(ctx, ccache);
251
		} else {
252
			/* Clean up the collection too */
253
			strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10);
254
			krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1;
255
			*krb5_ccname_dir_start++ = '\0';
256
			if (strcmp(krb5_ccname, "DIR") == 0) {
257
258
				strcat(krb5_ccname_dir_start, "/primary");
259
260
				if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) {
261
					if (unlink(krb5_ccname_dir_start) == 0) {
262
						krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/');
263
						*krb5_ccname_dir_end = '\0';
264
						if (rmdir(krb5_ccname_dir_start) == -1)
265
							debug("cache dir '%s' remove failed: %s",
266
							    krb5_ccname_dir_start, strerror(errno));
267
					}
268
					else
269
						debug("cache primary file '%s', remove failed: %s",
270
						    krb5_ccname_dir_start, strerror(errno));
271
				}
272
			}
273
		}
274
unlock:
275
		krb5_cccol_cursor_free(ctx, &cursor);
276
277
		/* Release lock */
278
		//krb5_cccol_unlock(ctx);
229
	}
279
	}
230
	if (authctxt->krb5_user) {
280
	if (authctxt->krb5_user) {
231
		krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
281
		krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
Lines 237-272 krb5_cleanup_proc(Authctxt *authctxt) Link Here
237
	}
287
	}
238
}
288
}
239
289
240
#ifndef HEIMDAL
241
krb5_error_code
242
ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
243
	int tmpfd, ret, oerrno;
244
	char ccname[40];
245
	mode_t old_umask;
246
290
247
	ret = snprintf(ccname, sizeof(ccname),
291
#if !defined(HEIMDAL)
248
	    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
292
int
249
	if (ret < 0 || (size_t)ret >= sizeof(ccname))
293
ssh_asprintf_append(char **dsc, const char *fmt, ...) {
250
		return ENOMEM;
294
	char *src, *old;
251
295
	va_list ap;
252
	old_umask = umask(0177);
296
	int i;
253
	tmpfd = mkstemp(ccname + strlen("FILE:"));
297
254
	oerrno = errno;
298
	va_start(ap, fmt);
255
	umask(old_umask);
299
	i = vasprintf(&src, fmt, ap);
256
	if (tmpfd == -1) {
300
	va_end(ap);
257
		logit("mkstemp(): %.100s", strerror(oerrno));
301
258
		return oerrno;
302
	if (i == -1 || src == NULL)
303
		return -1;
304
305
	old = *dsc;
306
307
	i = asprintf(dsc, "%s%s", *dsc, src);
308
	if (i == -1 || src == NULL) {
309
		free(src);
310
		return -1;
311
	}
312
313
	free(old);
314
	free(src);
315
316
	return i;
317
}
318
319
int
320
ssh_krb5_expand_template(char **result, const char *template) {
321
	char *p_n, *p_o, *r, *tmp_template;
322
323
	debug3("%s: called, template = %s", __func__, template);
324
	if (template == NULL)
325
		return -1;
326
327
	tmp_template = p_n = p_o = xstrdup(template);
328
	r = xstrdup("");
329
330
	while ((p_n = strstr(p_o, "%{")) != NULL) {
331
332
		*p_n++ = '\0';
333
		if (ssh_asprintf_append(&r, "%s", p_o) == -1)
334
			goto cleanup;
335
336
		if (strncmp(p_n, "{uid}", 5) == 0 || strncmp(p_n, "{euid}", 6) == 0 ||
337
			strncmp(p_n, "{USERID}", 8) == 0) {
338
			p_o = strchr(p_n, '}') + 1;
339
			if (ssh_asprintf_append(&r, "%d", geteuid()) == -1)
340
				goto cleanup;
341
			continue;
342
		}
343
		else if (strncmp(p_n, "{TEMP}", 6) == 0) {
344
			p_o = strchr(p_n, '}') + 1;
345
			if (ssh_asprintf_append(&r, "/tmp") == -1)
346
				goto cleanup;
347
			continue;
348
		} else {
349
			p_o = strchr(p_n, '}') + 1;
350
			p_o = '\0';
351
			debug("%s: unsupported token %s in %s", __func__, p_n, template);
352
			/* unknown token, fallback to the default */
353
			goto cleanup;
354
		}
259
	}
355
	}
260
356
261
	if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
357
	if (ssh_asprintf_append(&r, "%s", p_o) == -1)
358
		goto cleanup;
359
360
	*result = r;
361
	free(tmp_template);
362
	return 0;
363
364
cleanup:
365
	free(r);
366
	free(tmp_template);
367
	return -1;
368
}
369
370
krb5_error_code
371
ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
372
	profile_t p;
373
	int ret = 0;
374
	char *value = NULL;
375
376
	debug3("%s: called", __func__);
377
	ret = krb5_get_profile(ctx, &p);
378
	if (ret)
379
		return ret;
380
381
	ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value);
382
	if (ret || !value)
383
		return ret;
384
385
	ret = ssh_krb5_expand_template(ccname, value);
386
387
	debug3("%s: returning with ccname = %s", __func__, *ccname);
388
	return ret;
389
}
390
391
krb5_error_code
392
ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) {
393
	int tmpfd, ret, oerrno, type_len;
394
	char *ccname = NULL;
395
	mode_t old_umask;
396
	char *type = NULL, *colon = NULL;
397
398
	debug3("%s: called", __func__);
399
	if (need_environment)
400
		*need_environment = 0;
401
	ret = ssh_krb5_get_cctemplate(ctx, &ccname);
402
	if (ret || !ccname || options.kerberos_unique_ticket) {
403
		/* Otherwise, go with the old method */
404
		if (ccname)
405
			free(ccname);
406
		ccname = NULL;
407
408
		ret = asprintf(&ccname,
409
		    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
410
		if (ret < 0)
411
			return ENOMEM;
412
413
		old_umask = umask(0177);
414
		tmpfd = mkstemp(ccname + strlen("FILE:"));
262
		oerrno = errno;
415
		oerrno = errno;
263
		logit("fchmod(): %.100s", strerror(oerrno));
416
		umask(old_umask);
417
		if (tmpfd == -1) {
418
			logit("mkstemp(): %.100s", strerror(oerrno));
419
			return oerrno;
420
		}
421
422
		if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
423
			oerrno = errno;
424
			logit("fchmod(): %.100s", strerror(oerrno));
425
			close(tmpfd);
426
			return oerrno;
427
		}
428
		/* make sure the KRB5CCNAME is set for non-standard location */
429
		if (need_environment)
430
			*need_environment = 1;
264
		close(tmpfd);
431
		close(tmpfd);
265
		return oerrno;
266
	}
432
	}
267
	close(tmpfd);
268
433
269
	return (krb5_cc_resolve(ctx, ccname, ccache));
434
	debug3("%s: setting default ccname to %s", __func__, ccname);
435
	/* set the default with already expanded user IDs */
436
	ret = krb5_cc_set_default_name(ctx, ccname);
437
	if (ret)
438
		return ret;
439
440
	if ((colon = strstr(ccname, ":")) != NULL) {
441
		type_len = colon - ccname;
442
		type = malloc((type_len + 1) * sizeof(char));
443
		if (type == NULL)
444
			return ENOMEM;
445
		strncpy(type, ccname, type_len);
446
		type[type_len] = 0;
447
	} else {
448
		type = strdup(ccname);
449
	}
450
451
	/* If we have a credential cache from krb5.conf, we need to switch
452
	 * a primary cache for this collection, if it supports that (non-FILE)
453
	 */
454
	if (krb5_cc_support_switch(ctx, type)) {
455
		debug3("%s: calling cc_new_unique(%s)", __func__, ccname);
456
		ret = krb5_cc_new_unique(ctx, type, NULL, ccache);
457
		if (ret)
458
			return ret;
459
460
		debug3("%s: calling cc_switch()", __func__);
461
		return krb5_cc_switch(ctx, *ccache);
462
	} else {
463
		/* Otherwise, we can not create a unique ccname here (either
464
		 * it is already unique from above or the type does not support
465
		 * collections
466
		 */
467
		debug3("%s: calling cc_resolve(%s)", __func__, ccname);
468
		return (krb5_cc_resolve(ctx, ccname, ccache));
469
	}
270
}
470
}
271
#endif /* !HEIMDAL */
471
#endif /* !HEIMDAL */
272
#endif /* KRB5 */
472
#endif /* KRB5 */
(-)a/auth.h (-1 / +2 lines)
Lines 82-87 struct Authctxt { Link Here
82
	krb5_principal	 krb5_user;
82
	krb5_principal	 krb5_user;
83
	char		*krb5_ticket_file;
83
	char		*krb5_ticket_file;
84
	char		*krb5_ccname;
84
	char		*krb5_ccname;
85
	int		 krb5_set_env;
85
#endif
86
#endif
86
	struct sshbuf	*loginmsg;
87
	struct sshbuf	*loginmsg;
87
88
Lines 243-248 int sys_auth_passwd(struct ssh *, const char *); Link Here
243
244
244
#if defined(KRB5) && !defined(HEIMDAL)
245
#if defined(KRB5) && !defined(HEIMDAL)
245
#include <krb5.h>
246
#include <krb5.h>
246
krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
247
krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
247
#endif
248
#endif
248
#endif
249
#endif
(-)a/gss-serv-krb5.c (-11 / +14 lines)
Lines 114-120 ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) Link Here
114
/* This writes out any forwarded credentials from the structure populated
114
/* This writes out any forwarded credentials from the structure populated
115
 * during userauth. Called after we have setuid to the user */
115
 * during userauth. Called after we have setuid to the user */
116
116
117
static void
117
static int
118
ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
118
ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
119
{
119
{
120
	krb5_ccache ccache;
120
	krb5_ccache ccache;
Lines 123-136 ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) Link Here
123
	OM_uint32 maj_status, min_status;
123
	OM_uint32 maj_status, min_status;
124
	int len;
124
	int len;
125
	const char *errmsg;
125
	const char *errmsg;
126
	int set_env = 0;
126
127
127
	if (client->creds == NULL) {
128
	if (client->creds == NULL) {
128
		debug("No credentials stored");
129
		debug("No credentials stored");
129
		return;
130
		return 0;
130
	}
131
	}
131
132
132
	if (ssh_gssapi_krb5_init() == 0)
133
	if (ssh_gssapi_krb5_init() == 0)
133
		return;
134
		return 0;
134
135
135
#ifdef HEIMDAL
136
#ifdef HEIMDAL
136
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
137
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
Lines 147-157 ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) Link Here
147
		return;
148
		return;
148
	}
149
	}
149
#else
150
#else
150
	if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) {
151
	if ((problem = ssh_krb5_cc_new_unique(krb_context, &ccache, &set_env)) != 0) {
151
		errmsg = krb5_get_error_message(krb_context, problem);
152
		errmsg = krb5_get_error_message(krb_context, problem);
152
		logit("ssh_krb5_cc_gen(): %.100s", errmsg);
153
		logit("ssh_krb5_cc_new_unique(): %.100s", errmsg);
153
		krb5_free_error_message(krb_context, errmsg);
154
		krb5_free_error_message(krb_context, errmsg);
154
		return;
155
		return 0;
155
	}
156
	}
156
#endif	/* #ifdef HEIMDAL */
157
#endif	/* #ifdef HEIMDAL */
157
158
Lines 160-166 ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) Link Here
160
		errmsg = krb5_get_error_message(krb_context, problem);
161
		errmsg = krb5_get_error_message(krb_context, problem);
161
		logit("krb5_parse_name(): %.100s", errmsg);
162
		logit("krb5_parse_name(): %.100s", errmsg);
162
		krb5_free_error_message(krb_context, errmsg);
163
		krb5_free_error_message(krb_context, errmsg);
163
		return;
164
		return 0;
164
	}
165
	}
165
166
166
	if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) {
167
	if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) {
Lines 169-175 ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) Link Here
169
		krb5_free_error_message(krb_context, errmsg);
170
		krb5_free_error_message(krb_context, errmsg);
170
		krb5_free_principal(krb_context, princ);
171
		krb5_free_principal(krb_context, princ);
171
		krb5_cc_destroy(krb_context, ccache);
172
		krb5_cc_destroy(krb_context, ccache);
172
		return;
173
		return 0;
173
	}
174
	}
174
175
175
	krb5_free_principal(krb_context, princ);
176
	krb5_free_principal(krb_context, princ);
Lines 178-184 ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) Link Here
178
	    client->creds, ccache))) {
179
	    client->creds, ccache))) {
179
		logit("gss_krb5_copy_ccache() failed");
180
		logit("gss_krb5_copy_ccache() failed");
180
		krb5_cc_destroy(krb_context, ccache);
181
		krb5_cc_destroy(krb_context, ccache);
181
		return;
182
		return 0;
182
	}
183
	}
183
184
184
	client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
185
	client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
Lines 188-200 ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) Link Here
188
	snprintf(client->store.envval, len, "FILE:%s", client->store.filename);
189
	snprintf(client->store.envval, len, "FILE:%s", client->store.filename);
189
190
190
#ifdef USE_PAM
191
#ifdef USE_PAM
191
	if (options.use_pam)
192
	if (options.use_pam && set_env)
192
		do_pam_putenv(client->store.envvar, client->store.envval);
193
		do_pam_putenv(client->store.envvar, client->store.envval);
193
#endif
194
#endif
194
195
195
	krb5_cc_close(krb_context, ccache);
196
	krb5_cc_close(krb_context, ccache);
196
197
197
	return;
198
	client->store.data = krb_context;
199
200
	return set_env;
198
}
201
}
199
202
200
ssh_gssapi_mech gssapi_kerberos_mech = {
203
ssh_gssapi_mech gssapi_kerberos_mech = {
(-)a/gss-serv.c (-7 / +18 lines)
Lines 320-341 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) Link Here
320
void
320
void
321
ssh_gssapi_cleanup_creds(void)
321
ssh_gssapi_cleanup_creds(void)
322
{
322
{
323
	if (gssapi_client.store.filename != NULL) {
323
	krb5_ccache ccache = NULL;
324
		/* Unlink probably isn't sufficient */
324
	krb5_error_code problem;
325
		debug("removing gssapi cred file\"%s\"",
325
326
		    gssapi_client.store.filename);
326
	if (gssapi_client.store.data != NULL) {
327
		unlink(gssapi_client.store.filename);
327
		if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) {
328
			debug("%s: krb5_cc_resolve(): %.100s", __func__,
329
				krb5_get_err_text(gssapi_client.store.data, problem));
330
		} else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) {
331
			debug("%s: krb5_cc_destroy(): %.100s", __func__,
332
				krb5_get_err_text(gssapi_client.store.data, problem));
333
		} else {
334
			krb5_free_context(gssapi_client.store.data);
335
			gssapi_client.store.data = NULL;
336
		}
328
	}
337
	}
329
}
338
}
330
339
331
/* As user */
340
/* As user */
332
void
341
int
333
ssh_gssapi_storecreds(void)
342
ssh_gssapi_storecreds(void)
334
{
343
{
335
	if (gssapi_client.mech && gssapi_client.mech->storecreds) {
344
	if (gssapi_client.mech && gssapi_client.mech->storecreds) {
336
		(*gssapi_client.mech->storecreds)(&gssapi_client);
345
		return (*gssapi_client.mech->storecreds)(&gssapi_client);
337
	} else
346
	} else
338
		debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
347
		debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
348
349
	return 0;
339
}
350
}
340
351
341
/* This allows GSSAPI methods to do things to the childs environment based
352
/* This allows GSSAPI methods to do things to the childs environment based
(-)a/servconf.c (-1 / +12 lines)
Lines 122-127 initialize_server_options(ServerOptions *options) Link Here
122
	options->kerberos_or_local_passwd = -1;
122
	options->kerberos_or_local_passwd = -1;
123
	options->kerberos_ticket_cleanup = -1;
123
	options->kerberos_ticket_cleanup = -1;
124
	options->kerberos_get_afs_token = -1;
124
	options->kerberos_get_afs_token = -1;
125
	options->kerberos_unique_ticket = -1;
125
	options->gss_authentication=-1;
126
	options->gss_authentication=-1;
126
	options->gss_cleanup_creds = -1;
127
	options->gss_cleanup_creds = -1;
127
	options->gss_strict_acceptor = -1;
128
	options->gss_strict_acceptor = -1;
Lines 315-320 fill_default_server_options(ServerOptions *options) Link Here
315
		options->kerberos_ticket_cleanup = 1;
316
		options->kerberos_ticket_cleanup = 1;
316
	if (options->kerberos_get_afs_token == -1)
317
	if (options->kerberos_get_afs_token == -1)
317
		options->kerberos_get_afs_token = 0;
318
		options->kerberos_get_afs_token = 0;
319
	if (options->kerberos_unique_ticket == -1)
320
		options->kerberos_unique_ticket = 0;
318
	if (options->gss_authentication == -1)
321
	if (options->gss_authentication == -1)
319
		options->gss_authentication = 0;
322
		options->gss_authentication = 0;
320
	if (options->gss_cleanup_creds == -1)
323
	if (options->gss_cleanup_creds == -1)
Lines 447-453 typedef enum { Link Here
447
	sPermitRootLogin, sLogFacility, sLogLevel,
450
	sPermitRootLogin, sLogFacility, sLogLevel,
448
	sRhostsRSAAuthentication, sRSAAuthentication,
451
	sRhostsRSAAuthentication, sRSAAuthentication,
449
	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
452
	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
450
	sKerberosGetAFSToken, sChallengeResponseAuthentication,
453
	sKerberosGetAFSToken, sKerberosUniqueTicket,
454
	sChallengeResponseAuthentication,
451
	sPasswordAuthentication, sKbdInteractiveAuthentication,
455
	sPasswordAuthentication, sKbdInteractiveAuthentication,
452
	sListenAddress, sAddressFamily,
456
	sListenAddress, sAddressFamily,
453
	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
457
	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
Lines 526-536 static struct { Link Here
526
#else
530
#else
527
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
531
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
528
#endif
532
#endif
533
	{ "kerberosuniqueticket", sKerberosUniqueTicket, SSHCFG_GLOBAL },
529
#else
534
#else
530
	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
535
	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
531
	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
536
	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
532
	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
537
	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
533
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
538
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
539
	{ "kerberosuniqueticket", sUnsupported, SSHCFG_GLOBAL },
534
#endif
540
#endif
535
	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
541
	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
536
	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
542
	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
Lines 1437-1442 process_server_config_line(ServerOptions *options, char *line, Link Here
1437
		intptr = &options->kerberos_get_afs_token;
1443
		intptr = &options->kerberos_get_afs_token;
1438
		goto parse_flag;
1444
		goto parse_flag;
1439
1445
1446
	case sKerberosUniqueTicket:
1447
		intptr = &options->kerberos_unique_ticket;
1448
		goto parse_flag;
1449
1440
	case sGssAuthentication:
1450
	case sGssAuthentication:
1441
		intptr = &options->gss_authentication;
1451
		intptr = &options->gss_authentication;
1442
		goto parse_flag;
1452
		goto parse_flag;
Lines 2507-2512 dump_config(ServerOptions *o) Link Here
2507
# ifdef USE_AFS
2517
# ifdef USE_AFS
2508
	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2518
	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2509
# endif
2519
# endif
2520
	dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket);
2510
#endif
2521
#endif
2511
#ifdef GSSAPI
2522
#ifdef GSSAPI
2512
	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2523
	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
(-)a/servconf.h (+2 lines)
Lines 123-128 typedef struct { Link Here
123
						 * file on logout. */
123
						 * file on logout. */
124
	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
124
	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
125
						 * authenticated with Kerberos. */
125
						 * authenticated with Kerberos. */
126
	int     kerberos_unique_ticket;		/* If true, the aquired ticket will
127
						 * be stored in per-session ccache */
126
	int     gss_authentication;	/* If true, permit GSSAPI authentication */
128
	int     gss_authentication;	/* If true, permit GSSAPI authentication */
127
	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
129
	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
128
	int     gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
130
	int     gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
(-)a/session.c (-2 / +3 lines)
Lines 1033-1039 do_setup_env(struct ssh *ssh, Session *s, const char *shell) Link Here
1033
	/* Allow any GSSAPI methods that we've used to alter
1033
	/* Allow any GSSAPI methods that we've used to alter
1034
	 * the childs environment as they see fit
1034
	 * the childs environment as they see fit
1035
	 */
1035
	 */
1036
	ssh_gssapi_do_child(&env, &envsize);
1036
	if (s->authctxt->krb5_set_env)
1037
		ssh_gssapi_do_child(&env, &envsize);
1037
#endif
1038
#endif
1038
1039
1039
	/* Set basic environment. */
1040
	/* Set basic environment. */
Lines 1105-1111 do_setup_env(struct ssh *ssh, Session *s, const char *shell) Link Here
1105
	}
1106
	}
1106
#endif
1107
#endif
1107
#ifdef KRB5
1108
#ifdef KRB5
1108
	if (s->authctxt->krb5_ccname)
1109
	if (s->authctxt->krb5_ccname && s->authctxt->krb5_set_env)
1109
		child_set_env(&env, &envsize, "KRB5CCNAME",
1110
		child_set_env(&env, &envsize, "KRB5CCNAME",
1110
		    s->authctxt->krb5_ccname);
1111
		    s->authctxt->krb5_ccname);
1111
#endif
1112
#endif
(-)a/ssh-gss.h (-2 / +2 lines)
Lines 83-89 typedef struct ssh_gssapi_mech_struct { Link Here
83
	int (*dochild) (ssh_gssapi_client *);
83
	int (*dochild) (ssh_gssapi_client *);
84
	int (*userok) (ssh_gssapi_client *, char *);
84
	int (*userok) (ssh_gssapi_client *, char *);
85
	int (*localname) (ssh_gssapi_client *, char **);
85
	int (*localname) (ssh_gssapi_client *, char **);
86
	void (*storecreds) (ssh_gssapi_client *);
86
	int (*storecreds) (ssh_gssapi_client *);
87
} ssh_gssapi_mech;
87
} ssh_gssapi_mech;
88
88
89
typedef struct {
89
typedef struct {
Lines 127-133 int ssh_gssapi_userok(char *name); Link Here
127
OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
127
OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
128
void ssh_gssapi_do_child(char ***, u_int *);
128
void ssh_gssapi_do_child(char ***, u_int *);
129
void ssh_gssapi_cleanup_creds(void);
129
void ssh_gssapi_cleanup_creds(void);
130
void ssh_gssapi_storecreds(void);
130
int ssh_gssapi_storecreds(void);
131
const char *ssh_gssapi_displayname(void);
131
const char *ssh_gssapi_displayname(void);
132
132
133
#endif /* GSSAPI */
133
#endif /* GSSAPI */
(-)a/sshd.c (-1 / +1 lines)
Lines 2162-2168 main(int ac, char **av) Link Here
2162
#ifdef GSSAPI
2162
#ifdef GSSAPI
2163
	if (options.gss_authentication) {
2163
	if (options.gss_authentication) {
2164
		temporarily_use_uid(authctxt->pw);
2164
		temporarily_use_uid(authctxt->pw);
2165
		ssh_gssapi_storecreds();
2165
		authctxt->krb5_set_env = ssh_gssapi_storecreds();
2166
		restore_uid();
2166
		restore_uid();
2167
	}
2167
	}
2168
#endif
2168
#endif
(-)a/sshd_config.5 (+6 lines)
Lines 860-865 Specifies whether to automatically destroy the user's ticket cache Link Here
860
file on logout.
860
file on logout.
861
The default is
861
The default is
862
.Cm yes .
862
.Cm yes .
863
.It Cm KerberosUniqueTicket
864
Specifies whether to store the aquired tickets in the per-session credential
865
cache or whether to use per-user credential cache, which might overwrite
866
tickets aquired in different sessions of the same user.
867
The default is
868
.Cm no .
863
.It Cm KexAlgorithms
869
.It Cm KexAlgorithms
864
Specifies the available KEX (Key Exchange) algorithms.
870
Specifies the available KEX (Key Exchange) algorithms.
865
Multiple algorithms must be comma-separated.
871
Multiple algorithms must be comma-separated.

Return to bug 2775