>From 0c94000e04ea6b47526935d1201a526b4e39be2d Mon Sep 17 00:00:00 2001
From: Nathan Kinder <nkinder@redhat.com>
Date: Mon, 5 Oct 2009 13:31:01 -0700
Subject: [PATCH] Allow anonymous bind resource limits to be set.

This patch adds a new config setting named nsslapd-anonlimitsdn
that one can set to the DN of an entry containing the bind-based
resource limit attributes to use for operations performed by an
anonymous user.  This allows the defaults to still be used for
all other actual bound users who do not have any user specific
resource settings.

This implementation approach allows any resource limits that
are registered via the reslimit API to work with this anonymous
limits template entry.
---
 ldap/servers/slapd/libglobs.c   |   34 ++++++++++++++++++++++++++++++++++
 ldap/servers/slapd/pblock.c     |   17 ++++++++++++++---
 ldap/servers/slapd/proto-slap.h |    2 ++
 ldap/servers/slapd/slap.h       |    2 ++
 4 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index cd7bb5d..3726dfd 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -496,6 +496,9 @@ static struct config_get_and_set {
                 NULL, 0,
 		(void**)&global_slapdFrontendConfig.ldapi_auto_dn_suffix, CONFIG_STRING, NULL},
 #endif
+	{CONFIG_ANON_LIMITS_DN_ATTRIBUTE, config_set_anon_limits_dn,
+                NULL, 0,
+                (void**)&global_slapdFrontendConfig.anon_limits_dn, CONFIG_STRING, NULL},
 	{CONFIG_SLAPI_COUNTER_ATTRIBUTE, config_set_slapi_counters,
 		NULL, 0,
 		(void**)&global_slapdFrontendConfig.slapi_counters, CONFIG_ON_OFF, 
@@ -906,6 +909,7 @@ FrontendConfig_init () {
   cfg->versionstring = SLAPD_VERSION_STR;
   cfg->sizelimit = SLAPD_DEFAULT_SIZELIMIT;
   cfg->timelimit = SLAPD_DEFAULT_TIMELIMIT;
+  cfg->anon_limits_dn = slapi_ch_strdup("");
   cfg->schemacheck = LDAP_ON;
   cfg->syntaxcheck = LDAP_OFF;
   cfg->syntaxlogging = LDAP_OFF;
@@ -1434,6 +1438,25 @@ int config_set_ldapi_auto_dn_suffix( const char *attrname, char *value, char *er
 }
 #endif
 
+int config_set_anon_limits_dn( const char *attrname, char *value, char *errorbuf, int apply )
+{
+  int retVal = LDAP_SUCCESS;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  if ( apply) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapi_ch_free ( (void **) &(slapdFrontendConfig->anon_limits_dn) );
+        slapdFrontendConfig->anon_limits_dn = slapi_ch_strdup ( value );
+         CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+  return retVal;
+}
+
 /*
  * Set nsslapd-counters: on | off to the internal config variable slapi_counters.
  * If set to off, slapi_counters is not initialized and the counters are not
@@ -3539,6 +3562,17 @@ char *config_get_ldapi_auto_dn_suffix(){
 }
 #endif
 
+
+char *config_get_anon_limits_dn(){
+  char *retVal;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapi_ch_strdup(slapdFrontendConfig->anon_limits_dn);
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
 int config_get_slapi_counters()
 {   
   int retVal;
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index 21195ea..f0443af 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -3093,14 +3093,25 @@ bind_credentials_set_nolock( Connection *conn, char *authtype, char *normdn,
 		if ( conn->c_dn != NULL ) {
 			if ( bind_target_entry == NULL )
 			{
-				Slapi_DN	*sdn;
+				Slapi_DN        *sdn;
 
 				sdn = slapi_sdn_new_dn_byref( conn->c_dn );			/* set */
 				reslimit_update_from_dn( conn, sdn );
 				slapi_sdn_free( &sdn );
-			}
-			else
+			} else {
 				reslimit_update_from_entry( conn, bind_target_entry );	
+			}
+		} else {
+			char *anon_dn = config_get_anon_limits_dn();
+			Slapi_DN *anon_sdn = NULL;
+
+			/* If an anonymous limits dn is set, use it to set the limits. */
+			if (anon_dn && (strlen(anon_dn) > 0)) {
+				anon_sdn = slapi_sdn_new_dn_byref( anon_dn );
+				reslimit_update_from_dn( conn, anon_sdn );
+				slapi_sdn_free( &anon_sdn );
+				slapi_ch_free_string( &anon_dn );
+			}
 		}
 	}
 }
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 35e5697..b220bf0 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -255,6 +255,7 @@ int config_set_ldapi_search_base_dn( const char *attrname, char *value, char *er
 #if defined(ENABLE_AUTO_DN_SUFFIX)
 int config_set_ldapi_auto_dn_suffix( const char *attrname, char *value, char *errorbuf, int apply );   
 #endif
+int config_set_anon_limits_dn( const char *attrname, char *value, char *errorbuf, int apply );
 int config_set_slapi_counters( const char *attrname, char *value, char *errorbuf, int apply );   
 int config_set_srvtab( const char *attrname, char *value, char *errorbuf, int apply );
 int config_set_sizelimit( const char *attrname, char *value, char *errorbuf, int apply );
@@ -379,6 +380,7 @@ char *config_get_ldapi_search_base_dn();
 #if defined(ENABLE_AUTO_DN_SUFFIX)
 char *config_get_ldapi_auto_dn_suffix(); 
 #endif
+char *config_get_anon_limits_dn();
 int config_get_slapi_counters(); 
 char *config_get_srvtab();
 int config_get_sizelimit();
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index ec030bc..76c8df2 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1743,6 +1743,7 @@ typedef struct _slapdEntryPoints {
 #define CONFIG_LDAPI_GIDNUMBER_TYPE_ATTRIBUTE "nsslapd-ldapigidnumbertype"
 #define CONFIG_LDAPI_SEARCH_BASE_DN_ATTRIBUTE "nsslapd-ldapientrysearchbase"
 #define CONFIG_LDAPI_AUTO_DN_SUFFIX_ATTRIBUTE "nsslapd-ldapiautodnsuffix"
+#define CONFIG_ANON_LIMITS_DN_ATTRIBUTE "nsslapd-anonlimitsdn"
 #define CONFIG_SLAPI_COUNTER_ATTRIBUTE "nsslapd-counters"
 #define CONFIG_SECURITY_ATTRIBUTE "nsslapd-security"
 #define CONFIG_SSL3CIPHERS_ATTRIBUTE "nsslapd-SSL3ciphers"
@@ -2024,6 +2025,7 @@ typedef struct _slapdFrontendConfig {
   int allow_anon_access;	/* switch to enable/disable anonymous access */
   int minssf;			/* minimum security strength factor (for SASL and SSL/TLS) */
   size_t maxsasliosize;         /* limit incoming SASL IO packet size */
+  char *anon_limits_dn;		/* template entry for anonymous resource limits */
 #ifndef _WIN32
   struct passwd *localuserinfo; /* userinfo of localuser */
 #endif /* _WIN32 */
-- 
1.6.2.5

