You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Lubomir Rintel <lk...@v3.sk> on 2014/03/19 11:00:21 UTC
[PATCH RESEND 1/2] mod_authn_ldap: Allow authentication with SASL
From: Lubomir Rintel <lu...@gooddata.com>
---
docs/manual/mod/mod_authnz_ldap.xml | 34 ++++++++++++-
docs/manual/style/scripts/prettify.js | 2 +-
include/util_ldap.h | 5 +-
modules/aaa/mod_authnz_ldap.c | 14 +++++-
modules/ldap/util_ldap.c | 94 +++++++++++++++++++++++------------
5 files changed, 111 insertions(+), 38 deletions(-)
diff --git a/docs/manual/mod/mod_authnz_ldap.xml b/docs/manual/mod/mod_authnz_ldap.xml
index de59a0b..1a99079 100644
--- a/docs/manual/mod/mod_authnz_ldap.xml
+++ b/docs/manual/mod/mod_authnz_ldap.xml
@@ -183,6 +183,14 @@ for HTTP Basic authentication.</description>
<td>An optional password to bind
with during the search phase.</td>
</tr>
+
+ <tr>
+ <td><directive
+ module="mod_authnz_ldap">AuthLDAPBindSASLMech</directive></td>
+
+ <td>An optional SASL mechanism to use for bind
+ with during the search phase.</td>
+ </tr>
</table>
</section>
@@ -903,8 +911,8 @@ to perform a DN lookup</description>
<usage>
<p>An optional DN used to bind to the server when searching for
- entries. If not provided, <module>mod_authnz_ldap</module> will use
- an anonymous bind.</p>
+ entries. If not provided, and simple bind (not SASL) is used,
+ <module>mod_authnz_ldap</module> will use an anonymous bind.</p>
</usage>
</directivesynopsis>
@@ -943,6 +951,28 @@ AuthLDAPBindPassword "exec:/path/to/otherProgram argument1"
</directivesynopsis>
<directivesynopsis>
+<name>AuthLDAPBindSASLMech</name>
+<description>Optional SASL mechanism to use in binding to the LDAP server</description>
+<syntax>AuthLDAPBindSASLMech <em>sasl-mech</em></syntax>
+<contextlist><context>directory</context><context>.htaccess</context>
+</contextlist>
+<override>AuthConfig</override>
+
+<usage>
+ <p>An optional SASL mechanism used to bind to the server when
+ searching for entries. Multiple mechanisms can be used,
+ separated with commas. If not provided,
+ <module>mod_authnz_ldap</module> will use simple bind.</p>
+
+<example><pre>
+#Authenticate with Kerberos GSSAPI
+AuthLDAPBindSASLMech "GSSAPI"
+</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 2fa959a..f1ab2e6 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,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,CacheDetailHeade
r,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,DeflateMemLevel,Deflate
WindowSize,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,ISAPILogNotSuppo
rted,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,MaxKeepAliveRequests,MaxMemFre
e,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,ProxyReceiveBufferSize,ProxyRe
mote,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,SessionC
ookieRemove,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,SSLOptions,SSLPassPhrase
Dialog,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_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_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 1dc0ee2..05de641 100644
--- a/include/util_ldap.h
+++ b/include/util_ldap.h
@@ -117,6 +117,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) */
int bound; /* Flag to indicate whether this connection is bound yet */
@@ -242,8 +243,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, deref_options deref,
- int secure));
+ const char *binddn, const char *bindpw, const char *bindsaslmech,
+ deref_options deref, int secure));
/**
* Compare two DNs for sameness
diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c
index 4ed6c21..fe0ec85 100644
--- a/modules/aaa/mod_authnz_ldap.c
+++ b/modules/aaa/mod_authnz_ldap.c
@@ -59,6 +59,7 @@ typedef struct {
deref_options deref; /* how to handle alias dereferening */
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) */
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 */
@@ -344,6 +345,7 @@ static void *create_authnz_ldap_dir_config(apr_pool_t *p, char *d)
sec->host = NULL;
sec->binddn = NULL;
sec->bindpw = NULL;
+ sec->bindsaslmech = NULL;
sec->bind_authoritative = 1;
sec->deref = always;
sec->group_attrib_is_dn = 1;
@@ -439,6 +441,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;
/* If the per-request config isn't set, we didn't authenticate this user, and leave the default credentials */
if (req && req->password &&
@@ -447,10 +450,11 @@ static util_ldap_connection_t *get_connection_for_authz(request_rec *r, enum aut
(type == LDAP_COMPARE_AND_SEARCH && sec->compare_as_user && sec->search_as_user))){
binddn = req->dn;
bindpw = req->password;
+ bindsaslmech = NULL;
}
return util_ldap_connection_find(r, sec->host, sec->port,
- binddn, bindpw,
+ binddn, bindpw, bindsaslmech,
sec->deref, sec->secure);
}
/*
@@ -500,13 +504,15 @@ static authn_status authn_ldap_check_password(request_rec *r, const char *user,
if (sec->host) {
const char *binddn = sec->binddn;
const char *bindpw = sec->bindpw;
+ const char *bindsaslmech = sec->bindsaslmech;
if (sec->initial_bind_as_user) {
bindpw = password;
binddn = ldap_determine_binddn(r, user);
+ bindsaslmech = NULL;
}
ldc = util_ldap_connection_find(r, sec->host, sec->port,
- binddn, bindpw,
+ binddn, bindpw, bindsaslmech,
sec->deref, sec->secure);
}
else {
@@ -1705,6 +1711,10 @@ static const command_rec authnz_ldap_cmds[] =
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_TAKE1("AuthLDAPBindSASLMech", ap_set_string_slot,
+ (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_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 750e6a7..33462c7 100644
--- a/modules/ldap/util_ldap.c
+++ b/modules/ldap/util_ldap.c
@@ -493,39 +493,67 @@ 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.
+ *
+ * Always returns LDAP_SUCCESS
+ */
+
+static int uldap_sasl_interact(LDAP *ld,
+ unsigned flags,
+ void *defaults,
+ void *sasl_interact)
+{
+ return LDAP_SUCCESS;
+}
+
+/*
* Replacement function for ldap_simple_bind_s() with a timeout.
* To do this in a portable way, we have to use ldap_simple_bind() and
* ldap_result().
*
* Returns LDAP_SUCCESS on success; and an error code on failure
*/
-static int uldap_simple_bind(util_ldap_connection_t *ldc, char *binddn,
- char* bindpw, struct timeval *timeout)
+static int uldap_bind(util_ldap_connection_t *ldc, char *binddn,
+ char* bindpw, char *bindsaslmech,
+ struct timeval *timeout)
{
- LDAPMessage *result;
int rc;
- int msgid = ldap_simple_bind(ldc->ldap, binddn, bindpw);
- if (msgid == -1) {
- ldc->reason = "LDAP: ldap_simple_bind() failed";
- return uldap_ld_errno(ldc);
- }
- rc = ldap_result(ldc->ldap, msgid, 0, timeout, &result);
- if (rc == -1) {
- ldc->reason = "LDAP: ldap_simple_bind() result retrieval failed";
- /* -1 is LDAP_SERVER_DOWN in openldap, use something else */
- return uldap_ld_errno(ldc);
- }
- else if (rc == 0) {
- ldc->reason = "LDAP: ldap_simple_bind() timed out";
- rc = LDAP_TIMEOUT;
- } else if (ldap_parse_result(ldc->ldap, result, &rc, NULL, NULL, NULL,
- NULL, 1) == -1) {
- ldc->reason = "LDAP: ldap_simple_bind() parse result failed";
- return uldap_ld_errno(ldc);
- }
- else {
- ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp bind", ldc);
- }
+
+ if (bindsaslmech) {
+ rc = ldap_sasl_interactive_bind_s(ldc->ldap, binddn, bindsaslmech,
+ NULL, NULL, LDAP_SASL_QUIET,
+ uldap_sasl_interact, NULL);
+ if (rc == -1) {
+ ldc->reason = "LDAP: ldap_sasl_interactive_bind_s() failed";
+ /* -1 is LDAP_SERVER_DOWN in openldap, use something else */
+ return uldap_ld_errno(ldc);
+ }
+ } else {
+ LDAPMessage *result;
+ int msgid;
+
+ msgid = ldap_simple_bind(ldc->ldap, binddn, bindpw);
+ if (msgid == -1) {
+ ldc->reason = "LDAP: ldap_simple_bind() failed";
+ return uldap_ld_errno(ldc);
+ }
+ rc = ldap_result(ldc->ldap, msgid, 0, timeout, &result);
+ if (rc == -1) {
+ ldc->reason = "LDAP: ldap_simple_bind() result retrieval failed";
+ /* -1 is LDAP_SERVER_DOWN in openldap, use something else */
+ return uldap_ld_errno(ldc);
+ } else if (rc == 0) {
+ ldc->reason = "LDAP: ldap_simple_bind() timed out";
+ rc = LDAP_TIMEOUT;
+ } else if (ldap_parse_result(ldc->ldap, result, &rc, NULL, NULL, NULL,
+ NULL, 1) == -1) {
+ ldc->reason = "LDAP: ldap_simple_bind() parse result failed";
+ return uldap_ld_errno(ldc);
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp bind", ldc);
return rc;
}
@@ -588,8 +616,8 @@ static int uldap_connection_open(request_rec *r,
if (failures > 0 && st->retry_delay > 0) {
apr_sleep(st->retry_delay);
}
- rc = uldap_simple_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw,
- st->opTimeout);
+ rc = uldap_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw,
+ (char *)ldc->bindsaslmech, st->opTimeout);
if (rc == LDAP_SUCCESS) break;
@@ -628,7 +656,7 @@ static int uldap_connection_open(request_rec *r,
if (LDAP_SUCCESS != rc)
{
uldap_connection_unbind(ldc);
- ldc->reason = "LDAP: ldap_simple_bind() failed";
+ ldc->reason = "LDAP: bind failed";
}
else {
ldc->bound = 1;
@@ -693,6 +721,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,
deref_options deref, int secure)
{
struct util_ldap_connection_t *l, *p; /* To traverse the linked list */
@@ -726,6 +755,8 @@ static util_ldap_connection_t *
&& !strcmp(l->binddn, binddn)))
&& ((!l->bindpw && !bindpw) || (l->bindpw && bindpw
&& !strcmp(l->bindpw, bindpw)))
+ && ((!l->bindsaslmech && !bindsaslmech) || (l->bindsaslmech && bindsaslmech
+ && !strcmp(l->bindsaslmech, bindsaslmech)))
&& (l->deref == deref) && (l->secure == secureflag)
&& !compare_client_certs(dc->client_certs, l->client_certs))
{
@@ -785,7 +816,7 @@ static util_ldap_connection_t *
l->must_rebind = 1;
util_ldap_strdup((char**)&(l->binddn), binddn);
util_ldap_strdup((char**)&(l->bindpw), bindpw);
-
+ util_ldap_strdup((char**)&(l->bindsaslmech), bindsaslmech);
break;
}
#if APR_HAS_THREADS
@@ -837,6 +868,7 @@ static util_ldap_connection_t *
l->deref = deref;
util_ldap_strdup((char**)&(l->binddn), binddn);
util_ldap_strdup((char**)&(l->bindpw), bindpw);
+ util_ldap_strdup((char**)&(l->bindsaslmech), bindsaslmech);
l->ChaseReferrals = dc->ChaseReferrals;
l->ReferralHopLimit = dc->ReferralHopLimit;
@@ -1790,8 +1822,8 @@ start_over:
* fails, it means that the password is wrong (the dn obviously
* exists, since we just retrieved it)
*/
- result = uldap_simple_bind(ldc, (char *)*binddn, (char *)bindpw,
- st->opTimeout);
+ result = uldap_bind(ldc, (char *)*binddn, (char *)bindpw, NULL,
+ st->opTimeout);
if (AP_LDAP_IS_SERVER_DOWN(result) ||
(result == LDAP_TIMEOUT && failures == 0)) {
if (AP_LDAP_IS_SERVER_DOWN(result))
--
1.8.3.1