components/openssh/patches/016-pam_enhancement.patch
changeset 4071 4b68c2b0134b
parent 1979 bdbb0de8834e
child 4503 bf30d46ab06e
child 5324 5683175b6e99
equal deleted inserted replaced
4070:de7938d475ad 4071:4b68c2b0134b
     7 # We have contributed back this feature to the OpenSSH upstream community. 
     7 # We have contributed back this feature to the OpenSSH upstream community. 
     8 # For more information, see https://bugzilla.mindrot.org/show_bug.cgi?id=2246
     8 # For more information, see https://bugzilla.mindrot.org/show_bug.cgi?id=2246
     9 # In the future, if these enhancements are accepted by the upsteam in a 
     9 # In the future, if these enhancements are accepted by the upsteam in a 
    10 # later release, we will remove this patch when we upgrade to that release.
    10 # later release, we will remove this patch when we upgrade to that release.
    11 #
    11 #
    12 --- orig/auth-pam.c	Fri Jun 20 15:39:05 2014
    12 --- orig/auth-pam.c	Mon Jan 26 18:02:09 2015
    13 +++ new/auth-pam.c	Fri Jun 20 16:47:09 2014
    13 +++ new/auth-pam.c	Mon Mar 30 15:24:11 2015
    14 @@ -617,6 +617,72 @@
    14 @@ -617,6 +617,72 @@
    15  	sshpam_handle = NULL;
    15  	sshpam_handle = NULL;
    16  }
    16  }
    17  
    17  
    18 +#ifdef PAM_ENHANCEMENT
    18 +#ifdef PAM_ENHANCEMENT
    82 +#endif /* PAM_ENHANCEMENT */
    82 +#endif /* PAM_ENHANCEMENT */
    83 +
    83 +
    84  static int
    84  static int
    85  sshpam_init(Authctxt *authctxt)
    85  sshpam_init(Authctxt *authctxt)
    86  {
    86  {
    87 @@ -624,18 +690,61 @@
    87 @@ -624,18 +690,71 @@
    88  	const char *pam_rhost, *pam_user, *user = authctxt->user;
    88  	const char *pam_rhost, *pam_user, *user = authctxt->user;
    89  	const char **ptr_pam_user = &pam_user;
    89  	const char **ptr_pam_user = &pam_user;
    90  
    90  
    91 +#ifdef PAM_ENHANCEMENT
    91 +#ifdef PAM_ENHANCEMENT
    92 +	const char *pam_service;
    92 +	const char *pam_service;
   119 +		    && strncmp(svc, pam_service, strlen(svc)) == 0) {
   119 +		    && strncmp(svc, pam_service, strlen(svc)) == 0) {
   120 +		        free(svc);
   120 +		        free(svc);
   121 +			return (0);
   121 +			return (0);
   122 +                }
   122 +                }
   123 +
   123 +
       
   124 +		/*
       
   125 +		 * Clean up previous PAM state.  No need to clean up session 
       
   126 +		 * and creds.
       
   127 +		 */
       
   128 +                sshpam_authenticated = 0;
       
   129 +                sshpam_account_status = -1;
       
   130 +
       
   131 +		sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, NULL);
       
   132 +         	if (sshpam_err != PAM_SUCCESS)
       
   133 +		        debug3("Cannot remove PAM conv"); /* a warning only */
   124 +#else /* Original */
   134 +#else /* Original */
   125  		/* We already have a PAM context; check if the user matches */
   135  		/* We already have a PAM context; check if the user matches */
   126  		sshpam_err = pam_get_item(sshpam_handle,
   136  		sshpam_err = pam_get_item(sshpam_handle,
   127  		    PAM_USER, (sshpam_const void **)ptr_pam_user);
   137  		    PAM_USER, (sshpam_const void **)ptr_pam_user);
   128  		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
   138  		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
   144  	    pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
   154  	    pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
   145 +#endif
   155 +#endif
   146  	sshpam_authctxt = authctxt;
   156  	sshpam_authctxt = authctxt;
   147  
   157  
   148  	if (sshpam_err != PAM_SUCCESS) {
   158  	if (sshpam_err != PAM_SUCCESS) {
   149 --- orig/auth.h	Fri Jun 20 15:39:05 2014
   159 --- orig/auth.h	Mon Jan 26 18:02:11 2015
   150 +++ new/auth.h	Fri Jun 20 15:39:05 2014
   160 +++ new/auth.h	Mon Jan 26 18:02:11 2015
   151 @@ -76,6 +76,9 @@
   161 @@ -76,6 +76,9 @@
   152  #endif
   162  #endif
   153  	Buffer		*loginmsg;
   163  	Buffer		*loginmsg;
   154  	void		*methoddata;
   164  	void		*methoddata;
   155 +#ifdef PAM_ENHANCEMENT
   165 +#ifdef PAM_ENHANCEMENT
   156 +        char            *authmethod_name;
   166 +        char            *authmethod_name;
   157 +#endif 
   167 +#endif 
   158  };
   168  };
   159  /*
   169  /*
   160   * Every authentication method has to handle authentication requests for
   170   * Every authentication method has to handle authentication requests for
   161 --- orig/auth2.c	Fri Jun 20 15:39:05 2014
   171 --- orig/auth2.c	Mon Jan 26 18:02:10 2015
   162 +++ new/auth2.c	Fri Jun 20 15:39:05 2014
   172 +++ new/auth2.c	Tue Mar 31 15:19:10 2015
   163 @@ -249,10 +249,13 @@
   173 @@ -249,10 +249,21 @@
   164  			PRIVSEP(audit_event(SSH_INVALID_USER));
   174  			PRIVSEP(audit_event(SSH_INVALID_USER));
   165  #endif
   175  #endif
   166  		}
   176  		}
   167 +
   177 +
   168 +#ifndef PAM_ENHANCEMENT
   178 +
   169  #ifdef USE_PAM
   179  #ifdef USE_PAM
       
   180 +#ifdef PAM_ENHANCEMENT
       
   181 +		/*
       
   182 +		 * Start PAM here and once only, if each userauth does not
       
   183 +		 * has its own PAM service.
       
   184 +		 */
       
   185 +	        if (options.use_pam && !options.pam_service_per_authmethod)
       
   186 +			PRIVSEP(start_pam(authctxt));
       
   187 +#else
   170  		if (options.use_pam)
   188  		if (options.use_pam)
   171  			PRIVSEP(start_pam(authctxt));
   189  			PRIVSEP(start_pam(authctxt));
   172  #endif
   190  #endif
   173 +#endif
   191 +#endif
   174  		setproctitle("%s%s", authctxt->valid ? user : "unknown",
   192  		setproctitle("%s%s", authctxt->valid ? user : "unknown",
   175  		    use_privsep ? " [net]" : "");
   193  		    use_privsep ? " [net]" : "");
   176  		authctxt->service = xstrdup(service);
   194  		authctxt->service = xstrdup(service);
   177 @@ -286,6 +289,14 @@
   195 @@ -286,6 +297,18 @@
   178  	/* try to authenticate user */
   196  	/* try to authenticate user */
   179  	m = authmethod_lookup(authctxt, method);
   197  	m = authmethod_lookup(authctxt, method);
   180  	if (m != NULL && authctxt->failures < options.max_authtries) {
   198  	if (m != NULL && authctxt->failures < options.max_authtries) {
   181 +
   199 +
   182 +#ifdef PAM_ENHANCEMENT
   200 +#if defined(USE_PAM) && defined(PAM_ENHANCEMENT)
   183 +                authctxt->authmethod_name = xstrdup(method);
   201 +		/* start PAM service for each userauth */
   184 +                if (use_privsep)
   202 +                if (options.use_pam && options.pam_service_per_authmethod) {
   185 +                       mm_inform_authmethod(method);
   203 +       		        if (authctxt->authmethod_name != NULL)
   186 +		if (options.use_pam)
   204 +		                free(authctxt->authmethod_name);
   187 +		       PRIVSEP(start_pam(authctxt));
   205 +                        authctxt->authmethod_name = xstrdup(method);
       
   206 +                        if (use_privsep)
       
   207 +                                mm_inform_authmethod(method);
       
   208 +		        PRIVSEP(start_pam(authctxt));
       
   209 +		}
   188 +#endif
   210 +#endif
   189  		debug2("input_userauth_request: try method %s", method);
   211  		debug2("input_userauth_request: try method %s", method);
   190  		authenticated =	m->userauth(authctxt);
   212  		authenticated =	m->userauth(authctxt);
   191  	}
   213  	}
   192 @@ -303,6 +314,10 @@
   214 @@ -303,6 +326,10 @@
   193  	char *methods;
   215  	char *methods;
   194  	int partial = 0;
   216  	int partial = 0;
   195  
   217  
   196 +#ifdef  PAM_ENHANCEMENT
   218 +#ifdef  PAM_ENHANCEMENT
   197 +        debug3("%s: entering", __func__);
   219 +        debug3("%s: entering", __func__);
   198 +#endif
   220 +#endif
   199 +
   221 +
   200  	if (!authctxt->valid && authenticated)
   222  	if (!authctxt->valid && authenticated)
   201  		fatal("INTERNAL ERROR: authenticated invalid user %s",
   223  		fatal("INTERNAL ERROR: authenticated invalid user %s",
   202  		    authctxt->user);
   224  		    authctxt->user);
   203 @@ -623,5 +638,3 @@
   225 @@ -319,6 +346,25 @@
       
   226  	}
       
   227  
       
   228  	if (authenticated && options.num_auth_methods != 0) {
       
   229 +
       
   230 +#if defined(USE_PAM) && defined(PAM_ENHANCEMENT)
       
   231 +                /*
       
   232 +                 * If each userauth has its own PAM service, then PAM need to 
       
   233 +                 * perform account check for this service.
       
   234 +                 */
       
   235 +                if (options.use_pam && options.pam_service_per_authmethod &&
       
   236 +                    !PRIVSEP(do_pam_account())) {
       
   237 +                        /* if PAM returned a message, send it to the user */
       
   238 +                        if (buffer_len(&loginmsg) > 0) {
       
   239 +                                buffer_append(&loginmsg, "\0", 1);
       
   240 +                                userauth_send_banner(buffer_ptr(&loginmsg));
       
   241 +                                packet_write_wait();
       
   242 +                        }
       
   243 +
       
   244 +                        fatal("Access denied for user %s by PAM account "
       
   245 +                            "configuration", authctxt->user);
       
   246 +                }
       
   247 +#endif
       
   248  		if (!auth2_update_methods_lists(authctxt, method, submethod)) {
       
   249  			authenticated = 0;
       
   250  			partial = 1;
       
   251 @@ -332,7 +378,20 @@
       
   252  		return;
       
   253  
       
   254  #ifdef USE_PAM
       
   255 +
       
   256 +#ifdef PAM_ENHANCEMENT
       
   257 +        /*
       
   258 +         * PAM needs to perform account checks after auth. However, if each
       
   259 +         * userauth has its own PAM service and options.num_auth_methods != 0,
       
   260 +         * then no need to perform account checking, because it was done 
       
   261 +         * already.
       
   262 +         */
       
   263 +        if (options.use_pam && authenticated && 
       
   264 +            !(options.num_auth_methods != 0 &&
       
   265 +            options.pam_service_per_authmethod)){
       
   266 +#else
       
   267  	if (options.use_pam && authenticated) {
       
   268 +#endif
       
   269  		if (!PRIVSEP(do_pam_account())) {
       
   270  			/* if PAM returned a message, send it to the user */
       
   271  			if (buffer_len(&loginmsg) > 0) {
       
   272 @@ -623,5 +682,3 @@
   204  		fatal("%s: method not in AuthenticationMethods", __func__);
   273  		fatal("%s: method not in AuthenticationMethods", __func__);
   205  	return 0;
   274  	return 0;
   206  }
   275  }
   207 -
   276 -
   208 -
   277 -
   209 --- orig/monitor_wrap.c	Fri Jun 20 15:39:05 2014
   278 --- orig/monitor_wrap.c	Mon Jan 26 18:02:09 2015
   210 +++ new/monitor_wrap.c	Fri Jun 20 15:39:05 2014
   279 +++ new/monitor_wrap.c	Mon Jan 26 18:02:11 2015
   211 @@ -338,6 +338,24 @@
   280 @@ -338,6 +338,24 @@
   212  	buffer_free(&m);
   281  	buffer_free(&m);
   213  }
   282  }
   214  
   283  
   215 +#ifdef PAM_ENHANCEMENT
   284 +#ifdef PAM_ENHANCEMENT
   231 +#endif
   300 +#endif
   232 +
   301 +
   233  /* Do the password authentication */
   302  /* Do the password authentication */
   234  int
   303  int
   235  mm_auth_password(Authctxt *authctxt, char *password)
   304  mm_auth_password(Authctxt *authctxt, char *password)
   236 --- orig/monitor.c	Fri Jun 20 15:39:05 2014
   305 --- orig/monitor.c	Mon Jan 26 18:02:10 2015
   237 +++ new/monitor.c	Fri Jun 20 15:39:05 2014
   306 +++ new/monitor.c	Tue Mar 31 16:10:50 2015
   238 @@ -146,6 +146,9 @@
   307 @@ -146,6 +146,9 @@
   239  int mm_answer_pwnamallow(int, Buffer *);
   308  int mm_answer_pwnamallow(int, Buffer *);
   240  int mm_answer_auth2_read_banner(int, Buffer *);
   309  int mm_answer_auth2_read_banner(int, Buffer *);
   241  int mm_answer_authserv(int, Buffer *);
   310  int mm_answer_authserv(int, Buffer *);
   242 +#ifdef PAM_ENHANCEMENT
   311 +#ifdef PAM_ENHANCEMENT
   261      {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
   330      {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
   262 +#endif
   331 +#endif
   263      {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
   332      {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
   264      {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
   333      {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
   265      {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
   334      {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
   266 @@ -828,6 +838,10 @@
   335 @@ -391,6 +401,24 @@
       
   336  			if (!compat20)
       
   337  				fatal("AuthenticationMethods is not supported"
       
   338  				    "with SSH protocol 1");
       
   339 +
       
   340 +#if defined(USE_PAM) && defined(PAM_ENHANCEMENT)
       
   341 +                        /* 
       
   342 +                         * If each userauth has its own PAM service, then PAM
       
   343 +                         * need to perform account check for this service.
       
   344 +                         */
       
   345 +                        if (options.use_pam && authenticated &&
       
   346 +                            options.pam_service_per_authmethod) {
       
   347 +                                Buffer m;
       
   348 +
       
   349 +                                buffer_init(&m);
       
   350 +                                mm_request_receive_expect(pmonitor->m_sendfd,
       
   351 +                                    MONITOR_REQ_PAM_ACCOUNT, &m);
       
   352 +                                authenticated = 
       
   353 +                                    mm_answer_pam_account(pmonitor->m_sendfd, &m);
       
   354 +                                buffer_free(&m);
       
   355 +                         }
       
   356 +#endif
       
   357  			if (authenticated &&
       
   358  			    !auth2_update_methods_lists(authctxt,
       
   359  			    auth_method, auth_submethod)) {
       
   360 @@ -409,8 +437,21 @@
       
   361  			    !auth_root_allowed(auth_method))
       
   362  				authenticated = 0;
       
   363  #ifdef USE_PAM
       
   364 +#ifdef PAM_ENHANCEMENT
       
   365 +                        /*
       
   366 +                         * PAM needs to perform account checks after auth.
       
   367 +                         * However, if each userauth has its own PAM service
       
   368 +                         * and options.num_auth_methods != 0, then no need to
       
   369 +                         * perform account checking, because it was done 
       
   370 +                         * already.
       
   371 +                         */
       
   372 +                        if (options.use_pam && authenticated &&
       
   373 +                            !(options.num_auth_methods != 0 &&
       
   374 +                            options.pam_service_per_authmethod)) {
       
   375 +#else
       
   376  			/* PAM needs to perform account checks after auth */
       
   377  			if (options.use_pam && authenticated) {
       
   378 +#endif
       
   379  				Buffer m;
       
   380  
       
   381  				buffer_init(&m);
       
   382 @@ -828,6 +869,10 @@
   267  		/* Allow service/style information on the auth context */
   383  		/* Allow service/style information on the auth context */
   268  		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
   384  		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
   269  		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
   385  		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
   270 +#ifdef PAM_ENHANCEMENT
   386 +#ifdef PAM_ENHANCEMENT
   271 +                /* Allow authmethod information on the auth context */
   387 +                /* Allow authmethod information on the auth context */
   272 +		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHMETHOD, 1);
   388 +		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHMETHOD, 1);
   273 +#endif
   389 +#endif
   274  	}
   390  	}
   275  #ifdef USE_PAM
   391  #ifdef USE_PAM
   276  	if (options.use_pam)
   392  	if (options.use_pam)
   277 @@ -868,7 +882,25 @@
   393 @@ -868,7 +913,25 @@
   278  	return (0);
   394  	return (0);
   279  }
   395  }
   280  
   396  
   281 +#ifdef PAM_ENHANCEMENT
   397 +#ifdef PAM_ENHANCEMENT
   282  int
   398  int
   298 +
   414 +
   299 +int
   415 +int
   300  mm_answer_authpassword(int sock, Buffer *m)
   416  mm_answer_authpassword(int sock, Buffer *m)
   301  {
   417  {
   302  	static int call_count;
   418  	static int call_count;
   303 --- orig/monitor.h	Fri Jun 20 15:39:05 2014
   419 --- orig/monitor.h	Mon Jan 26 18:02:10 2015
   304 +++ new/monitor.h	Fri Jun 20 15:39:05 2014
   420 +++ new/monitor.h	Mon Jan 26 18:02:11 2015
   305 @@ -70,6 +70,9 @@
   421 @@ -70,6 +70,9 @@
   306  	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
   422  	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
   307  	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
   423  	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
   308  
   424  
   309 +#ifdef PAM_ENHANCEMENT
   425 +#ifdef PAM_ENHANCEMENT
   310 +        MONITOR_REQ_AUTHMETHOD = 114,
   426 +        MONITOR_REQ_AUTHMETHOD = 114,
   311 +#endif        
   427 +#endif        
   312  };
   428  };
   313  
   429  
   314  struct mm_master;
   430  struct mm_master;
   315 --- orig/servconf.c	Fri Jun 20 15:39:05 2014
   431 --- orig/servconf.c	Mon Jan 26 18:02:09 2015
   316 +++ new/servconf.c	Fri Jun 20 15:39:05 2014
   432 +++ new/servconf.c	Tue Mar 31 16:24:59 2015
   317 @@ -154,6 +154,10 @@
   433 @@ -154,6 +154,18 @@
   318  	options->ip_qos_interactive = -1;
   434  	options->ip_qos_interactive = -1;
   319  	options->ip_qos_bulk = -1;
   435  	options->ip_qos_bulk = -1;
   320  	options->version_addendum = NULL;
   436  	options->version_addendum = NULL;
   321 +#ifdef PAM_ENHANCEMENT
   437 +#ifdef PAM_ENHANCEMENT
   322 +	options->pam_service_name = NULL;
   438 +	options->pam_service_name = NULL;
   323 +	options->pam_service_prefix = NULL;
   439 +	options->pam_service_prefix = NULL;
       
   440 +
       
   441 +	/* 
       
   442 +	 * Each user method will have its own PAM service by default.
       
   443 +	 * However, if PAMServiceName is specified or the protocal version
       
   444 +	 * is not compat20, then there will be only one PAM service for the
       
   445 +	 * entire user authentication.
       
   446 +	 */
       
   447 +        options->pam_service_per_authmethod = 1;
   324 +#endif
   448 +#endif
   325  }
   449  }
   326  
   450  
   327  void
   451  void
   328 @@ -303,6 +307,12 @@
   452 @@ -303,6 +315,12 @@
   329  		options->ip_qos_bulk = IPTOS_THROUGHPUT;
   453  		options->ip_qos_bulk = IPTOS_THROUGHPUT;
   330  	if (options->version_addendum == NULL)
   454  	if (options->version_addendum == NULL)
   331  		options->version_addendum = xstrdup("");
   455  		options->version_addendum = xstrdup("");
   332 +
   456 +
   333 +#ifdef PAM_ENHANCEMENT
   457 +#ifdef PAM_ENHANCEMENT
   336 +#endif
   460 +#endif
   337 +
   461 +
   338  	/* Turn privilege separation on by default */
   462  	/* Turn privilege separation on by default */
   339  	if (use_privsep == -1)
   463  	if (use_privsep == -1)
   340  		use_privsep = PRIVSEP_NOSANDBOX;
   464  		use_privsep = PRIVSEP_NOSANDBOX;
   341 @@ -351,6 +361,9 @@
   465 @@ -351,6 +369,9 @@
   342  	sKexAlgorithms, sIPQoS, sVersionAddendum,
   466  	sKexAlgorithms, sIPQoS, sVersionAddendum,
   343  	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
   467  	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
   344  	sAuthenticationMethods, sHostKeyAgent,
   468  	sAuthenticationMethods, sHostKeyAgent,
   345 +#ifdef PAM_ENHANCEMENT
   469 +#ifdef PAM_ENHANCEMENT
   346 +	sPAMServicePrefix, sPAMServiceName,
   470 +	sPAMServicePrefix, sPAMServiceName,
   347 +#endif
   471 +#endif
   348  	sDeprecated, sUnsupported
   472  	sDeprecated, sUnsupported
   349  } ServerOpCodes;
   473  } ServerOpCodes;
   350  
   474  
   351 @@ -482,6 +495,10 @@
   475 @@ -482,6 +503,10 @@
   352  	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
   476  	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
   353  	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
   477  	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
   354  	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
   478  	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
   355 +#ifdef PAM_ENHANCEMENT
   479 +#ifdef PAM_ENHANCEMENT
   356 +        { "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL },
   480 +        { "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL },
   357 +        { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL },
   481 +        { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL },
   358 +#endif
   482 +#endif
   359  	{ NULL, sBadOption, 0 }
   483  	{ NULL, sBadOption, 0 }
   360  };
   484  };
   361  
   485  
   362 @@ -1632,6 +1649,30 @@
   486 @@ -1632,6 +1657,37 @@
   363  		}
   487  		}
   364  		return 0;
   488  		return 0;
   365  
   489  
   366 +	case sPAMServicePrefix:
   490 +	case sPAMServicePrefix:
   367 +		arg = strdelim(&cp);
   491 +		arg = strdelim(&cp);
   381 +			fatal("%s line %d: Missing argument.",
   505 +			fatal("%s line %d: Missing argument.",
   382 +			    filename, linenum);
   506 +			    filename, linenum);
   383 +		if (options->pam_service_prefix != NULL)
   507 +		if (options->pam_service_prefix != NULL)
   384 +			fatal("%s line %d: PAMServiceName and PAMServicePrefix"
   508 +			fatal("%s line %d: PAMServiceName and PAMServicePrefix"
   385 +			    " are mutually exclusive.", filename, linenum);
   509 +			    " are mutually exclusive.", filename, linenum);
   386 +		if (options->pam_service_name == NULL)
   510 +		if (options->pam_service_name == NULL) {
   387 +			options->pam_service_name = xstrdup(arg);
   511 +			options->pam_service_name = xstrdup(arg);
       
   512 +
       
   513 +			/*
       
   514 +			 * When this option is specified, we will not have
       
   515 +			 * PAM service for each auth method.
       
   516 +                         */
       
   517 +			options->pam_service_per_authmethod = 0;
       
   518 +		}
   388 +		break;
   519 +		break;
   389 +
   520 +
   390  	case sDeprecated:
   521  	case sDeprecated:
   391  		logit("%s line %d: Deprecated option %s",
   522  		logit("%s line %d: Deprecated option %s",
   392  		    filename, linenum, arg);
   523  		    filename, linenum, arg);
   393 --- orig/servconf.h	Fri Jun 20 15:39:05 2014
   524 --- orig/servconf.h	Mon Jan 26 18:02:10 2015
   394 +++ new/servconf.h	Fri Jun 20 15:39:05 2014
   525 +++ new/servconf.h	Tue Mar 31 15:07:14 2015
   395 @@ -54,6 +54,10 @@
   526 @@ -54,6 +54,10 @@
   396  /* Magic name for internal sftp-server */
   527  /* Magic name for internal sftp-server */
   397  #define INTERNAL_SFTP_NAME	"internal-sftp"
   528  #define INTERNAL_SFTP_NAME	"internal-sftp"
   398  
   529  
   399 +#ifdef PAM_ENHANCEMENT
   530 +#ifdef PAM_ENHANCEMENT
   401 +#endif
   532 +#endif
   402 +
   533 +
   403  typedef struct {
   534  typedef struct {
   404  	u_int	num_ports;
   535  	u_int	num_ports;
   405  	u_int	ports_from_cmdline;
   536  	u_int	ports_from_cmdline;
   406 @@ -185,6 +189,12 @@
   537 @@ -185,6 +189,13 @@
   407  
   538  
   408  	u_int	num_auth_methods;
   539  	u_int	num_auth_methods;
   409  	char   *auth_methods[MAX_AUTH_METHODS];
   540  	char   *auth_methods[MAX_AUTH_METHODS];
   410 +
   541 +
   411 +#ifdef PAM_ENHANCEMENT
   542 +#ifdef PAM_ENHANCEMENT
   412 +	char   *pam_service_prefix;
   543 +	char   *pam_service_prefix;
   413 +	char   *pam_service_name;
   544 +	char   *pam_service_name;
       
   545 +	int	pam_service_per_authmethod;
   414 +#endif
   546 +#endif
   415 +        
   547 +        
   416  }       ServerOptions;
   548  }       ServerOptions;
   417  
   549  
   418  /* Information about the incoming connection as used by Match */
   550  /* Information about the incoming connection as used by Match */
   419 --- orig/sshd_config.5	Fri Jun 20 15:39:05 2014
   551 --- orig/sshd_config.5	Mon Jan 26 18:02:10 2015
   420 +++ new/sshd_config.5	Fri Jun 20 15:39:05 2014
   552 +++ new/sshd_config.5	Mon Jan 26 18:03:45 2015
   421 @@ -868,6 +868,21 @@
   553 @@ -868,6 +868,21 @@
   422  are refused if the number of unauthenticated connections reaches
   554  are refused if the number of unauthenticated connections reaches
   423  .Dq full
   555  .Dq full
   424  (60).
   556  (60).
   425 +.It Cm PAMServiceName
   557 +.It Cm PAMServiceName
   438 +keyboard-interactive authentication method is admincli-kbdint instead of the 
   570 +keyboard-interactive authentication method is admincli-kbdint instead of the 
   439 +default sshd-kbdint.
   571 +default sshd-kbdint.
   440  .It Cm PasswordAuthentication
   572  .It Cm PasswordAuthentication
   441  Specifies whether password authentication is allowed.
   573  Specifies whether password authentication is allowed.
   442  The default is
   574  The default is
   443 --- orig/sshd.8	Fri Jun 20 15:39:05 2014
   575 @@ -1203,8 +1218,7 @@
   444 +++ new/sshd.8	Fri Jun 20 15:39:05 2014
   576  is enabled, you will not be able to run
       
   577  .Xr sshd 8
       
   578  as a non-root user.
       
   579 -The default is
       
   580 -.Dq no .
       
   581 +On Solaris, the option is always enabled.
       
   582  .It Cm UsePrivilegeSeparation
       
   583  Specifies whether
       
   584  .Xr sshd 8
       
   585 --- orig/sshd.8	Mon Jan 26 18:02:09 2015
       
   586 +++ new/sshd.8	Mon Jan 26 18:02:11 2015
   445 @@ -951,6 +951,33 @@
   587 @@ -951,6 +951,33 @@
   446  started last).
   588  started last).
   447  The content of this file is not sensitive; it can be world-readable.
   589  The content of this file is not sensitive; it can be world-readable.
   448  .El
   590  .El
   449 +
   591 +
   474 +.Ed
   616 +.Ed
   475 +
   617 +
   476  .Sh SEE ALSO
   618  .Sh SEE ALSO
   477  .Xr scp 1 ,
   619  .Xr scp 1 ,
   478  .Xr sftp 1 ,
   620  .Xr sftp 1 ,
       
   621 --- orig/sshd.c	Tue Mar 31 18:12:33 2015
       
   622 +++ new/sshd.c	Tue Mar 31 18:42:28 2015
       
   623 @@ -2065,6 +2065,11 @@
       
   624  
       
   625  	sshd_exchange_identification(sock_in, sock_out);
       
   626  
       
   627 +#ifdef PAM_ENHANCEMENT
       
   628 +	if (!compat20)
       
   629 +	        options.pam_service_per_authmethod = 0;
       
   630 +#endif
       
   631 +
       
   632  	/* In inetd mode, generate ephemeral key only for proto 1 connections */
       
   633  	if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
       
   634  		generate_ephemeral_server_key();