From 023e47cb2f586b1b3a86341c88837e6d7ab45854 Mon Sep 17 00:00:00 2001 From: Daniel Ruggeri Date: Tue, 15 Jan 2013 16:00:44 +0000 Subject: [PATCH] Add helper function to execute command w args and get one line of output. Allow AuthLDAPBindPassword to have exec: argument like SSLPassPhraseDialog git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1433478 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/mod/mod_authnz_ldap.xml | 15 +++++++++++ include/httpd.h | 12 +++++++++ modules/aaa/mod_authnz_ldap.c | 40 +++++++++++++++++++++++++-- server/util.c | 42 +++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 2 deletions(-) diff --git a/docs/manual/mod/mod_authnz_ldap.xml b/docs/manual/mod/mod_authnz_ldap.xml index 5b90c7e9af..fdf5ecf85f 100644 --- a/docs/manual/mod/mod_authnz_ldap.xml +++ b/docs/manual/mod/mod_authnz_ldap.xml @@ -910,6 +910,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/httpd.h b/include/httpd.h index 8f5d4f109b..33b2d07800 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -2291,6 +2291,18 @@ AP_DECLARE(apr_status_t) ap_password_validate(request_rec *r, const char *passwd, const char *hash); +/** + * 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 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 6f02890481..4783f95de6 100644 --- a/server/util.c +++ b/server/util.c @@ -2936,3 +2936,45 @@ AP_DECLARE(apr_status_t) ap_password_validate(request_rec *r, cache->result = apr_password_validate(passwd, hash); return cache->result; } + +AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p, + const char *cmd, + const char * const * argv) +{ + static 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 buf; +} -- 2.40.0