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

Collapse All | Expand All

(-)orig/auth-pam.c (+119 lines)
Lines 617-622 Link Here
617
	sshpam_handle = NULL;
617
	sshpam_handle = NULL;
618
}
618
}
619
619
620
#ifdef PAM_ENHANCEMENT
621
char *
622
derive_pam_service_name(Authctxt *authctxt)
623
{
624
	char *svcname = xmalloc(BUFSIZ);
625
626
	/*
627
	 * If PamServiceName is set we use that for everything, including
628
	 * SSHv1
629
	 */
630
	if (options.pam_service_name != NULL) {
631
		(void) strlcpy(svcname, options.pam_service_name, BUFSIZ);
632
		return (svcname);
633
	}
634
635
	if (compat20) {
636
		char *method_name = authctxt->authmethod_name;
637
638
		if (!method_name)
639
			fatal("Userauth method unknown while starting PAM");
640
641
		/*
642
		 * For SSHv2 we use "sshd-<userauth name>
643
		 * The "sshd" prefix can be changed via the PAMServicePrefix
644
		 * sshd_config option.
645
		 */
646
		if (strcmp(method_name, "none") == 0) {
647
			snprintf(svcname, BUFSIZ, "%s-none",
648
			    options.pam_service_prefix);
649
		}
650
		if (strcmp(method_name, "password") == 0) {
651
			snprintf(svcname, BUFSIZ, "%s-password",
652
			    options.pam_service_prefix);
653
		}
654
		if (strcmp(method_name, "keyboard-interactive") == 0) {
655
			/* "keyboard-interactive" is too long, shorten it */
656
			snprintf(svcname, BUFSIZ, "%s-kbdint",
657
			    options.pam_service_prefix);
658
		}
659
		if (strcmp(method_name, "publickey") == 0) {
660
			/* "publickey" is too long, shorten it */
661
			snprintf(svcname, BUFSIZ, "%s-pubkey",
662
			    options.pam_service_prefix);
663
		}
664
		if (strcmp(method_name, "hostbased") == 0) {
665
			snprintf(svcname, BUFSIZ, "%s-hostbased",
666
			    options.pam_service_prefix);
667
		}
668
		if (strncmp(method_name, "gssapi-", 7) == 0) {
669
		        /*
670
			 * Although OpenSSH only supports "gssapi-with-mic"
671
			 * for now. We will still map any userauth method
672
                         * prefixed with "gssapi-" to the gssapi PAM service.
673
			 */ 
674
			snprintf(svcname, BUFSIZ, "%s-gssapi",
675
			    options.pam_service_prefix);
676
		}
677
		return svcname;
678
	} else {
679
		/* SSHv1 doesn't get to be so cool */
680
	        snprintf(svcname, BUFSIZ, "sshd-v1");
681
	}
682
	return svcname;
683
}
684
#endif /* PAM_ENHANCEMENT */
685
620
static int
686
static int
621
sshpam_init(Authctxt *authctxt)
687
sshpam_init(Authctxt *authctxt)
622
{
688
{
Lines 624-641 Link Here
624
	const char *pam_rhost, *pam_user, *user = authctxt->user;
690
	const char *pam_rhost, *pam_user, *user = authctxt->user;
625
	const char **ptr_pam_user = &pam_user;
691
	const char **ptr_pam_user = &pam_user;
626
692
693
#ifdef PAM_ENHANCEMENT
694
	const char *pam_service;
695
        const char **ptr_pam_service = &pam_service;
696
	char *svc = NULL;
697
698
	svc = derive_pam_service_name(authctxt);
699
        debug3("PAM service is %s", svc);
700
#endif
701
627
	if (sshpam_handle != NULL) {
702
	if (sshpam_handle != NULL) {
703
#ifdef PAM_ENHANCEMENT
704
	        /* get the pam service name */
705
		sshpam_err = pam_get_item(sshpam_handle,
706
		    PAM_SERVICE, (sshpam_const void **)ptr_pam_service);
707
                if (sshpam_err != PAM_SUCCESS) 
708
		    fatal("Failed to get the PAM service name");
709
		debug3("Previous pam_service is %s", pam_service ?
710
                    pam_service : "NULL");
711
712
		/* get the pam user name */
713
		sshpam_err = pam_get_item(sshpam_handle,
714
		    PAM_USER, (sshpam_const void **)ptr_pam_user);
715
716
		/*
717
		 * only need to re-start if either user or service is 
718
                 * different.
719
                 */
720
		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0
721
		    && strncmp(svc, pam_service, strlen(svc)) == 0) {
722
		        free(svc);
723
			return (0);
724
                }
725
726
		/*
727
		 * Clean up previous PAM state.  No need to clean up session 
728
		 * and creds.
729
		 */
730
                sshpam_authenticated = 0;
731
                sshpam_account_status = -1;
732
733
		sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, NULL);
734
         	if (sshpam_err != PAM_SUCCESS)
735
		        debug3("Cannot remove PAM conv"); /* a warning only */
736
#else /* Original */
628
		/* We already have a PAM context; check if the user matches */
737
		/* We already have a PAM context; check if the user matches */
629
		sshpam_err = pam_get_item(sshpam_handle,
738
		sshpam_err = pam_get_item(sshpam_handle,
630
		    PAM_USER, (sshpam_const void **)ptr_pam_user);
739
		    PAM_USER, (sshpam_const void **)ptr_pam_user);
631
		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
740
		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
632
			return (0);
741
			return (0);
742
#endif /* PAM_ENHANCEMENT */
633
		pam_end(sshpam_handle, sshpam_err);
743
		pam_end(sshpam_handle, sshpam_err);
634
		sshpam_handle = NULL;
744
		sshpam_handle = NULL;
635
	}
745
	}
