+#ifdef SLAP_AUTH_REWRITE
+#include "rewrite.h"
+struct rewrite_info *sasl_rwinfo = NULL;
+#define AUTHID_CONTEXT "authid"
+#endif /* SLAP_AUTH_REWRITE */
+
+/* What SASL proxy authorization policies are allowed? */
+#define SASL_AUTHZ_NONE 0x00
+#define SASL_AUTHZ_FROM 0x01
+#define SASL_AUTHZ_TO 0x02
+#define SASL_AUTHZ_AND 0x10
+
+static int authz_policy = SASL_AUTHZ_NONE;
+
+static
+int slap_sasl_match( Operation *opx, struct berval *rule,
+ struct berval *assertDN, struct berval *authc );
+
+int slap_sasl_setpolicy( const char *arg )
+{
+ int rc = LDAP_SUCCESS;
+
+ if ( strcasecmp( arg, "none" ) == 0 ) {
+ authz_policy = SASL_AUTHZ_NONE;
+ } else if ( strcasecmp( arg, "from" ) == 0 ) {
+ authz_policy = SASL_AUTHZ_FROM;
+ } else if ( strcasecmp( arg, "to" ) == 0 ) {
+ authz_policy = SASL_AUTHZ_TO;
+ } else if ( strcasecmp( arg, "both" ) == 0 || strcasecmp( arg, "any" ) == 0 ) {
+ authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO;
+ } else if ( strcasecmp( arg, "all" ) == 0 ) {
+ authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO | SASL_AUTHZ_AND;
+ } else {
+ rc = LDAP_OTHER;
+ }
+ return rc;
+}
+
+int slap_parse_user( struct berval *id, struct berval *user,
+ struct berval *realm, struct berval *mech )
+{
+ char u;
+
+ assert( id );
+ assert( !BER_BVISNULL( id ) );
+ assert( user );
+ assert( realm );
+ assert( mech );
+
+ u = id->bv_val[ 0 ];
+
+ if ( u != 'u' && u != 'U' ) {
+ /* called with something other than u: */
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ /* uauthzid form:
+ * u[.mech[/realm]]:user
+ */
+
+ user->bv_val = strchr( id->bv_val, ':' );
+ if ( BER_BVISNULL( user ) ) {
+ return LDAP_PROTOCOL_ERROR;
+ }
+ user->bv_val[ 0 ] = '\0';
+ user->bv_val++;
+ user->bv_len = id->bv_len - ( user->bv_val - id->bv_val );
+
+ mech->bv_val = strchr( id->bv_val, '.' );
+ if ( !BER_BVISNULL( mech ) ) {
+ mech->bv_val[ 0 ] = '\0';
+ mech->bv_val++;
+
+ realm->bv_val = strchr( mech->bv_val, '/' );
+
+ if ( !BER_BVISNULL( realm ) ) {
+ realm->bv_val[ 0 ] = '\0';
+ realm->bv_val++;
+ mech->bv_len = realm->bv_val - mech->bv_val - 1;
+ realm->bv_len = user->bv_val - realm->bv_val - 1;
+ } else {
+ mech->bv_len = user->bv_val - mech->bv_val - 1;
+ }
+
+ } else {
+ BER_BVZERO( realm );
+ }
+
+ if ( id->bv_val[ 1 ] != '\0' ) {
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ if ( !BER_BVISNULL( mech ) ) {
+ assert( mech->bv_val == id->bv_val + 2 );
+
+ AC_MEMCPY( mech->bv_val - 2, mech->bv_val, mech->bv_len + 1 );
+ mech->bv_val -= 2;
+ }
+
+ if ( !BER_BVISNULL( realm ) ) {
+ assert( realm->bv_val >= id->bv_val + 2 );
+
+ AC_MEMCPY( realm->bv_val - 2, realm->bv_val, realm->bv_len + 1 );
+ realm->bv_val -= 2;
+ }
+
+ /* leave "u:" before user */
+ user->bv_val -= 2;
+ user->bv_len += 2;
+ user->bv_val[ 0 ] = u;
+ user->bv_val[ 1 ] = ':';
+
+ return LDAP_SUCCESS;
+}
+
+static int slap_parseURI( Operation *op, struct berval *uri,
+ struct berval *base, struct berval *nbase,
+ int *scope, Filter **filter, struct berval *fstr )