--- 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 | 92 ++++++++++++++++++++++----------- 5 files changed, 110 insertions(+), 37 deletions(-)
diff --git a/docs/manual/mod/mod_authnz_ldap.xml b/docs/manual/mod/mod_authnz_ldap.xml index 358115f..85e626c 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> @@ -890,8 +898,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> @@ -929,6 +937,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 a27abe4..97c69c1 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 3d5faed..60123b3 100644 --- a/include/util_ldap.h +++ b/include/util_ldap.h @@ -113,6 +113,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 */ @@ -238,8 +239,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 b1c5740..cdf06f4 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, connection->user is DN instead of userid */ @@ -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); } /* @@ -497,13 +501,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 { @@ -1621,6 +1627,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 da0db6e..535c12a 100644 --- a/modules/ldap/util_ldap.c +++ b/modules/ldap/util_ldap.c @@ -490,39 +490,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; } @@ -585,8 +613,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; @@ -625,7 +653,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; @@ -690,6 +718,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 */ @@ -723,6 +752,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)) { @@ -782,7 +813,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 @@ -834,6 +865,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; @@ -1779,8 +1811,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.7.1