636
	debug("PAM: initializing for \"%s\"", user);
746
	debug("PAM: initializing for \"%s\"", user);
747
748
#ifdef PAM_ENHANCEMENT
749
        debug3("Starting PAM service %s for user %s method %s", svc, user,
750
            authctxt->authmethod_name);
637
	sshpam_err =
751
	sshpam_err =
752
	    pam_start(svc, user, &store_conv, &sshpam_handle);
753
	free(svc);
754
#else /* Original */
755
	sshpam_err =
638
	    pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
756
	    pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
757
#endif
639
	sshpam_authctxt = authctxt;
758
	sshpam_authctxt = authctxt;
640
759
641
	if (sshpam_err != PAM_SUCCESS) {
760
	if (sshpam_err != PAM_SUCCESS) {
(-)orig/auth.h (+3 lines)
Lines 76-81 Link Here
76
#endif
76
#endif
77
	Buffer		*loginmsg;
77
	Buffer		*loginmsg;
78
	void		*methoddata;
78
	void		*methoddata;
79
#ifdef PAM_ENHANCEMENT
80
        char            *authmethod_name;
81
#endif 
79
};
82
};
80
/*
83
/*
81
 * Every authentication method has to handle authentication requests for
84
 * Every authentication method has to handle authentication requests for
(-)orig/auth2.c (-2 / +59 lines)
Lines 249-258 Link Here
249
			PRIVSEP(audit_event(SSH_INVALID_USER));
249
			PRIVSEP(audit_event(SSH_INVALID_USER));
250
#endif
250
#endif
251
		}
251
		}
252
253
252
#ifdef USE_PAM
254
#ifdef USE_PAM
255
#ifdef PAM_ENHANCEMENT
256
		/*
257
		 * Start PAM here and once only, if each userauth does not
258
		 * has its own PAM service.
259
		 */
260
	        if (options.use_pam && !options.pam_service_per_authmethod)
261
			PRIVSEP(start_pam(authctxt));
262
#else
253
		if (options.use_pam)
263
		if (options.use_pam)
254
			PRIVSEP(start_pam(authctxt));
264
			PRIVSEP(start_pam(authctxt));
