From: Lubomir Rintel <lubo.rin...@gooddata.com> --- docs/manual/mod/mod_authnz_ldap.xml | 28 +++++++++++++++ docs/manual/style/scripts/prettify.js | 2 +- include/util_ldap.h | 4 ++- modules/aaa/mod_authnz_ldap.c | 16 +++++++-- modules/ldap/util_ldap.c | 67 +++++++++++++++++++++++++++++------ 5 files changed, 102 insertions(+), 15 deletions(-)
diff --git a/docs/manual/mod/mod_authnz_ldap.xml b/docs/manual/mod/mod_authnz_ldap.xml index 1a99079..264b447 100644 --- a/docs/manual/mod/mod_authnz_ldap.xml +++ b/docs/manual/mod/mod_authnz_ldap.xml @@ -191,6 +191,14 @@ for HTTP Basic authentication.</description> <td>An optional SASL mechanism to use for bind with during the search phase.</td> </tr> + + <tr> + <td><directive + module="mod_authnz_ldap">AuthLDAPBindSASLInteract</directive></td> + + <td>An optional command to run when SASL + requests interaction to obtain credentials.</td> + </tr> </table> </section> @@ -973,6 +981,26 @@ AuthLDAPBindSASLMech "GSSAPI" </directivesynopsis> <directivesynopsis> +<name>AuthLDAPBindSASLInteract</name> +<description>Optional command to run when SASL requests interaction to obtain credentials</description> +<syntax>AuthLDAPBindSASLInteract <em>command</em></syntax> +<contextlist><context>directory</context><context>.htaccess</context> +</contextlist> +<override>AuthConfig</override> + +<usage> + <p>An optional command to run when SASL + requests interaction to obtain credentials.</p> + +<example><pre> +#Initialize Kerberos Credentials Cache using a key from a keytab for given principal +AuthLDAPBindSASLInteract "/usr/bin/kinit -k -t /etc/httpd/conf/krb5.keytab host/example.com" +</pre></example> + +</usage> +</directivesynopsis> + +<directivesynopsis> <name>AuthLDAPCharsetConfig</name> <description>Language to charset conversion configuration file</description> <syntax>AuthLDAPCharsetConfig <em>file-path</em></syntax> diff --git a/docs/manual/style/scripts/prettify.js b/docs/manual/style/scripts/prettify.js index f1ab2e6..5777258 100644 --- a/docs/manual/style/scripts/prettify.js +++ b/docs/manual/style/scripts/prettify.js @@ -132,7 +132,7 @@ var prettyPrint; var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," + "function,in,local,set,then,until,echo"]; var CONFIG_ENVS = ["User-Agent,HTTP_USER_AGENT,HTTP_REFERER,HTTP_COOKIE,HTTP_FORWARDED,HTTP_HOST,HTTP_PROXY_CONNECTION,HTTP_ACCEPT,REMOTE_ADDR,REMOTE_HOST,REMOTE_PORT,REMOTE_USER,REMOTE_IDENT,REQUEST_METHOD,SCRIPT_FILENAME,PATH_INFO,QUERY_STRING,AUTH_TYPE,DOCUMENT_ROOT,SERVER_ADMIN,SERVER_NAME,SERVER_ADDR,SERVER_PORT,SERVER_PROTOCOL,SERVER_SOFTWARE,TIME_YEAR,TIME_MON,TIME_DAY,TIME_HOUR,TIME_MIN,TIME_SEC,TIME_WDAY,TIME,API_VERSION,THE_REQUEST,REQUEST_URI,REQUEST_FILENAME,IS_SUBREQ,HTTPS,REQUEST_SCHEME"]; - var CONFIG_KEYWORDS = ["Macro,UndefMacro,Use,AuthLDAPURL,AcceptFilter,AcceptPathInfo,AccessFileName,Action,AddAlt,AddAltByEncoding,AddAltByType,AddCharset,AddDefaultCharset,AddDescription,AddEncoding,AddHandler,AddIcon,AddIconByEncoding,AddIconByType,AddInputFilter,AddLanguage,AddModuleInfo,AddOutputFilter,AddOutputFilterByType,AddType,Alias,AliasMatch,Allow,AllowCONNECT,AllowEncodedSlashes,AllowMethods,AllowOverride,AllowOverrideList,Anonymous,Anonymous_LogEmail,Anonymous_MustGiveEmail,Anonymous_NoUserID,Anonymous_VerifyEmail,AsyncRequestWorkerFactor,AuthBasicAuthoritative,AuthBasicProvider,AuthDBDUserPWQuery,AuthDBDUserRealmQuery,AuthDBMGroupFile,AuthDBMType,AuthDBMUserFile,AuthDigestAlgorithm,AuthDigestDomain,AuthDigestNcCheck,AuthDigestNonceFormat,AuthDigestNonceLifetime,AuthDigestProvider,AuthDigestQop,AuthDigestShmemSize,AuthFormAuthoritative,AuthFormBody,AuthFormDisableNoStore,AuthFormFakeBasicAuth,AuthFormLocation,AuthFormLoginRequiredLocation,AuthFormLoginSuccessLocation, AuthFormLogoutLocation,AuthFormMethod,AuthFormMimetype,AuthFormPassword,AuthFormProvider,AuthFormSitePassphrase,AuthFormSize,AuthFormUsername,AuthGroupFile,AuthLDAPAuthorizePrefix,AuthLDAPBindAuthoritative,AuthLDAPBindDN,AuthLDAPBindPassword,AuthLDAPBindSASLMech,AuthLDAPCharsetConfig,AuthLDAPCompareAsUser,AuthLDAPCompareDNOnServer,AuthLDAPDereferenceAliases,AuthLDAPGroupAttribute,AuthLDAPGroupAttributeIsDN,AuthLDAPInitialBindAsUser,AuthLDAPInitialBindPattern,AuthLDAPMaxSubGroupDepth,AuthLDAPRemoteUserAttribute,AuthLDAPRemoteUserIsDN,AuthLDAPSearchAsUser,AuthLDAPSubGroupAttribute,AuthLDAPSubGroupClass,AuthLDAPUrl,AuthMerging,AuthName,AuthnCacheContext,AuthnCacheEnable,AuthnCacheProvideFor,AuthnCacheSOCache,AuthnCacheTimeout,<AuthnProviderAlias>,AuthType,AuthUserFile,AuthzDBDLoginToReferer,AuthzDBDQuery,AuthzDBDRedirectQuery,AuthzDBMType,<AuthzProviderAlias>,AuthzSendForbiddenOnFailure,BalancerGrowth,BalancerMember,BrowserMatch,BrowserMatchNoCase,BufferedLogs,BufferSize,CacheDefaultEx pire,CacheDetailHeader,CacheDirLength,CacheDirLevels,CacheDisable,CacheEnable,CacheFile,CacheHeader,CacheIgnoreCacheControl,CacheIgnoreHeaders,CacheIgnoreNoLastMod,CacheIgnoreQueryString,CacheIgnoreURLSessionIdentifiers,CacheKeyBaseURL,CacheLastModifiedFactor,CacheLock,CacheLockMaxAge,CacheLockPath,CacheMaxExpire,CacheMaxFileSize,CacheMinExpire,CacheMinFileSize,CacheNegotiatedDocs,CacheQuickHandler,CacheReadSize,CacheReadTime,CacheRoot,CacheStaleOnError,CacheStoreExpired,CacheStoreNoStore,CacheStorePrivate,CGIMapExtension,CharsetDefault,CharsetOptions,CharsetSourceEnc,CheckCaseOnly,CheckSpelling,ChrootDir,ContentDigest,CookieDomain,CookieExpires,CookieName,CookieStyle,CookieTracking,CoreDumpDirectory,CustomLog,Dav,DavDepthInfinity,DavGenericLockDB,DavLockDB,DavMinTimeout,DBDExptime,DBDInitSQL,DBDKeep,DBDMax,DBDMin,DBDParams,DBDPersist,DBDPrepareSQL,DBDriver,DefaultIcon,DefaultLanguage,DefaultRuntimeDir,DefaultType,Define,DeflateBufferSize,DeflateCompressionLevel,DeflateFilterNote,De flateMemLevel,DeflateWindowSize,Deny,<Directory>,DirectoryIndex,DirectoryIndexRedirect,<DirectoryMatch>,DirectorySlash,DocumentRoot,DTracePrivileges,DumpIOInput,DumpIOOutput,<Else>,<ElseIf>,EnableExceptionHook,EnableMMAP,EnableSendfile,Error,ErrorDocument,ErrorLog,ErrorLogFormat,Example,ExpiresActive,ExpiresByType,ExpiresDefault,ExtendedStatus,ExtFilterDefine,ExtFilterOptions,FallbackResource,FileETag,<Files>,<FilesMatch>,FilterChain,FilterDeclare,FilterProtocol,FilterProvider,FilterTrace,ForceLanguagePriority,ForceType,ForensicLog,GprofDir,GracefulShutdownTimeout,Group,Header,HeaderName,HeartbeatAddress,HeartbeatListen,HeartbeatMaxServers,HeartbeatStorage,HeartbeatStorage,HostnameLookups,IdentityCheck,IdentityCheckTimeout,<If>,<IfDefine>,<IfModule>,<IfVersion>,ImapBase,ImapDefault,ImapMenu,Include,IncludeOptional,IndexHeadInsert,IndexIgnore,IndexIgnoreReset,IndexOptions,IndexOrderDefault,IndexStyleSheet,InputSed,ISAPIAppendLogToErrors,ISAPIAppendLogToQuery,ISAPICacheFile,ISAPIFakeA sync,ISAPILogNotSupported,ISAPIReadAheadBuffer,KeepAlive,KeepAliveTimeout,KeptBodySize,LanguagePriority,LDAPCacheEntries,LDAPCacheTTL,LDAPConnectionPoolTTL,LDAPConnectionTimeout,LDAPLibraryDebug,LDAPOpCacheEntries,LDAPOpCacheTTL,LDAPReferralHopLimit,LDAPReferrals,LDAPRetries,LDAPRetryDelay,LDAPSharedCacheFile,LDAPSharedCacheSize,LDAPTimeout,LDAPTrustedClientCert,LDAPTrustedGlobalCert,LDAPTrustedMode,LDAPVerifyServerCert,<Limit>,<LimitExcept>,LimitInternalRecursion,LimitRequestBody,LimitRequestFields,LimitRequestFieldSize,LimitRequestLine,LimitXMLRequestBody,Listen,ListenBackLog,LoadFile,LoadModule,<Location>,<LocationMatch>,LogFormat,LogLevel,LogMessage,LuaCodeCache,LuaHookAccessChecker,LuaHookAuthChecker,LuaAuthzProvider,LuaHookCheckUserID,LuaHookFixups,LuaHookInsertFilter,LuaHookMapToStorage,LuaHookTranslateName,LuaHookTypeChecker,LuaInherit,LuaInputFilter,LuaMapHandler,LuaOutputFilter,LuaPackageCPath,LuaPackagePath,LuaQuickHandler,LuaRoot,LuaScope,MaxConnectionsPerChild,MaxKeepAl iveRequests,MaxMemFree,MaxRangeOverlaps,MaxRangeReversals,MaxRanges,MaxRequestWorkers,MaxSpareServers,MaxSpareThreads,MaxThreads,MetaDir,MetaFiles,MetaSuffix,MimeMagicFile,MinSpareServers,MinSpareThreads,MMapFile,ModemStandard,ModMimeUsePathInfo,MultiviewsMatch,Mutex,NameVirtualHost,NoProxy,NWSSLTrustedCerts,NWSSLUpgradeable,Options,Order,OutputSed,PassEnv,PidFile,PrivilegesMode,Protocol,ProtocolEcho,<Proxy>,ProxyAddHeaders,ProxyBadHeader,ProxyBlock,ProxyDomain,ProxyErrorOverride,ProxyExpressDBMFile,ProxyExpressDBMType,ProxyExpressEnable,ProxyFtpDirCharset,ProxyFtpEscapeWildcards,ProxyFtpListOnWildcard,ProxyHTMLBufSize,ProxyHTMLCharsetOut,ProxyHTMLDocType,ProxyHTMLEnable,ProxyHTMLEvents,ProxyHTMLExtended,ProxyHTMLFixups,ProxyHTMLInterp,ProxyHTMLLinks,ProxyHTMLStripComments,ProxyHTMLURLMap,ProxyIOBufferSize,<ProxyMatch>,ProxyMaxForwards,ProxyPass,ProxyPassInterpolateEnv,ProxyPassMatch,ProxyPassReverse,ProxyPassReverseCookieDomain,ProxyPassReverseCookiePath,ProxyPreserveHost,ProxyRece iveBufferSize,ProxyRemote,ProxyRemoteMatch,ProxyRequests,ProxySCGIInternalRedirect,ProxySCGISendfile,ProxySet,ProxySourceAddress,ProxyStatus,ProxyTimeout,ProxyVia,ReadmeName,ReceiveBufferSize,Redirect,RedirectMatch,RedirectPermanent,RedirectTemp,ReflectorHeader,RemoteIPHeader,RemoteIPInternalProxy,RemoteIPInternalProxyList,RemoteIPProxiesHeader,RemoteIPTrustedProxy,RemoteIPTrustedProxyList,RemoveCharset,RemoveEncoding,RemoveHandler,RemoveInputFilter,RemoveLanguage,RemoveOutputFilter,RemoveType,RequestHeader,RequestReadTimeout,Require,<RequireAll>,<RequireAny>,<RequireNone>,RewriteBase,RewriteCond,RewriteEngine,RewriteMap,RewriteOptions,RewriteRule,RLimitCPU,RLimitMEM,RLimitNPROC,Satisfy,ScoreBoardFile,Script,ScriptAlias,ScriptAliasMatch,ScriptInterpreterSource,ScriptLog,ScriptLogBuffer,ScriptLogLength,ScriptSock,SecureListen,SeeRequestTail,SendBufferSize,ServerAdmin,ServerAlias,ServerLimit,ServerName,ServerPath,ServerRoot,ServerSignature,ServerTokens,Session,SessionCookieName,Sessio nCookieName2,SessionCookieRemove,SessionCryptoCipher,SessionCryptoDriver,SessionCryptoPassphrase,SessionCryptoPassphraseFile,SessionDBDCookieName,SessionDBDCookieName2,SessionDBDCookieRemove,SessionDBDDeleteLabel,SessionDBDInsertLabel,SessionDBDPerUser,SessionDBDSelectLabel,SessionDBDUpdateLabel,SessionEnv,SessionExclude,SessionHeader,SessionInclude,SessionMaxAge,SetEnv,SetEnvIf,SetEnvIfExpr,SetEnvIfNoCase,SetHandler,SetInputFilter,SetOutputFilter,SSIEndTag,SSIErrorMsg,SSIETag,SSILastModified,SSILegacyExprParser,SSIStartTag,SSITimeFormat,SSIUndefinedEcho,SSLCACertificateFile,SSLCACertificatePath,SSLCADNRequestFile,SSLCADNRequestPath,SSLCARevocationCheck,SSLCARevocationFile,SSLCARevocationPath,SSLCertificateChainFile,SSLCertificateFile,SSLCertificateKeyFile,SSLCipherSuite,SSLCryptoDevice,SSLEngine,SSLFIPS,SSLHonorCipherOrder,SSLInsecureRenegotiation,SSLOCSPDefaultResponder,SSLOCSPEnable,SSLOCSPOverrideResponder,SSLOCSPResponderTimeout,SSLOCSPResponseMaxAge,SSLOCSPResponseTimeSkew,SSL Options,SSLPassPhraseDialog,SSLProtocol,SSLProxyCACertificateFile,SSLProxyCACertificatePath,SSLProxyCARevocationCheck,SSLProxyCARevocationFile,SSLProxyCARevocationPath,SSLProxyCheckPeerCN,SSLProxyCheckPeerExpire,SSLProxyCipherSuite,SSLProxyEngine,SSLProxyMachineCertificateChainFile,SSLProxyMachineCertificateFile,SSLProxyMachineCertificatePath,SSLProxyProtocol,SSLProxyVerify,SSLProxyVerifyDepth,SSLRandomSeed,SSLRenegBufferSize,SSLRequire,SSLRequireSSL,SSLSessionCache,SSLSessionCacheTimeout,SSLSessionTicketKeyFile,SSLStaplingCache,SSLStaplingErrorCacheTimeout,SSLStaplingFakeTryLater,SSLStaplingForceURL,SSLStaplingResponderTimeout,SSLStaplingResponseMaxAge,SSLStaplingResponseTimeSkew,SSLStaplingReturnResponderErrors,SSLStaplingStandardCacheTimeout,SSLStrictSNIVHostCheck,SSLUserName,SSLUseStapling,SSLVerifyClient,SSLVerifyDepth,StartServers,StartThreads,Substitute,Suexec,SuexecUserGroup,ThreadLimit,ThreadsPerChild,ThreadStackSize,TimeOut,TraceEnable,TransferLog,TypesConfig,UnDefine,Unse tEnv,UseCanonicalName,UseCanonicalPhysicalPort,User,UserDir,VHostCGIMode,VHostCGIPrivs,VHostGroup,VHostPrivs,VHostSecure,VHostUser,VirtualDocumentRoot,VirtualDocumentRootIP,<VirtualHost>,VirtualScriptAlias,VirtualScriptAliasIP,WatchdogInterval,XBitHack,xml2EncAlias,xml2EncDefault,xml2StartParse,RewriteLog,RewriteLogLevel"]; + var CONFIG_KEYWORDS = ["Macro,UndefMacro,Use,AuthLDAPURL,AcceptFilter,AcceptPathInfo,AccessFileName,Action,AddAlt,AddAltByEncoding,AddAltByType,AddCharset,AddDefaultCharset,AddDescription,AddEncoding,AddHandler,AddIcon,AddIconByEncoding,AddIconByType,AddInputFilter,AddLanguage,AddModuleInfo,AddOutputFilter,AddOutputFilterByType,AddType,Alias,AliasMatch,Allow,AllowCONNECT,AllowEncodedSlashes,AllowMethods,AllowOverride,AllowOverrideList,Anonymous,Anonymous_LogEmail,Anonymous_MustGiveEmail,Anonymous_NoUserID,Anonymous_VerifyEmail,AsyncRequestWorkerFactor,AuthBasicAuthoritative,AuthBasicProvider,AuthDBDUserPWQuery,AuthDBDUserRealmQuery,AuthDBMGroupFile,AuthDBMType,AuthDBMUserFile,AuthDigestAlgorithm,AuthDigestDomain,AuthDigestNcCheck,AuthDigestNonceFormat,AuthDigestNonceLifetime,AuthDigestProvider,AuthDigestQop,AuthDigestShmemSize,AuthFormAuthoritative,AuthFormBody,AuthFormDisableNoStore,AuthFormFakeBasicAuth,AuthFormLocation,AuthFormLoginRequiredLocation,AuthFormLoginSuccessLocation, AuthFormLogoutLocation,AuthFormMethod,AuthFormMimetype,AuthFormPassword,AuthFormProvider,AuthFormSitePassphrase,AuthFormSize,AuthFormUsername,AuthGroupFile,AuthLDAPAuthorizePrefix,AuthLDAPBindAuthoritative,AuthLDAPBindDN,AuthLDAPBindPassword,AuthLDAPBindSASLMech,AuthLDAPBindSASLInteract,AuthLDAPCharsetConfig,AuthLDAPCompareAsUser,AuthLDAPCompareDNOnServer,AuthLDAPDereferenceAliases,AuthLDAPGroupAttribute,AuthLDAPGroupAttributeIsDN,AuthLDAPInitialBindAsUser,AuthLDAPInitialBindPattern,AuthLDAPMaxSubGroupDepth,AuthLDAPRemoteUserAttribute,AuthLDAPRemoteUserIsDN,AuthLDAPSearchAsUser,AuthLDAPSubGroupAttribute,AuthLDAPSubGroupClass,AuthLDAPUrl,AuthMerging,AuthName,AuthnCacheContext,AuthnCacheEnable,AuthnCacheProvideFor,AuthnCacheSOCache,AuthnCacheTimeout,<AuthnProviderAlias>,AuthType,AuthUserFile,AuthzDBDLoginToReferer,AuthzDBDQuery,AuthzDBDRedirectQuery,AuthzDBMType,<AuthzProviderAlias>,AuthzSendForbiddenOnFailure,BalancerGrowth,BalancerMember,BrowserMatch,BrowserMatchNoCase,BufferedLogs, BufferSize,CacheDefaultExpire,CacheDetailHeader,CacheDirLength,CacheDirLevels,CacheDisable,CacheEnable,CacheFile,CacheHeader,CacheIgnoreCacheControl,CacheIgnoreHeaders,CacheIgnoreNoLastMod,CacheIgnoreQueryString,CacheIgnoreURLSessionIdentifiers,CacheKeyBaseURL,CacheLastModifiedFactor,CacheLock,CacheLockMaxAge,CacheLockPath,CacheMaxExpire,CacheMaxFileSize,CacheMinExpire,CacheMinFileSize,CacheNegotiatedDocs,CacheQuickHandler,CacheReadSize,CacheReadTime,CacheRoot,CacheStaleOnError,CacheStoreExpired,CacheStoreNoStore,CacheStorePrivate,CGIMapExtension,CharsetDefault,CharsetOptions,CharsetSourceEnc,CheckCaseOnly,CheckSpelling,ChrootDir,ContentDigest,CookieDomain,CookieExpires,CookieName,CookieStyle,CookieTracking,CoreDumpDirectory,CustomLog,Dav,DavDepthInfinity,DavGenericLockDB,DavLockDB,DavMinTimeout,DBDExptime,DBDInitSQL,DBDKeep,DBDMax,DBDMin,DBDParams,DBDPersist,DBDPrepareSQL,DBDriver,DefaultIcon,DefaultLanguage,DefaultRuntimeDir,DefaultType,Define,DeflateBufferSize,DeflateCompressionL evel,DeflateFilterNote,DeflateMemLevel,DeflateWindowSize,Deny,<Directory>,DirectoryIndex,DirectoryIndexRedirect,<DirectoryMatch>,DirectorySlash,DocumentRoot,DTracePrivileges,DumpIOInput,DumpIOOutput,<Else>,<ElseIf>,EnableExceptionHook,EnableMMAP,EnableSendfile,Error,ErrorDocument,ErrorLog,ErrorLogFormat,Example,ExpiresActive,ExpiresByType,ExpiresDefault,ExtendedStatus,ExtFilterDefine,ExtFilterOptions,FallbackResource,FileETag,<Files>,<FilesMatch>,FilterChain,FilterDeclare,FilterProtocol,FilterProvider,FilterTrace,ForceLanguagePriority,ForceType,ForensicLog,GprofDir,GracefulShutdownTimeout,Group,Header,HeaderName,HeartbeatAddress,HeartbeatListen,HeartbeatMaxServers,HeartbeatStorage,HeartbeatStorage,HostnameLookups,IdentityCheck,IdentityCheckTimeout,<If>,<IfDefine>,<IfModule>,<IfVersion>,ImapBase,ImapDefault,ImapMenu,Include,IncludeOptional,IndexHeadInsert,IndexIgnore,IndexIgnoreReset,IndexOptions,IndexOrderDefault,IndexStyleSheet,InputSed,ISAPIAppendLogToErrors,ISAPIAppendLogToQuery, ISAPICacheFile,ISAPIFakeAsync,ISAPILogNotSupported,ISAPIReadAheadBuffer,KeepAlive,KeepAliveTimeout,KeptBodySize,LanguagePriority,LDAPCacheEntries,LDAPCacheTTL,LDAPConnectionPoolTTL,LDAPConnectionTimeout,LDAPLibraryDebug,LDAPOpCacheEntries,LDAPOpCacheTTL,LDAPReferralHopLimit,LDAPReferrals,LDAPRetries,LDAPRetryDelay,LDAPSharedCacheFile,LDAPSharedCacheSize,LDAPTimeout,LDAPTrustedClientCert,LDAPTrustedGlobalCert,LDAPTrustedMode,LDAPVerifyServerCert,<Limit>,<LimitExcept>,LimitInternalRecursion,LimitRequestBody,LimitRequestFields,LimitRequestFieldSize,LimitRequestLine,LimitXMLRequestBody,Listen,ListenBackLog,LoadFile,LoadModule,<Location>,<LocationMatch>,LogFormat,LogLevel,LogMessage,LuaCodeCache,LuaHookAccessChecker,LuaHookAuthChecker,LuaAuthzProvider,LuaHookCheckUserID,LuaHookFixups,LuaHookInsertFilter,LuaHookMapToStorage,LuaHookTranslateName,LuaHookTypeChecker,LuaInherit,LuaInputFilter,LuaMapHandler,LuaOutputFilter,LuaPackageCPath,LuaPackagePath,LuaQuickHandler,LuaRoot,LuaScope,MaxConn ectionsPerChild,MaxKeepAliveRequests,MaxMemFree,MaxRangeOverlaps,MaxRangeReversals,MaxRanges,MaxRequestWorkers,MaxSpareServers,MaxSpareThreads,MaxThreads,MetaDir,MetaFiles,MetaSuffix,MimeMagicFile,MinSpareServers,MinSpareThreads,MMapFile,ModemStandard,ModMimeUsePathInfo,MultiviewsMatch,Mutex,NameVirtualHost,NoProxy,NWSSLTrustedCerts,NWSSLUpgradeable,Options,Order,OutputSed,PassEnv,PidFile,PrivilegesMode,Protocol,ProtocolEcho,<Proxy>,ProxyAddHeaders,ProxyBadHeader,ProxyBlock,ProxyDomain,ProxyErrorOverride,ProxyExpressDBMFile,ProxyExpressDBMType,ProxyExpressEnable,ProxyFtpDirCharset,ProxyFtpEscapeWildcards,ProxyFtpListOnWildcard,ProxyHTMLBufSize,ProxyHTMLCharsetOut,ProxyHTMLDocType,ProxyHTMLEnable,ProxyHTMLEvents,ProxyHTMLExtended,ProxyHTMLFixups,ProxyHTMLInterp,ProxyHTMLLinks,ProxyHTMLStripComments,ProxyHTMLURLMap,ProxyIOBufferSize,<ProxyMatch>,ProxyMaxForwards,ProxyPass,ProxyPassInterpolateEnv,ProxyPassMatch,ProxyPassReverse,ProxyPassReverseCookieDomain,ProxyPassReverseCookiePath,Pr oxyPreserveHost,ProxyReceiveBufferSize,ProxyRemote,ProxyRemoteMatch,ProxyRequests,ProxySCGIInternalRedirect,ProxySCGISendfile,ProxySet,ProxySourceAddress,ProxyStatus,ProxyTimeout,ProxyVia,ReadmeName,ReceiveBufferSize,Redirect,RedirectMatch,RedirectPermanent,RedirectTemp,ReflectorHeader,RemoteIPHeader,RemoteIPInternalProxy,RemoteIPInternalProxyList,RemoteIPProxiesHeader,RemoteIPTrustedProxy,RemoteIPTrustedProxyList,RemoveCharset,RemoveEncoding,RemoveHandler,RemoveInputFilter,RemoveLanguage,RemoveOutputFilter,RemoveType,RequestHeader,RequestReadTimeout,Require,<RequireAll>,<RequireAny>,<RequireNone>,RewriteBase,RewriteCond,RewriteEngine,RewriteMap,RewriteOptions,RewriteRule,RLimitCPU,RLimitMEM,RLimitNPROC,Satisfy,ScoreBoardFile,Script,ScriptAlias,ScriptAliasMatch,ScriptInterpreterSource,ScriptLog,ScriptLogBuffer,ScriptLogLength,ScriptSock,SecureListen,SeeRequestTail,SendBufferSize,ServerAdmin,ServerAlias,ServerLimit,ServerName,ServerPath,ServerRoot,ServerSignature,ServerTokens,Session ,SessionCookieName,SessionCookieName2,SessionCookieRemove,SessionCryptoCipher,SessionCryptoDriver,SessionCryptoPassphrase,SessionCryptoPassphraseFile,SessionDBDCookieName,SessionDBDCookieName2,SessionDBDCookieRemove,SessionDBDDeleteLabel,SessionDBDInsertLabel,SessionDBDPerUser,SessionDBDSelectLabel,SessionDBDUpdateLabel,SessionEnv,SessionExclude,SessionHeader,SessionInclude,SessionMaxAge,SetEnv,SetEnvIf,SetEnvIfExpr,SetEnvIfNoCase,SetHandler,SetInputFilter,SetOutputFilter,SSIEndTag,SSIErrorMsg,SSIETag,SSILastModified,SSILegacyExprParser,SSIStartTag,SSITimeFormat,SSIUndefinedEcho,SSLCACertificateFile,SSLCACertificatePath,SSLCADNRequestFile,SSLCADNRequestPath,SSLCARevocationCheck,SSLCARevocationFile,SSLCARevocationPath,SSLCertificateChainFile,SSLCertificateFile,SSLCertificateKeyFile,SSLCipherSuite,SSLCryptoDevice,SSLEngine,SSLFIPS,SSLHonorCipherOrder,SSLInsecureRenegotiation,SSLOCSPDefaultResponder,SSLOCSPEnable,SSLOCSPOverrideResponder,SSLOCSPResponderTimeout,SSLOCSPResponseMaxAge,SS LOCSPResponseTimeSkew,SSLOptions,SSLPassPhraseDialog,SSLProtocol,SSLProxyCACertificateFile,SSLProxyCACertificatePath,SSLProxyCARevocationCheck,SSLProxyCARevocationFile,SSLProxyCARevocationPath,SSLProxyCheckPeerCN,SSLProxyCheckPeerExpire,SSLProxyCipherSuite,SSLProxyEngine,SSLProxyMachineCertificateChainFile,SSLProxyMachineCertificateFile,SSLProxyMachineCertificatePath,SSLProxyProtocol,SSLProxyVerify,SSLProxyVerifyDepth,SSLRandomSeed,SSLRenegBufferSize,SSLRequire,SSLRequireSSL,SSLSessionCache,SSLSessionCacheTimeout,SSLSessionTicketKeyFile,SSLStaplingCache,SSLStaplingErrorCacheTimeout,SSLStaplingFakeTryLater,SSLStaplingForceURL,SSLStaplingResponderTimeout,SSLStaplingResponseMaxAge,SSLStaplingResponseTimeSkew,SSLStaplingReturnResponderErrors,SSLStaplingStandardCacheTimeout,SSLStrictSNIVHostCheck,SSLUserName,SSLUseStapling,SSLVerifyClient,SSLVerifyDepth,StartServers,StartThreads,Substitute,Suexec,SuexecUserGroup,ThreadLimit,ThreadsPerChild,ThreadStackSize,TimeOut,TraceEnable,TransferLog, TypesConfig,UnDefine,UnsetEnv,UseCanonicalName,UseCanonicalPhysicalPort,User,UserDir,VHostCGIMode,VHostCGIPrivs,VHostGroup,VHostPrivs,VHostSecure,VHostUser,VirtualDocumentRoot,VirtualDocumentRootIP,<VirtualHost>,VirtualScriptAlias,VirtualScriptAliasIP,WatchdogInterval,XBitHack,xml2EncAlias,xml2EncDefault,xml2StartParse,RewriteLog,RewriteLogLevel"]; var CONFIG_OPTIONS = /^[\\+\\-]?(AuthConfig|IncludesNOEXEC|ExecCGI|FollowSymLinks|MultiViews|Includes|Indexes|SymLinksIfOwnerMatch)\b/i; var ALL_KEYWORDS = [ CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS + diff --git a/include/util_ldap.h b/include/util_ldap.h index 05de641..b708a1e 100644 --- a/include/util_ldap.h +++ b/include/util_ldap.h @@ -118,6 +118,7 @@ typedef struct util_ldap_connection_t { const char *binddn; /* DN to bind to server (can be NULL) */ const char *bindpw; /* Password to bind to server (can be NULL) */ const char *bindsaslmech; /* SASL Mechanism to use for server bind (can be NULL) */ + char *bindsaslinteract; /* Command to run when SASL requests interaction to obtain credentials (can be NULL) */ int bound; /* Flag to indicate whether this connection is bound yet */ @@ -243,7 +244,8 @@ APR_DECLARE_OPTIONAL_FN(apr_status_t,uldap_connection_unbind,(void *param)); * int netscapessl, int starttls) */ APR_DECLARE_OPTIONAL_FN(util_ldap_connection_t *,uldap_connection_find,(request_rec *r, const char *host, int port, - const char *binddn, const char *bindpw, const char *bindsaslmech, + const char *binddn, const char *bindpw, + const char *bindsaslmech, const char *bindsaslinteract, deref_options deref, int secure)); /** diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c index fe0ec85..d491ac7 100644 --- a/modules/aaa/mod_authnz_ldap.c +++ b/modules/aaa/mod_authnz_ldap.c @@ -60,6 +60,7 @@ typedef struct { char *binddn; /* DN to bind to server (can be NULL) */ char *bindpw; /* Password to bind to server (can be NULL) */ char *bindsaslmech; /* SASL Mechanism to use for server bind (can be NULL) */ + char *bindsaslinteract; /* Command to run when SASL requests interaction to obtain credentials. */ int bind_authoritative; /* If true, will return errors when bind fails */ int user_is_dn; /* If true, r->user is replaced by DN during authn */ @@ -346,6 +347,7 @@ static void *create_authnz_ldap_dir_config(apr_pool_t *p, char *d) sec->binddn = NULL; sec->bindpw = NULL; sec->bindsaslmech = NULL; + sec->bindsaslinteract = NULL; sec->bind_authoritative = 1; sec->deref = always; sec->group_attrib_is_dn = 1; @@ -442,6 +444,7 @@ static util_ldap_connection_t *get_connection_for_authz(request_rec *r, enum aut char *binddn = sec->binddn; char *bindpw = sec->bindpw; char *bindsaslmech = sec->bindsaslmech; + char *bindsaslinteract = sec->bindsaslinteract; /* If the per-request config isn't set, we didn't authenticate this user, and leave the default credentials */ if (req && req->password && @@ -451,10 +454,12 @@ static util_ldap_connection_t *get_connection_for_authz(request_rec *r, enum aut binddn = req->dn; bindpw = req->password; bindsaslmech = NULL; + bindsaslinteract = NULL; } return util_ldap_connection_find(r, sec->host, sec->port, - binddn, bindpw, bindsaslmech, + binddn, bindpw, + bindsaslmech, bindsaslinteract, sec->deref, sec->secure); } /* @@ -505,14 +510,17 @@ static authn_status authn_ldap_check_password(request_rec *r, const char *user, const char *binddn = sec->binddn; const char *bindpw = sec->bindpw; const char *bindsaslmech = sec->bindsaslmech; + const char *bindsaslinteract = sec->bindsaslinteract; if (sec->initial_bind_as_user) { bindpw = password; binddn = ldap_determine_binddn(r, user); bindsaslmech = NULL; + bindsaslinteract = NULL; } ldc = util_ldap_connection_find(r, sec->host, sec->port, - binddn, bindpw, bindsaslmech, + binddn, bindpw, + bindsaslmech, bindsaslinteract, sec->deref, sec->secure); } else { @@ -1715,6 +1723,10 @@ static const command_rec authnz_ldap_cmds[] = (void *)APR_OFFSETOF(authn_ldap_config_t, bindsaslmech), OR_AUTHCFG, "SASL Mechanism to use to bind to LDAP server. If not provided, simple authentication will be done."), + AP_INIT_TAKE1("AuthLDAPBindSASLInteract", ap_set_string_slot, + (void *)APR_OFFSETOF(authn_ldap_config_t, bindsaslinteract), OR_AUTHCFG, + "Command to run when SASL requests interaction to obtain credentials."), + AP_INIT_FLAG("AuthLDAPBindAuthoritative", ap_set_flag_slot, (void *)APR_OFFSETOF(authn_ldap_config_t, bind_authoritative), OR_AUTHCFG, "Set to 'on' to return failures when user-specific bind fails - defaults to on."), diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c index 33462c7..24468ba 100644 --- a/modules/ldap/util_ldap.c +++ b/modules/ldap/util_ldap.c @@ -493,18 +493,57 @@ static int uldap_ld_errno(util_ldap_connection_t *ldc) } /* - * SASL credentials conversation function. Does nothing really useful yet, - * is around just because it is required. + * SASL credentials conversation function. + * Calls external helper if specified, otherwise just returns success. * - * Always returns LDAP_SUCCESS + * Returns LDAP_SUCCESS on success; and an error code on failure */ - static int uldap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *sasl_interact) { - return LDAP_SUCCESS; + char *bindsaslinteract = (char *)defaults; + int ret = LDAP_SUCCESS; + apr_pool_t *pool; + apr_proc_t proc; + apr_procattr_t *procattr; + apr_exit_why_e why; + int code; + char **argv; + + if (bindsaslinteract == NULL) + return ret; + + apr_pool_create(&pool, NULL); + + if (apr_tokenize_to_argv(bindsaslinteract, &argv, pool) != APR_SUCCESS) { + ret = LDAP_PARAM_ERROR; + goto out; + } + + if (apr_procattr_create(&procattr, pool) != APR_SUCCESS) { + ret = LDAP_LOCAL_ERROR; + goto out; + } + + if (apr_proc_create(&proc, argv[0],(const char * const*)argv, + NULL, procattr, pool) != APR_SUCCESS) { + ret = LDAP_LOCAL_ERROR; + goto out; + } + + if (apr_proc_wait(&proc, &code, &why, APR_WAIT) != APR_CHILD_DONE) { + ret = LDAP_LOCAL_ERROR; + goto out; + } + + if (why != APR_PROC_EXIT) + ret = LDAP_LOCAL_ERROR; + +out: + apr_pool_destroy(pool); + return ret; } /* @@ -514,8 +553,9 @@ static int uldap_sasl_interact(LDAP *ld, * * Returns LDAP_SUCCESS on success; and an error code on failure */ -static int uldap_bind(util_ldap_connection_t *ldc, char *binddn, - char* bindpw, char *bindsaslmech, +static int uldap_bind(util_ldap_connection_t *ldc, + char *binddn, char* bindpw, + char *bindsaslmech, char *bindsaslinteract, struct timeval *timeout) { int rc; @@ -523,7 +563,7 @@ static int uldap_bind(util_ldap_connection_t *ldc, char *binddn, if (bindsaslmech) { rc = ldap_sasl_interactive_bind_s(ldc->ldap, binddn, bindsaslmech, NULL, NULL, LDAP_SASL_QUIET, - uldap_sasl_interact, NULL); + uldap_sasl_interact, bindsaslinteract); if (rc == -1) { ldc->reason = "LDAP: ldap_sasl_interactive_bind_s() failed"; /* -1 is LDAP_SERVER_DOWN in openldap, use something else */ @@ -617,7 +657,8 @@ static int uldap_connection_open(request_rec *r, apr_sleep(st->retry_delay); } rc = uldap_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw, - (char *)ldc->bindsaslmech, st->opTimeout); + (char *)ldc->bindsaslmech, (char *)ldc->bindsaslinteract, + st->opTimeout); if (rc == LDAP_SUCCESS) break; @@ -721,7 +762,7 @@ static util_ldap_connection_t * uldap_connection_find(request_rec *r, const char *host, int port, const char *binddn, const char *bindpw, - const char *bindsaslmech, + const char *bindsaslmech, const char *bindsaslinteract, deref_options deref, int secure) { struct util_ldap_connection_t *l, *p; /* To traverse the linked list */ @@ -757,6 +798,8 @@ static util_ldap_connection_t * && !strcmp(l->bindpw, bindpw))) && ((!l->bindsaslmech && !bindsaslmech) || (l->bindsaslmech && bindsaslmech && !strcmp(l->bindsaslmech, bindsaslmech))) + && ((!l->bindsaslinteract && !bindsaslinteract) || (l->bindsaslinteract && bindsaslinteract + && !strcmp(l->bindsaslinteract, bindsaslinteract))) && (l->deref == deref) && (l->secure == secureflag) && !compare_client_certs(dc->client_certs, l->client_certs)) { @@ -817,6 +860,7 @@ static util_ldap_connection_t * util_ldap_strdup((char**)&(l->binddn), binddn); util_ldap_strdup((char**)&(l->bindpw), bindpw); util_ldap_strdup((char**)&(l->bindsaslmech), bindsaslmech); + util_ldap_strdup((char**)&(l->bindsaslinteract), bindsaslinteract); break; } #if APR_HAS_THREADS @@ -869,6 +913,7 @@ static util_ldap_connection_t * util_ldap_strdup((char**)&(l->binddn), binddn); util_ldap_strdup((char**)&(l->bindpw), bindpw); util_ldap_strdup((char**)&(l->bindsaslmech), bindsaslmech); + util_ldap_strdup((char**)&(l->bindsaslinteract), bindsaslinteract); l->ChaseReferrals = dc->ChaseReferrals; l->ReferralHopLimit = dc->ReferralHopLimit; @@ -1822,7 +1867,7 @@ start_over: * fails, it means that the password is wrong (the dn obviously * exists, since we just retrieved it) */ - result = uldap_bind(ldc, (char *)*binddn, (char *)bindpw, NULL, + result = uldap_bind(ldc, (char *)*binddn, (char *)bindpw, NULL, NULL, st->opTimeout); if (AP_LDAP_IS_SERVER_DOWN(result) || (result == LDAP_TIMEOUT && failures == 0)) { -- 1.8.3.1