From: Graham Leggett Date: Sat, 27 Apr 2013 23:14:11 +0000 (+0000) Subject: mod_authnz_ldap: Allow using exec: callouts like SSLPassphraseDialog X-Git-Tag: 2.4.5~360 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a16ee712db2c19d99b778e7f734e008045c258c;p=apache mod_authnz_ldap: Allow using exec: callouts like SSLPassphraseDialog for AuthLDAPBindPassword. trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1433478 http://svn.apache.org/viewvc?view=revision&revision=1467523 http://svn.apache.org/viewvc?view=revision&revision=1467792 2.4.x patch: http://people.apache.org/~druggeri/patches/AuthLDAPBindPasswordExec-2.4.patch (20130119 - updated to include minor mmn bump) (20130412 - updated to not use static var - thx, wrowe) Submitted by: druggeri Reviewed by: jim, minfrin git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1476694 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 1dcde800e2..bb43fe5fe4 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.5 + *) mod_authnz_ldap: Allow using exec: calls to obtain LDAP bind + password. [Daniel Ruggeri] + *) Added balancer parameter failontimeout to allow server admin to configure an IO timeout as an error in the balancer. [Daniel Ruggeri] diff --git a/STATUS b/STATUS index 73d63497c5..dd3b1e86a7 100644 --- a/STATUS +++ b/STATUS @@ -90,16 +90,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_authnz_ldap: Allow using exec: callouts like SSLPassphraseDialog - for AuthLDAPBindPassword. - trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1433478 - http://svn.apache.org/viewvc?view=revision&revision=1467523 - http://svn.apache.org/viewvc?view=revision&revision=1467792 - 2.4.x patch: http://people.apache.org/~druggeri/patches/AuthLDAPBindPasswordExec-2.4.patch - (20130119 - updated to include minor mmn bump) - (20130412 - updated to not use static var - thx, wrowe) - +1: druggeri, jim, minfrin - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/docs/manual/mod/mod_authnz_ldap.xml b/docs/manual/mod/mod_authnz_ldap.xml index 67db78bc7d..95ef0554e6 100644 --- a/docs/manual/mod/mod_authnz_ldap.xml +++ b/docs/manual/mod/mod_authnz_ldap.xml @@ -911,6 +911,21 @@ to perform a DN lookup module="mod_authnz_ldap">AuthLDAPBindDN and AuthLDAPBindPassword if you absolutely need them to search the directory.

+ +

If the value begins with exec: the resulting command will be + executed and the first line returned to standard output by the + program will be used as the password.

+
+#Password used as-is
+AuthLDAPBindPassword secret
+
+#Run /path/to/program to get my password
+AuthLDAPBindPassword exec:/path/to/program
+
+#Run /path/to/otherProgram and provide arguments
+AuthLDAPBindPassword "exec:/path/to/otherProgram argument1"
+
+ diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 351808ac47..ef117aab27 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -401,7 +401,8 @@ * 20120211.9 (2.4.4-dev) Add fgrab() to ap_slotmem_provider_t. * 20120211.10 (2.4.4-dev) Add in bal_persist field to proxy_server_conf * 20120211.11 (2.4.4-dev) Add ap_bin2hex() - * 20120211.12 (2.4.5-dev) Add ap_remove_input|output_filter_byhandle() + * 20120211.12 (2.4.4-dev) Add ap_remove_input|output_filter_byhandle() + * 20120211.13 (2.4.4-dev) Add ap_get_exec_line */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -409,7 +410,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 12 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 13 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/httpd.h b/include/httpd.h index 43987435e9..24e4c0ddca 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -2218,6 +2218,18 @@ AP_DECLARE(void) ap_get_loadavg(ap_loadavg_t *ld); */ AP_DECLARE(void) ap_bin2hex(const void *src, apr_size_t srclen, char *dest); +/** + * Short function to execute a command and return the first line of + * output minus \r \n. Useful for "obscuring" passwords via exec calls + * @param p the pool to allocate from + * @param cmd the command to execute + * @param argv the arguments to pass to the cmd + * @return ptr to characters or NULL on any error + */ +AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p, + const char *cmd, + const char * const *argv); + #define AP_NORESTART APR_OS_START_USEERR + 1 #ifdef __cplusplus diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c index d55b57f5c8..b7b132e011 100644 --- a/modules/aaa/mod_authnz_ldap.c +++ b/modules/aaa/mod_authnz_ldap.c @@ -1531,6 +1531,43 @@ static const char *set_bind_pattern(cmd_parms *cmd, void *_cfg, const char *exp, return NULL; } +static const char *set_bind_password(cmd_parms *cmd, void *_cfg, const char *arg) +{ + authn_ldap_config_t *sec = _cfg; + int arglen = strlen(arg); + char **argv; + char *result; + + if ((arglen > 5) && strncmp(arg, "exec:", 5) == 0) { + if (apr_tokenize_to_argv(arg+5, &argv, cmd->temp_pool) != APR_SUCCESS) { + return apr_pstrcat(cmd->pool, + "Unable to parse exec arguments from ", + arg+5, NULL); + } + argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]); + + if (!argv[0]) { + return apr_pstrcat(cmd->pool, + "Invalid AuthLDAPBindPassword exec location:", + arg+5, NULL); + } + result = ap_get_exec_line(cmd->pool, + (const char*)argv[0], (const char * const *)argv); + + if(!result) { + return apr_pstrcat(cmd->pool, + "Unable to get bind password from exec of ", + arg+5, NULL); + } + sec->bindpw = result; + } + else { + sec->bindpw = (char *)arg; + } + + return NULL; +} + static const command_rec authnz_ldap_cmds[] = { AP_INIT_TAKE12("AuthLDAPURL", mod_auth_ldap_parse_url, NULL, OR_AUTHCFG, @@ -1561,8 +1598,7 @@ static const command_rec authnz_ldap_cmds[] = (void *)APR_OFFSETOF(authn_ldap_config_t, binddn), OR_AUTHCFG, "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."), - AP_INIT_TAKE1("AuthLDAPBindPassword", ap_set_string_slot, - (void *)APR_OFFSETOF(authn_ldap_config_t, bindpw), OR_AUTHCFG, + AP_INIT_TAKE1("AuthLDAPBindPassword", set_bind_password, NULL, OR_AUTHCFG, "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."), AP_INIT_FLAG("AuthLDAPBindAuthoritative", ap_set_flag_slot, diff --git a/server/util.c b/server/util.c index 87a7f29ce6..a643c863f3 100644 --- a/server/util.c +++ b/server/util.c @@ -2886,3 +2886,45 @@ AP_DECLARE(void) ap_get_loadavg(ap_loadavg_t *ld) } #endif } + +AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p, + const char *cmd, + const char * const * argv) +{ + char buf[MAX_STRING_LEN]; + apr_procattr_t *procattr; + apr_proc_t *proc; + apr_file_t *fp; + apr_size_t nbytes = 1; + char c; + int k; + + if (apr_procattr_create(&procattr, p) != APR_SUCCESS) + return NULL; + if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK, + APR_FULL_BLOCK) != APR_SUCCESS) + return NULL; + if (apr_procattr_dir_set(procattr, + ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS) + return NULL; + if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS) + return NULL; + proc = apr_pcalloc(p, sizeof(apr_proc_t)); + if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS) + return NULL; + fp = proc->out; + + if (fp == NULL) + return NULL; + /* XXX: we are reading 1 byte at a time here */ + for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS + && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) { + if (c == '\n' || c == '\r') + break; + buf[k++] = c; + } + buf[k] = '\0'; + apr_file_close(fp); + + return apr_pstrndup(p, buf, k); +}