255
#endif
265
#endif
266
#endif
256
		setproctitle("%s%s", authctxt->valid ? user : "unknown",
267
		setproctitle("%s%s", authctxt->valid ? user : "unknown",
257
		    use_privsep ? " [net]" : "");
268
		    use_privsep ? " [net]" : "");
258
		authctxt->service = xstrdup(service);
269
		authctxt->service = xstrdup(service);
Lines 286-291 Link Here
286
	/* try to authenticate user */
297
	/* try to authenticate user */
287
	m = authmethod_lookup(authctxt, method);
298
	m = authmethod_lookup(authctxt, method);
288
	if (m != NULL && authctxt->failures < options.max_authtries) {
299
	if (m != NULL && authctxt->failures < options.max_authtries) {
300
301
#if defined(USE_PAM) && defined(PAM_ENHANCEMENT)
302
		/* start PAM service for each userauth */
303
                if (options.use_pam && options.pam_service_per_authmethod) {
304
       		        if (authctxt->authmethod_name != NULL)
305
		                free(authctxt->authmethod_name);
306
                        authctxt->authmethod_name = xstrdup(method);
307
                        if (use_privsep)
308
                                mm_inform_authmethod(method);
309
		        PRIVSEP(start_pam(authctxt));
310
		}
311
#endif
289
		debug2("input_userauth_request: try method %s", method);
312
		debug2("input_userauth_request: try method %s", method);
290
		authenticated =	m->userauth(authctxt);
313
		authenticated =	m->userauth(authctxt);
291
	}
314
	}
Lines 303-308 Link Here
303
	char *methods;
326
	char *methods;
304
	int partial = 0;
327
	int partial = 0;
305
328
329
#ifdef  PAM_ENHANCEMENT
330
        debug3("%s: entering", __func__);
331
#endif
332
306
	if (!authctxt->valid && authenticated)
333
	if (!authctxt->valid && authenticated)
307
		fatal("INTERNAL ERROR: authenticated invalid user %s",
334
		fatal("INTERNAL ERROR: authenticated invalid user %s",
308
		    authctxt->user);
335
		    authctxt->user);
Lines 319-324 Link Here
319
	}
346
	}
