Bugzilla – Attachment 2504 Details for
Bug 2246
specify PAM service name, per authn-method service names
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
pamservicename_enhancement.patch
pamservicename_enhancement.patch (text/plain), 18.83 KB, created by
huieying.lee
on 2014-11-06 12:40:36 AEDT
(
hide
)
Description:
pamservicename_enhancement.patch
Filename:
MIME Type:
Creator:
huieying.lee
Created:
2014-11-06 12:40:36 AEDT
Size:
18.83 KB
patch
obsolete
># ># ># >--- orig/auth-pam.c Thu Oct 23 11:49:50 2014 >+++ new/auth-pam.c Thu Oct 23 11:49:51 2014 >@@ -617,6 +617,80 @@ > sshpam_handle = NULL; > } > >+#ifdef PAM_ENHANCEMENT >+char * >+derive_pam_service_name(Authctxt *authctxt) >+{ >+ char *svcname = NULL; >+ char *method_name; >+ >+ if (!compat20 && options.pam_service_per_authmethod) >+ fatal("PAMServiceName -%m can not be used in protocol 1"); >+ >+ if (options.pam_service_name == NULL) { >+ /* default to "sshd" */ >+ svcname = xstrdup("sshd"); >+ return (svcname); >+ } >+ >+ if (!options.pam_service_per_authmethod) { >+ /* >+ * no -%m in PAMServiceName option, so >+ * options.pam_service_name is the PAM Service Name. >+ */ >+ svcname = xstrdup(options.pam_service_name); >+ return (svcname); >+ } else { >+ char *method_name = authctxt->authmethod_name; >+ int svcname_len; >+ >+ if (!method_name) >+ fatal("Userauth method unknown while starting PAM"); >+ >+ /* >+ * Expand -%m; options.pam_service_name is now the prefix. >+ * Should allocate sufficient space for the expanded PAM >+ * service name. >+ */ >+ svcname_len = strlen(options.pam_service_name) + 20; >+ svcname = xmalloc(svcname_len); >+ >+ if (strcmp(method_name, "none") == 0) { >+ snprintf(svcname, svcname_len, "%s-none", >+ options.pam_service_name); >+ } >+ if (strcmp(method_name, "password") == 0) { >+ snprintf(svcname, svcname_len, "%s-password", >+ options.pam_service_name); >+ } >+ if (strcmp(method_name, "keyboard-interactive") == 0) { >+ /* "keyboard-interactive" is too long, shorten it */ >+ snprintf(svcname, svcname_len, "%s-kbdint", >+ options.pam_service_name); >+ } >+ if (strcmp(method_name, "publickey") == 0) { >+ /* "publickey" is too long, shorten it */ >+ snprintf(svcname, svcname_len, "%s-pubkey", >+ options.pam_service_name); >+ } >+ if (strcmp(method_name, "hostbased") == 0) { >+ snprintf(svcname, svcname_len, "%s-hostbased", >+ options.pam_service_name); >+ } >+ if (strncmp(method_name, "gssapi-", 7) == 0) { >+ /* >+ * Although OpenSSH only supports "gssapi-with-mic" >+ * for now. We will still map any userauth method >+ * prefixed with "gssapi-" to the gssapi PAM service. >+ */ >+ snprintf(svcname, svcname_len, "%s-gssapi", >+ options.pam_service_name); >+ } >+ return svcname; >+ } >+} >+#endif /* PAM_ENHANCEMENT */ >+ > static int > sshpam_init(Authctxt *authctxt) > { >@@ -624,7 +698,54 @@ > const char *pam_rhost, *pam_user, *user = authctxt->user; > const char **ptr_pam_user = &pam_user; > >+#ifdef PAM_ENHANCEMENT >+ const char *pam_service; >+ const char **ptr_pam_service = &pam_service; >+ char *svc = NULL; >+ >+ svc = derive_pam_service_name(authctxt); >+ debug3("PAM service is %s", svc); >+#endif >+ > if (sshpam_handle != NULL) { >+#ifdef PAM_ENHANCEMENT >+ /* get the pam service name */ >+ sshpam_err = pam_get_item(sshpam_handle, >+ PAM_SERVICE, (sshpam_const void **)ptr_pam_service); >+ if (sshpam_err != PAM_SUCCESS) >+ fatal("Failed to get the PAM service name"); >+ debug3("Previous pam_service is %s", pam_service ? >+ pam_service : "NULL"); >+ >+ /* get the pam user name */ >+ sshpam_err = pam_get_item(sshpam_handle, >+ PAM_USER, (sshpam_const void **)ptr_pam_user); >+ >+ /* >+ * only need to re-start if either user or service is >+ * different. >+ */ >+ if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0 >+ && strncmp(svc, pam_service, strlen(svc)) == 0) { >+ free(svc); >+ return (0); >+ } >+ >+ /* >+ * Clean up previous PAM state. No need to clean up session >+ * and creds. >+ */ >+ sshpam_authenticated = 0; >+ sshpam_account_status = -1; >+ >+ sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, NULL); >+ if (sshpam_err != PAM_SUCCESS) >+ debug3("Cannot remove PAM conv"); /* a warning only */ >+ >+ pam_end(sshpam_handle, sshpam_err); >+ sshpam_handle = NULL; >+ >+#else /* Original */ > /* We already have a PAM context; check if the user matches */ > sshpam_err = pam_get_item(sshpam_handle, > PAM_USER, (sshpam_const void **)ptr_pam_user); >@@ -632,10 +753,20 @@ > return (0); > pam_end(sshpam_handle, sshpam_err); > sshpam_handle = NULL; >+#endif /* PAM_ENHANCEMENT */ > } > debug("PAM: initializing for \"%s\"", user); >+ >+#ifdef PAM_ENHANCEMENT >+ debug("Starting PAM service %s for user %s method %s", svc, user, >+ authctxt->authmethod_name); > sshpam_err = >+ pam_start(svc, user, &store_conv, &sshpam_handle); >+ free(svc); >+#else /* Original */ >+ sshpam_err = > pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle); >+#endif > sshpam_authctxt = authctxt; > > if (sshpam_err != PAM_SUCCESS) { >--- orig/auth.h Thu Oct 23 11:49:50 2014 >+++ new/auth.h Thu Oct 23 11:49:51 2014 >@@ -76,6 +76,9 @@ > #endif > Buffer *loginmsg; > void *methoddata; >+#ifdef PAM_ENHANCEMENT >+ char *authmethod_name; >+#endif > }; > /* > * Every authentication method has to handle authentication requests for >--- orig/auth2.c Thu Oct 23 11:49:50 2014 >+++ new/auth2.c Thu Oct 23 11:49:51 2014 >@@ -249,10 +249,20 @@ > PRIVSEP(audit_event(SSH_INVALID_USER)); > #endif > } >+ > #ifdef USE_PAM >+#ifdef PAM_ENHANCEMENT >+ /* >+ * Start PAM here and once only, if each userauth does not >+ * has its own PAM service. >+ */ >+ if (options.use_pam && !options.pam_service_per_authmethod) >+ PRIVSEP(start_pam(authctxt)); >+#else > if (options.use_pam) > PRIVSEP(start_pam(authctxt)); > #endif >+#endif > setproctitle("%s%s", authctxt->valid ? user : "unknown", > use_privsep ? " [net]" : ""); > authctxt->service = xstrdup(service); >@@ -286,6 +296,18 @@ > /* try to authenticate user */ > m = authmethod_lookup(authctxt, method); > if (m != NULL && authctxt->failures < options.max_authtries) { >+ >+#if defined(USE_PAM) && defined(PAM_ENHANCEMENT) >+ /* start PAM service for each userauth */ >+ if (options.use_pam && options.pam_service_per_authmethod) { >+ if (authctxt->authmethod_name != NULL) >+ free(authctxt->authmethod_name); >+ authctxt->authmethod_name = xstrdup(method); >+ if (use_privsep) >+ mm_inform_authmethod(method); >+ PRIVSEP(start_pam(authctxt)); >+ } >+#endif > debug2("input_userauth_request: try method %s", method); > authenticated = m->userauth(authctxt); > } >@@ -303,6 +325,10 @@ > char *methods; > int partial = 0; > >+#ifdef PAM_ENHANCEMENT >+ debug3("%s: entering", __func__); >+#endif >+ > if (!authctxt->valid && authenticated) > fatal("INTERNAL ERROR: authenticated invalid user %s", > authctxt->user); >@@ -319,6 +345,24 @@ > } > > if (authenticated && options.num_auth_methods != 0) { >+#if defined(USE_PAM) && defined(PAM_ENHANCEMENT) >+ /* >+ * If each userauth has its own PAM service, then PAM need to >+ * perform account check for this service. >+ */ >+ if (options.use_pam && options.pam_service_per_authmethod && >+ !PRIVSEP(do_pam_account())) { >+ /* if PAM returned a message, send it to the user */ >+ if (buffer_len(&loginmsg) > 0) { >+ buffer_append(&loginmsg, "\0", 1); >+ userauth_send_banner(buffer_ptr(&loginmsg)); >+ packet_write_wait(); >+ } >+ >+ fatal("Access denied for user %s by PAM account " >+ "configuration", authctxt->user); >+ } >+#endif > if (!auth2_update_methods_lists(authctxt, method, submethod)) { > authenticated = 0; > partial = 1; >@@ -332,7 +376,19 @@ > return; > > #ifdef USE_PAM >+#ifdef PAM_ENHANCEMENT >+ /* >+ * PAM needs to perform account checks after auth. However, if each >+ * userauth has its own PAM service and options.num_auth_methods != 0, >+ * then no need to perform account checking, because it was done >+ * already. >+ */ >+ if (options.use_pam && authenticated && >+ !(options.num_auth_methods != 0 && >+ options.pam_service_per_authmethod)){ >+#else > if (options.use_pam && authenticated) { >+#endif > if (!PRIVSEP(do_pam_account())) { > /* if PAM returned a message, send it to the user */ > if (buffer_len(&loginmsg) > 0) { >--- orig/monitor_wrap.c Thu Oct 23 11:49:50 2014 >+++ new/monitor_wrap.c Thu Oct 23 11:49:51 2014 >@@ -338,6 +338,24 @@ > buffer_free(&m); > } > >+#ifdef PAM_ENHANCEMENT >+/* Inform the privileged process about the authentication method */ >+void >+mm_inform_authmethod(char *authmethod) >+{ >+ Buffer m; >+ >+ debug3("%s entering", __func__); >+ >+ buffer_init(&m); >+ buffer_put_cstring(&m, authmethod); >+ >+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHMETHOD, &m); >+ >+ buffer_free(&m); >+} >+#endif >+ > /* Do the password authentication */ > int > mm_auth_password(Authctxt *authctxt, char *password) >--- orig/monitor_wrap.h Thu Oct 23 11:49:50 2014 >+++ new/monitor_wrap.h Thu Oct 23 11:49:51 2014 >@@ -42,6 +42,11 @@ > DH *mm_choose_dh(int, int, int); > int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); > void mm_inform_authserv(char *, char *); >+ >+#ifdef PAM_ENHANCEMENT >+void mm_inform_authmethod(char *); >+#endif >+ > struct passwd *mm_getpwnamallow(const char *); > char *mm_auth2_read_banner(void); > int mm_auth_password(struct Authctxt *, char *); >--- orig/monitor.c Thu Oct 23 11:49:50 2014 >+++ new/monitor.c Thu Oct 23 11:49:51 2014 >@@ -146,6 +146,9 @@ > int mm_answer_pwnamallow(int, Buffer *); > int mm_answer_auth2_read_banner(int, Buffer *); > int mm_answer_authserv(int, Buffer *); >+#ifdef PAM_ENHANCEMENT >+int mm_answer_authmethod(int, Buffer *); >+#endif > int mm_answer_authpassword(int, Buffer *); > int mm_answer_bsdauthquery(int, Buffer *); > int mm_answer_bsdauthrespond(int, Buffer *); >@@ -225,10 +228,17 @@ > {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, > {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, > {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, >+#ifdef PAM_ENHANCEMENT >+ {MONITOR_REQ_AUTHMETHOD, MON_ISAUTH, mm_answer_authmethod}, >+#endif > {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, > {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, > #ifdef USE_PAM >+#ifdef PAM_ENHANCEMENT >+ {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start}, >+#else > {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, >+#endif > {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, > {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, > {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, >@@ -385,12 +395,29 @@ > auth_method = "unknown"; > auth_submethod = NULL; > authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); >- > /* Special handling for multiple required authentications */ > if (options.num_auth_methods != 0) { > if (!compat20) > fatal("AuthenticationMethods is not supported" > "with SSH protocol 1"); >+ >+#if defined(USE_PAM) && defined(PAM_ENHANCEMENT) >+ /* >+ * If each userauth has its own PAM service, then PAM >+ * need to perform account check for this service. >+ */ >+ if (options.use_pam && authenticated && >+ options.pam_service_per_authmethod) { >+ Buffer m; >+ >+ buffer_init(&m); >+ mm_request_receive_expect(pmonitor->m_sendfd, >+ MONITOR_REQ_PAM_ACCOUNT, &m); >+ authenticated = >+ mm_answer_pam_account(pmonitor->m_sendfd, &m); >+ buffer_free(&m); >+ } >+#endif > if (authenticated && > !auth2_update_methods_lists(authctxt, > auth_method, auth_submethod)) { >@@ -399,6 +426,7 @@ > authenticated = 0; > partial = 1; > } >+ > } > > if (authenticated) { >@@ -409,8 +437,21 @@ > !auth_root_allowed(auth_method)) > authenticated = 0; > #ifdef USE_PAM >+#ifdef PAM_ENHANCEMENT >+ /* >+ * PAM needs to perform account checks after auth. >+ * However, if each userauth has its own PAM service >+ * and options.num_auth_methods != 0, then no need to >+ * perform account checking, because it was done >+ * already. >+ */ >+ if (options.use_pam && authenticated && >+ !(options.num_auth_methods != 0 && >+ options.pam_service_per_authmethod)) { >+#else > /* PAM needs to perform account checks after auth */ > if (options.use_pam && authenticated) { >+#endif > Buffer m; > > buffer_init(&m); >@@ -828,6 +869,10 @@ > /* Allow service/style information on the auth context */ > monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); > monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); >+#ifdef PAM_ENHANCEMENT >+ /* Allow authmethod information on the auth context */ >+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHMETHOD, 1); >+#endif > } > #ifdef USE_PAM > if (options.use_pam) >@@ -868,7 +913,28 @@ > return (0); > } > >+#ifdef PAM_ENHANCEMENT > int >+mm_answer_authmethod(int sock, Buffer *m) >+{ >+ monitor_permit_authentications(1); >+ >+ if (authctxt->authmethod_name != NULL) >+ free(authctxt->authmethod_name); >+ >+ authctxt->authmethod_name = buffer_get_string(m, NULL); >+ debug3("%s: authmethod_name=%s", __func__, authctxt->authmethod_name); >+ >+ if (strlen(authctxt->authmethod_name) == 0) { >+ free(authctxt->authmethod_name); >+ authctxt->authmethod_name = NULL; >+ } >+ >+ return (0); >+} >+#endif >+ >+int > mm_answer_authpassword(int sock, Buffer *m) > { > static int call_count; >--- orig/monitor.h Thu Oct 23 11:49:50 2014 >+++ new/monitor.h Thu Oct 23 11:49:51 2014 >@@ -70,6 +70,9 @@ > MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, > MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, > >+#ifdef PAM_ENHANCEMENT >+ MONITOR_REQ_AUTHMETHOD = 114, >+#endif > }; > > struct mm_master; >--- orig/servconf.c Thu Oct 23 11:49:50 2014 >+++ new/servconf.c Thu Oct 23 11:49:51 2014 >@@ -1,4 +1,3 @@ >- > /* $OpenBSD: servconf.c,v 1.248 2013/12/06 13:39:49 markus Exp $ */ > /* > * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland >@@ -154,6 +153,10 @@ > options->ip_qos_interactive = -1; > options->ip_qos_bulk = -1; > options->version_addendum = NULL; >+#ifdef PAM_ENHANCEMENT >+ options->pam_service_name = NULL; >+ options->pam_service_per_authmethod = 0; >+#endif > } > > void >@@ -351,6 +354,9 @@ > sKexAlgorithms, sIPQoS, sVersionAddendum, > sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, > sAuthenticationMethods, sHostKeyAgent, >+#ifdef PAM_ENHANCEMENT >+ sPAMServiceName, >+#endif > sDeprecated, sUnsupported > } ServerOpCodes; > >@@ -482,6 +488,9 @@ > { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, > { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, > { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, >+#ifdef PAM_ENHANCEMENT >+ { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL }, >+#endif > { NULL, sBadOption, 0 } > }; > >@@ -1632,6 +1641,46 @@ > } > return 0; > >+#ifdef PAM_ENHANCEMENT >+ case sPAMServiceName: >+ arg = strdelim(&cp); >+ if (!arg || *arg == '\0') >+ fatal("%s line %d: Missing argument.", >+ filename, linenum); >+ >+ if (options->pam_service_name == NULL) { >+ char *svc_ptr; >+ int len; >+ >+ svc_ptr = strstr(arg, "-%m"); >+ if (svc_ptr == NULL) { /* no "-%m" */ >+ options->pam_service_name = xstrdup(arg); >+ options->pam_service_per_authmethod = 0; >+ } else { >+ options->pam_service_per_authmethod = 1; >+ >+ if ((strlen(svc_ptr) == strlen(arg)) || >+ (strcmp(svc_ptr, "-%m") != 0)) { >+ /* >+ * have nothing before -%m or >+ * have something after -%m. >+ */ >+ fatal("%s line %d: " >+ "invalid PAMServiceName %s", >+ filename, linenum, arg); >+ } else { >+ len = svc_ptr - arg + 1; >+ options->pam_service_name = >+ xmalloc(len); >+ strlcpy(options->pam_service_name, arg, >+ len); >+ >+ } >+ } >+ } >+ break; >+#endif >+ > case sDeprecated: > logit("%s line %d: Deprecated option %s", > filename, linenum, arg); >--- orig/servconf.h Thu Oct 23 11:49:50 2014 >+++ new/servconf.h Thu Oct 23 11:49:51 2014 >@@ -185,6 +185,12 @@ > > u_int num_auth_methods; > char *auth_methods[MAX_AUTH_METHODS]; >+ >+#ifdef PAM_ENHANCEMENT >+ char *pam_service_name; /* for PAMServiceName option */ >+ int pam_service_per_authmethod; >+#endif >+ > } ServerOptions; > > /* Information about the incoming connection as used by Match */ >--- orig/sshd_config.5 Thu Oct 23 11:52:04 2014 >+++ new/sshd_config.5 Tue Oct 28 17:51:23 2014 >@@ -868,6 +868,55 @@ > are refused if the number of unauthenticated connections reaches > .Dq full > (60). >+.It Cm PAMServiceName >+Specifies the PAM service name for the PAM session. The valid arguments are "service_name" or "service_name-%m". >+.Pp >+1) PAMServiceName service_name >+.Pp >+Specifies the PAM service for all user authentications, where >+"service_name" is the PAM service name. For example, if >+"PAMServiceName mysshd" is specified, then "mysshd" is the >+PAM service name for all user authentications. >+.Pp >+2) PAMServiceName service_name-%m >+.Pp >+This option only applies to SSH protocol 2. >+.Pp >+With "-%m", each user authentication type has its own PAM service >+name. >+.Pp >+For example, if "PAMServiceName sshd-%m" is specified, then the >+PAM service name is expanded to sshd-pubkey for public key >+authentication, to sshd-kbdint for keyboard-interactive >+authentication, and so on. >+.Bd -literal -offset 5n >+ SSHv2 Userauth Expanded PAMServiceName >+ -------------- ----------------------- >+ none sshd-none >+ password sshd-password >+ keyboard-interactive sshd-kbdint >+ pubkey sshd-pubkey >+ hostbased sshd-hostbased >+ gssapi-with-mic sshd-gssapi >+.Ed >+.Pp >+If "PAMServiceName mysshd-%m" is specified, then the PAM service >+name is expanded to mysshd-pubkey for public key authentication, >+to mysshd-kbdint for keyboard-interactive authentication, and so >+on. >+.Bd -literal -offset 5n >+ SSHv2 Userauth Expanded PAMServiceName >+ -------------- ----------------------- >+ none mysshd-none >+ password mysshd-password >+ keyboard-interactive mysshd-kbdint >+ pubkey mysshd-pubkey >+ hostbased mysshd-hostbased >+ gssapi-with-mic mysshd-gssapi >+.Ed >+.Pp >+3) If "PAMServiceName service_name" or "PAMServiceName service_name-%m" is not >+specified, then "sshd" is the PAM service name for all user authentications. > .It Cm PasswordAuthentication > Specifies whether password authentication is allowed. > The default is >@@ -1203,8 +1252,7 @@ > is enabled, you will not be able to run > .Xr sshd 8 > as a non-root user. >-The default is >-.Dq no . >+On Solaris, the option is always enabled. > .It Cm UsePrivilegeSeparation > Specifies whether > .Xr sshd 8 >No differences encountered
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2246
:
2441
|
2504
|
2588