320
347
321
	if (authenticated && options.num_auth_methods != 0) {
348
	if (authenticated && options.num_auth_methods != 0) {
349
350
#if defined(USE_PAM) && defined(PAM_ENHANCEMENT)
351
                /*
352
                 * If each userauth has its own PAM service, then PAM need to 
353
                 * perform account check for this service.
354
                 */
355
                if (options.use_pam && options.pam_service_per_authmethod &&
356
                    !PRIVSEP(do_pam_account())) {
357
                        /* if PAM returned a message, send it to the user */
358
                        if (buffer_len(&loginmsg) > 0) {
359
                                buffer_append(&loginmsg, "\0", 1);
360
                                userauth_send_banner(buffer_ptr(&loginmsg));
361
                                packet_write_wait();
362
                        }
363
364
                        fatal("Access denied for user %s by PAM account "
365
                            "configuration", authctxt->user);
366
                }
367
#endif
322
		if (!auth2_update_methods_lists(authctxt, method, submethod)) {
368
		if (!auth2_update_methods_lists(authctxt, method, submethod)) {
323
			authenticated = 0;
369
			authenticated = 0;
324
			partial = 1;
370
			partial = 1;
Lines 332-338 Link Here
332
		return;
378
		return;
333
379
334
#ifdef USE_PAM
380
#ifdef USE_PAM
381
382
#ifdef PAM_ENHANCEMENT
383
        /*
384
         * PAM needs to perform account checks after auth. However, if each
385
         * userauth has its own PAM service and options.num_auth_methods != 0,
386
         * then no need to perform account checking, because it was done 
387
         * already.
388
         */
389
        if (options.use_pam && authenticated && 
390
            !(options.num_auth_methods != 0 &&
391
            options.pam_service_per_authmethod)){
392
#else
335
	if (options.use_pam && authenticated) {
393
	if (options.use_pam && authenticated) {
394
#endif
336
		if (!PRIVSEP(do_pam_account())) {
395
		if (!PRIVSEP(do_pam_account())) {
337
			/* if PAM returned a message, send it to the user */
396
			/* if PAM returned a message, send it to the user */
338
			if (buffer_len(&loginmsg) > 0) {
397
			if (buffer_len(&loginmsg) > 0) {
Lines 623-627 Link Here
623
		fatal("%s: method not in AuthenticationMethods", __func__);
682
		fatal("%s: method not in AuthenticationMethods", __func__);
624
	return 0;
683
	return 0;
625
}
684
}
626
627
(-)orig/monitor_wrap.c (+18 lines)
Lines 338-343 Link Here
338
	buffer_free(&m);
338
	buffer_free(&m);
339
}
339
}
340
340
341
#ifdef PAM_ENHANCEMENT
342
/* Inform the privileged process about the authentication method */
343
void
344
mm_inform_authmethod(char *authmethod)
345
{
346
	Buffer m;
347
348
	debug3("%s entering", __func__);
349
350
	buffer_init(&m);
351
	buffer_put_cstring(&m, authmethod);
352
353
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHMETHOD, &m);
354
355
	buffer_free(&m);
356
}
357
#endif
358
341
/* Do the password authentication */
359
/* Do the password authentication */
342
int
360
int
343
mm_auth_password(Authctxt *authctxt, char *password)
361
mm_auth_password(Authctxt *authctxt, char *password)
(-)orig/monitor.c (+63 lines)
Lines 146-151 Link Here
146
int mm_answer_pwnamallow(int, Buffer *);
146
int mm_answer_pwnamallow(int, Buffer *);
147
int mm_answer_auth2_read_banner(int, Buffer *);
147
int mm_answer_auth2_read_banner(int, Buffer *);
148
int mm_answer_authserv(int, Buffer *);
148
int mm_answer_authserv(int, Buffer *);
149
#ifdef PAM_ENHANCEMENT
150
int mm_answer_authmethod(int, Buffer *);
151
#endif
149
int mm_answer_authpassword(int, Buffer *);
152
int mm_answer_authpassword(int, Buffer *);
150
int mm_answer_bsdauthquery(int, Buffer *);
153
int mm_answer_bsdauthquery(int, Buffer *);
151
int mm_answer_bsdauthrespond(int, Buffer *);
154
int mm_answer_bsdauthrespond(int, Buffer *);
Lines 225-234 Link Here
225
    {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
228
    {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
226
    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
229
    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
227
    {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
230
    {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
231
#ifdef PAM_ENHANCEMENT
232
    {MONITOR_REQ_AUTHMETHOD, MON_ISAUTH, mm_answer_authmethod},
233
#endif
228
    {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
234
    {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
229
    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
235
    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
230
#ifdef USE_PAM
236
#ifdef USE_PAM
237
#ifdef PAM_ENHANCEMENT
238
    {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start},
239
#else
231
    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
240
    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
241
#endif
232
    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
242
    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
233
    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
243
    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
234
    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
244
    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
Lines 391-396 Link Here
391
			if (!compat20)
401
			if (!compat20)
392
				fatal("AuthenticationMethods is not supported"
402
				fatal("AuthenticationMethods is not supported"
393
				    "with SSH protocol 1");
403
				    "with SSH protocol 1");
404
405
#if defined(USE_PAM) && defined(PAM_ENHANCEMENT)
406
                        /* 
407
                         * If each userauth has its own PAM service, then PAM
408
                         * need to perform account check for this service.
409
                         */
410
                        if (options.use_pam && authenticated &&
411
                            options.pam_service_per_authmethod) {
412
                                Buffer m;
413
414
                                buffer_init(&m);
415
                                mm_request_receive_expect(pmonitor->m_sendfd,
416
                                    MONITOR_REQ_PAM_ACCOUNT, &m);
417
                                authenticated = 
418
                                    mm_answer_pam_account(pmonitor->m_sendfd, &m);
419
                                buffer_free(&m);
420
                         }
421
#endif
394
			if (authenticated &&
422
			if (authenticated &&
395
			    !auth2_update_methods_lists(authctxt,
423
			    !auth2_update_methods_lists(authctxt,
396
			    auth_method, auth_submethod)) {
424
			    auth_method, auth_submethod)) {
Lines 409-416 Link Here
409
			    !auth_root_allowed(auth_method))
437
			    !auth_root_allowed(auth_method))
410
				authenticated = 0;
438
				authenticated = 0;
411
#ifdef USE_PAM
439
#ifdef USE_PAM
440
#ifdef PAM_ENHANCEMENT
441
                        /*
442
                         * PAM needs to perform account checks after auth.
443
                         * However, if each userauth has its own PAM service
444
                         * and options.num_auth_methods != 0, then no need to
445
                         * perform account checking, because it was done 
446
                         * already.
447
                         */
448
                        if (options.use_pam && authenticated &&
449
                            !(options.num_auth_methods != 0 &&
450
                            options.pam_service_per_authmethod)) {
451
#else
412
			/* PAM needs to perform account checks after auth */
452
			/* PAM needs to perform account checks after auth */
413
			if (options.use_pam && authenticated) {
453
			if (options.use_pam && authenticated) {
454
#endif
414
				Buffer m;
455
				Buffer m;
415
456
416
				buffer_init(&m);
457
				buffer_init(&m);
Lines 828-833 Link Here
828
		/* Allow service/style information on the auth context */
869
		/* Allow service/style information on the auth context */
829
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
870
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
830
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
871
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
872
#ifdef PAM_ENHANCEMENT
873
                /* Allow authmethod information on the auth context */
874
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHMETHOD, 1);
875
#endif
831
	}
876
	}
832
#ifdef USE_PAM
877
#ifdef USE_PAM
833
	if (options.use_pam)
878
	if (options.use_pam)
Lines 868-874 Link Here
868
	return (0);
913
	return (0);
869
}
914
}
870
915
916
#ifdef PAM_ENHANCEMENT
871
int
917
int
918
mm_answer_authmethod(int sock, Buffer *m)
919
{
920
	monitor_permit_authentications(1);
921
922
	authctxt->authmethod_name = buffer_get_string(m, NULL);
923
	debug3("%s: authmethod_name=%s", __func__, authctxt->authmethod_name);
924
925
	if (strlen(authctxt->authmethod_name) == 0) {
926
		free(authctxt->authmethod_name);
927
		authctxt->authmethod_name = NULL;
928
	}
929
930
	return (0);
931
}
932
#endif
933
934
int
872
mm_answer_authpassword(int sock, Buffer *m)
935
mm_answer_authpassword(int sock, Buffer *m)
873
{
936
{
874
	static int call_count;
937
	static int call_count;
(-)orig/monitor.h (+3 lines)
Lines 70-75 Link Here
70
	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
70
	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
71
	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
71
	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
72
72
73
#ifdef PAM_ENHANCEMENT
74
        MONITOR_REQ_AUTHMETHOD = 114,
75
#endif        
73
};
76
};
74
77
75
struct mm_master;
78
struct mm_master;
(-)orig/servconf.c (+56 lines)
Lines 154-159 Link Here
154
	options->ip_qos_interactive = -1;
154
	options->ip_qos_interactive = -1;
155
	options->ip_qos_bulk = -1;
155
	options->ip_qos_bulk = -1;
156
	options->version_addendum = NULL;
156
	options->version_addendum = NULL;
157
#ifdef PAM_ENHANCEMENT
158
	options->pam_service_name = NULL;
159
	options->pam_service_prefix = NULL;
160
161
	/* 
162
	 * Each user method will have its own PAM service by default.
163
	 * However, if PAMServiceName is specified or the protocal version
164
	 * is not compat20, then there will be only one PAM service for the
165
	 * entire user authentication.
166
	 */
167
        options->pam_service_per_authmethod = 1;
168
#endif
157
}
169
}
158
170
159
void
171
void
Lines 303-308 Link Here
303
		options->ip_qos_bulk = IPTOS_THROUGHPUT;
315
		options->ip_qos_bulk = IPTOS_THROUGHPUT;
304
	if (options->version_addendum == NULL)
316
	if (options->version_addendum == NULL)
305
		options->version_addendum = xstrdup("");
317
		options->version_addendum = xstrdup("");
318
319
#ifdef PAM_ENHANCEMENT
320
        if (options->pam_service_prefix == NULL)
321
                options->pam_service_prefix = _SSH_PAM_SERVICE_PREFIX;
322
#endif
323
306
	/* Turn privilege separation on by default */
324
	/* Turn privilege separation on by default */
307
	if (use_privsep == -1)
325
	if (use_privsep == -1)
308
		use_privsep = PRIVSEP_NOSANDBOX;
326
		use_privsep = PRIVSEP_NOSANDBOX;
Lines 351-356 Link Here
351
	sKexAlgorithms, sIPQoS, sVersionAddendum,
369
	sKexAlgorithms, sIPQoS, sVersionAddendum,
352
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
370
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
353
	sAuthenticationMethods, sHostKeyAgent,
371
	sAuthenticationMethods, sHostKeyAgent,
372
#ifdef PAM_ENHANCEMENT
373
	sPAMServicePrefix, sPAMServiceName,
374
#endif
354
	sDeprecated, sUnsupported
375
	sDeprecated, sUnsupported
355
} ServerOpCodes;
376
} ServerOpCodes;
356
377
Lines 482-487 Link Here
482
	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
503
	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
483
	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
504
	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
484
	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
505
	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
506
#ifdef PAM_ENHANCEMENT
507
        { "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL },
508
        { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL },
509
#endif
485
	{ NULL, sBadOption, 0 }
510
	{ NULL, sBadOption, 0 }
486
};
511
};
487
512
Lines 1632-1637 Link Here
1632
		}
1657
		}
1633
		return 0;
1658
		return 0;
1634
1659
1660
	case sPAMServicePrefix:
1661
		arg = strdelim(&cp);
1662
		if (!arg || *arg == '\0')
1663
			fatal("%s line %d: Missing argument.",
1664
			    filename, linenum);
1665
		if (options->pam_service_name != NULL)
1666
			fatal("%s line %d: PAMServiceName and PAMServicePrefix"
1667
			    " are mutually exclusive.", filename, linenum);
1668
		if (options->pam_service_prefix == NULL)
1669
			options->pam_service_prefix = xstrdup(arg);
1670
		break;
1671
1672
	case sPAMServiceName:
1673
		arg = strdelim(&cp);
1674
		if (!arg || *arg == '\0')
1675
			fatal("%s line %d: Missing argument.",
1676
			    filename, linenum);
1677
		if (options->pam_service_prefix != NULL)
1678
			fatal("%s line %d: PAMServiceName and PAMServicePrefix"
1679
			    " are mutually exclusive.", filename, linenum);
1680
		if (options->pam_service_name == NULL) {
1681
			options->pam_service_name = xstrdup(arg);
1682
1683
			/*
1684
			 * When this option is specified, we will not have
1685
			 * PAM service for each auth method.
1686
                         */
1687
			options->pam_service_per_authmethod = 0;
1688
		}
1689
		break;
1690
1635
	case sDeprecated:
1691
	case sDeprecated:
1636
		logit("%s line %d: Deprecated option %s",
1692
		logit("%s line %d: Deprecated option %s",
1637
		    filename, linenum, arg);
1693
		    filename, linenum, arg);
(-)orig/servconf.h (+11 lines)
Lines 54-59 Link Here
54
/* Magic name for internal sftp-server */
54
/* Magic name for internal sftp-server */
55
#define INTERNAL_SFTP_NAME	"internal-sftp"
55
#define INTERNAL_SFTP_NAME	"internal-sftp"
56
56
57
#ifdef PAM_ENHANCEMENT
58
#define _SSH_PAM_SERVICE_PREFIX "sshd"
59
#endif
60
57
typedef struct {
61
typedef struct {
58
	u_int	num_ports;
62
	u_int	num_ports;
59
	u_int	ports_from_cmdline;
63
	u_int	ports_from_cmdline;
Lines 185-190 Link Here
185
189
186
	u_int	num_auth_methods;
190
	u_int	num_auth_methods;
187
	char   *auth_methods[MAX_AUTH_METHODS];
191
	char   *auth_methods[MAX_AUTH_METHODS];
192
193
#ifdef PAM_ENHANCEMENT
194
	char   *pam_service_prefix;
195
	char   *pam_service_name;
196
	int	pam_service_per_authmethod;
197
#endif
198
        
188
}       ServerOptions;
199
}       ServerOptions;
189
200
190
/* Information about the incoming connection as used by Match */
201
/* Information about the incoming connection as used by Match */
(-)orig/sshd_config.5 (+15 lines)
Lines 868-873 Link Here
868
are refused if the number of unauthenticated connections reaches
868
are refused if the number of unauthenticated connections reaches
869
.Dq full
869
.Dq full
870
(60).
870
(60).
871
.It Cm PAMServiceName
872
Specifies the PAM service name for the PAM session. The PAMServiceName and 
873
PAMServicePrefix options are mutually exclusive and if both set, sshd does not
874
start. If this option is set the service name is the same for all user 
875
authentication methods. The option has no default value. See PAMServicePrefix 
876
for more information.
877
.It Cm PAMServicePrefix
878
Specifies the PAM service name prefix for service names used for individual 
879
user authentication methods. The default is sshd. The PAMServiceName and 
880
PAMServicePrefix options are mutually exclusive and if both set, sshd does not 
881
start.
882
.Pp
883
For example, if this option is set to admincli, the service name for the 
884
keyboard-interactive authentication method is admincli-kbdint instead of the 
885
default sshd-kbdint.
871
.It Cm PasswordAuthentication
886
.It Cm PasswordAuthentication
872
Specifies whether password authentication is allowed.
887
Specifies whether password authentication is allowed.
873
The default is
888
The default is
(-)orig/sshd.8 (+27 lines)
Lines 951-956 Link Here
951
started last).
951
started last).
952
The content of this file is not sensitive; it can be world-readable.
952
The content of this file is not sensitive; it can be world-readable.
953
.El
953
.El
954
955
.Sh SECURITY
956
sshd uses pam(3PAM) for password and keyboard-interactive methods as well as 
957
for account management, session management, and the password management for all
958
authentication methods.
959
.Pp
960
Each SSHv2 userauth type has its own PAM service name:
961
962
.Bd -literal -offset 3n
963
964
-----------------------------------------------
965
| SSHv2 Userauth       | PAM Service Name     |
966
-----------------------------------------------
967
| none                 | sshd-none            |
968
-----------------------------------------------
969
| password             | sshd-password        |
970
-----------------------------------------------
971
| keyboard-interactive | sshd-kbdint          |
972
-----------------------------------------------
973
| pubkey               | sshd-pubkey          |
974
-----------------------------------------------
975
| hostbased            | sshd-hostbased       |
976
-----------------------------------------------
977
| gssapi-with-mic      | sshd-gssapi          |
978
-----------------------------------------------
979
.Ed
980
954
.Sh SEE ALSO
981
.Sh SEE ALSO
955
.Xr scp 1 ,
982
.Xr scp 1 ,
956
.Xr sftp 1 ,
983
.Xr sftp 1 ,
(-)orig/sshd.c (+5 lines)
Lines 2065-2070 Link Here
2065
2065
2066
	sshd_exchange_identification(sock_in, sock_out);
2066
	sshd_exchange_identification(sock_in, sock_out);
2067
2067
2068
#ifdef PAM_ENHANCEMENT
2069
	if (!compat20)
2070
	        options.pam_service_per_authmethod = 0;
2071
#endif
2072
2068
	/* In inetd mode, generate ephemeral key only for proto 1 connections */
2073
	/* In inetd mode, generate ephemeral key only for proto 1 connections */
2069
	if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
2074
	if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
2070
		generate_ephemeral_server_key();
2075
		generate_ephemeral_server_key();

Return to bug 2246