Diff for /servers/slapd/saslauthz.c between versions 1.144 and 1.144.2.11

version 1.144, 2004/12/08 18:09:54 version 1.144.2.11, 2005/11/26 23:54:48
Line 1 Line 1
 /* $OpenLDAP: pkg/ldap/servers/slapd/saslauthz.c,v 1.143 2004/11/25 21:59:01 hyc Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/saslauthz.c,v 1.144.2.10 2005/11/14 18:06:09 kurt Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
  * Copyright 1998-2004 The OpenLDAP Foundation.   * Copyright 1998-2005 The OpenLDAP Foundation.
  * Portions Copyright 2000 Mark Adamson, Carnegie Mellon.   * Portions Copyright 2000 Mark Adamson, Carnegie Mellon.
  * All rights reserved.   * All rights reserved.
  *   *
Line 17 Line 17
 #include "portable.h"  #include "portable.h"
   
 #include <stdio.h>  #include <stdio.h>
   #ifdef HAVE_LIMITS_H
   #include <limits.h>
   #endif
   
 #include <ac/stdlib.h>  #include <ac/stdlib.h>
 #include <ac/string.h>  #include <ac/string.h>
Line 24 Line 27
   
 #include "slap.h"  #include "slap.h"
   
 #include <limits.h>  
   
 #include "lutil.h"  #include "lutil.h"
   
 #define SASLREGEX_REPLACE 10  #define SASLREGEX_REPLACE 10
Line 87  struct rewrite_info *sasl_rwinfo = NULL; Line 88  struct rewrite_info *sasl_rwinfo = NULL;
 #define SASL_AUTHZ_TO   0x02  #define SASL_AUTHZ_TO   0x02
 #define SASL_AUTHZ_AND  0x10  #define SASL_AUTHZ_AND  0x10
   
   static const char *policy_txt[] = {
           "none", "from", "to", "any"
   };
   
 static int authz_policy = SASL_AUTHZ_NONE;  static int authz_policy = SASL_AUTHZ_NONE;
   
 static  static int
 int slap_sasl_match( Operation *opx, struct berval *rule,  slap_sasl_match( Operation *opx, struct berval *rule,
         struct berval *assertDN, struct berval *authc );          struct berval *assertDN, struct berval *authc );
   
 int slap_sasl_setpolicy( const char *arg )  int slap_sasl_setpolicy( const char *arg )
Line 113  int slap_sasl_setpolicy( const char *arg Line 118  int slap_sasl_setpolicy( const char *arg
         return rc;          return rc;
 }  }
   
   const char * slap_sasl_getpolicy()
   {
           if ( authz_policy == (SASL_AUTHZ_FROM | SASL_AUTHZ_TO | SASL_AUTHZ_AND) )
                   return "all";
           else
                   return policy_txt[authz_policy];
   }
   
 int slap_parse_user( struct berval *id, struct berval *user,  int slap_parse_user( struct berval *id, struct berval *user,
                 struct berval *realm, struct berval *mech )                  struct berval *realm, struct berval *mech )
 {  {
         char    u;          char    u;
                   
         assert( id );          assert( id != NULL );
         assert( !BER_BVISNULL( id ) );          assert( !BER_BVISNULL( id ) );
         assert( user );          assert( user != NULL );
         assert( realm );          assert( realm != NULL );
         assert( mech );          assert( mech != NULL );
   
         u = id->bv_val[ 0 ];          u = id->bv_val[ 0 ];
                   
Line 135  int slap_parse_user( struct berval *id, Line 148  int slap_parse_user( struct berval *id,
          *              u[.mech[/realm]]:user           *              u[.mech[/realm]]:user
          */           */
                   
         user->bv_val = strchr( id->bv_val, ':' );          user->bv_val = ber_bvchr( id, ':' );
         if ( BER_BVISNULL( user ) ) {          if ( BER_BVISNULL( user ) ) {
                 return LDAP_PROTOCOL_ERROR;                  return LDAP_PROTOCOL_ERROR;
         }          }
Line 143  int slap_parse_user( struct berval *id, Line 156  int slap_parse_user( struct berval *id,
         user->bv_val++;          user->bv_val++;
         user->bv_len = id->bv_len - ( user->bv_val - id->bv_val );          user->bv_len = id->bv_len - ( user->bv_val - id->bv_val );
   
         mech->bv_val = strchr( id->bv_val, '.' );          mech->bv_val = ber_bvchr( id, '.' );
         if ( !BER_BVISNULL( mech ) ) {          if ( !BER_BVISNULL( mech ) ) {
                 mech->bv_val[ 0 ] = '\0';                  mech->bv_val[ 0 ] = '\0';
                 mech->bv_val++;                  mech->bv_val++;
                   mech->bv_len = user->bv_val - mech->bv_val - 1;
   
                 realm->bv_val = strchr( mech->bv_val, '/' );                  realm->bv_val = ber_bvchr( mech, '/' );
   
                 if ( !BER_BVISNULL( realm ) ) {                  if ( !BER_BVISNULL( realm ) ) {
                         realm->bv_val[ 0 ] = '\0';                          realm->bv_val[ 0 ] = '\0';
                         realm->bv_val++;                          realm->bv_val++;
                         mech->bv_len = realm->bv_val - mech->bv_val - 1;                          mech->bv_len = realm->bv_val - mech->bv_val - 1;
                         realm->bv_len = user->bv_val - realm->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 {          } else {
Line 190  int slap_parse_user( struct berval *id, Line 202  int slap_parse_user( struct berval *id,
         return LDAP_SUCCESS;          return LDAP_SUCCESS;
 }  }
   
 static int slap_parseURI( Operation *op, struct berval *uri,  #ifdef SLAP_AUTHZ_SYNTAX
         struct berval *base, struct berval *nbase,  int
         int *scope, Filter **filter, struct berval *fstr )  authzValidate(
           Syntax *syntax,
           struct berval *in )
 {  {
         struct berval bv;          struct berval   bv;
         int rc;          int             rc = LDAP_INVALID_SYNTAX;
         LDAPURLDesc *ludp;          LDAPURLDesc     *ludp = NULL;
           int             scope = -1;
   
           /*
            * 1) <DN>
            * 2) dn[.{exact|children|subtree|onelevel}]:{*|<DN>}
            * 3) dn.regex:<pattern>
            * 4) u[.mech[/realm]]:<ID>
            * 5) group[/<groupClass>[/<memberAttr>]]:<DN>
            * 6) <URL>
            */
   
           assert( in != NULL );
           assert( !BER_BVISNULL( in ) );
   
           Debug( LDAP_DEBUG_TRACE,
                   "authzValidate: parsing %s\n", in->bv_val, 0, 0 );
   
           /*
            * 2) dn[.{exact|children|subtree|onelevel}]:{*|<DN>}
            * 3) dn.regex:<pattern>
            *
            * <DN> must pass DN normalization
            */
           if ( !strncasecmp( in->bv_val, "dn", STRLENOF( "dn" ) ) ) {
                   bv.bv_val = in->bv_val + STRLENOF( "dn" );
   
                   if ( bv.bv_val[ 0 ] == '.' ) {
                           bv.bv_val++;
   
                           if ( !strncasecmp( bv.bv_val, "exact:", STRLENOF( "exact:" ) ) ) {
                                   bv.bv_val += STRLENOF( "exact:" );
                                   scope = LDAP_X_SCOPE_EXACT;
   
                           } else if ( !strncasecmp( bv.bv_val, "regex:", STRLENOF( "regex:" ) ) ) {
                                   bv.bv_val += STRLENOF( "regex:" );
                                   scope = LDAP_X_SCOPE_REGEX;
   
                           } else if ( !strncasecmp( bv.bv_val, "children:", STRLENOF( "children:" ) ) ) {
                                   bv.bv_val += STRLENOF( "children:" );
                                   scope = LDAP_X_SCOPE_CHILDREN;
   
                           } else if ( !strncasecmp( bv.bv_val, "subtree:", STRLENOF( "subtree:" ) ) ) {
                                   bv.bv_val += STRLENOF( "subtree:" );
                                   scope = LDAP_X_SCOPE_SUBTREE;
   
                           } else if ( !strncasecmp( bv.bv_val, "onelevel:", STRLENOF( "onelevel:" ) ) ) {
                                   bv.bv_val += STRLENOF( "onelevel:" );
                                   scope = LDAP_X_SCOPE_ONELEVEL;
   
                           } else {
                                   return LDAP_INVALID_SYNTAX;
                           }
   
                   } else {
                           if ( bv.bv_val[ 0 ] != ':' ) {
                                   return LDAP_INVALID_SYNTAX;
                           }
                           scope = LDAP_X_SCOPE_EXACT;
                           bv.bv_val++;
                   }
   
                   bv.bv_val += strspn( bv.bv_val, " " );
                   /* jump here in case no type specification was present
                    * and uri was not an URI... HEADS-UP: assuming EXACT */
   is_dn:          bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val );
   
                   /* a single '*' means any DN without using regexes */
                   if ( ber_bvccmp( &bv, '*' ) ) {
                           /* LDAP_X_SCOPE_USERS */
                           return LDAP_SUCCESS;
                   }
   
                   switch ( scope ) {
                   case LDAP_X_SCOPE_EXACT:
                   case LDAP_X_SCOPE_CHILDREN:
                   case LDAP_X_SCOPE_SUBTREE:
                   case LDAP_X_SCOPE_ONELEVEL:
                           return dnValidate( NULL, &bv );
   
                   case LDAP_X_SCOPE_REGEX:
                           return LDAP_SUCCESS;
                   }
   
                   return rc;
   
           /*
            * 4) u[.mech[/realm]]:<ID>
            */
           } else if ( ( in->bv_val[ 0 ] == 'u' || in->bv_val[ 0 ] == 'U' )
                           && ( in->bv_val[ 1 ] == ':' 
                                   || in->bv_val[ 1 ] == '/' 
                                   || in->bv_val[ 1 ] == '.' ) )
           {
                   char            buf[ SLAP_LDAPDN_MAXLEN ];
                   struct berval   id,
                                   user = BER_BVNULL,
                                   realm = BER_BVNULL,
                                   mech = BER_BVNULL;
   
                   if ( sizeof( buf ) <= in->bv_len ) {
                           return LDAP_INVALID_SYNTAX;
                   }
   
                   id.bv_len = in->bv_len;
                   id.bv_val = buf;
                   strncpy( buf, in->bv_val, sizeof( buf ) );
   
                   rc = slap_parse_user( &id, &user, &realm, &mech );
                   if ( rc != LDAP_SUCCESS ) {
                           return LDAP_INVALID_SYNTAX;
                   }
   
                   return rc;
   
           /*
            * 5) group[/groupClass[/memberAttr]]:<DN>
            *
            * <groupClass> defaults to "groupOfNames"
            * <memberAttr> defaults to "member"
            * 
            * <DN> must pass DN normalization
            */
           } else if ( strncasecmp( in->bv_val, "group", STRLENOF( "group" ) ) == 0 )
           {
                   struct berval   group_dn = BER_BVNULL,
                                   group_oc = BER_BVNULL,
                                   member_at = BER_BVNULL;
   
                   bv.bv_val = in->bv_val + STRLENOF( "group" );
                   bv.bv_len = in->bv_len - STRLENOF( "group" );
                   group_dn.bv_val = ber_bvchr( &bv, ':' );
                   if ( group_dn.bv_val == NULL ) {
                           /* last chance: assume it's a(n exact) DN ... */
                           bv.bv_val = in->bv_val;
                           scope = LDAP_X_SCOPE_EXACT;
                           goto is_dn;
                   }
                   
                   /*
                    * FIXME: we assume that "member" and "groupOfNames"
                    * are present in schema...
                    */
                   if ( bv.bv_val[ 0 ] == '/' ) {
                           group_oc.bv_val = &bv.bv_val[ 1 ];
                           group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
   
                           member_at.bv_val = ber_bvchr( &group_oc, '/' );
                           if ( member_at.bv_val ) {
                                   AttributeDescription    *ad = NULL;
                                   const char              *text = NULL;
   
                                   group_oc.bv_len = member_at.bv_val - group_oc.bv_val;
                                   member_at.bv_val++;
                                   member_at.bv_len = group_dn.bv_val - member_at.bv_val;
                                   rc = slap_bv2ad( &member_at, &ad, &text );
                                   if ( rc != LDAP_SUCCESS ) {
                                           return rc;
                                   }
                           }
   
                           if ( oc_bvfind( &group_oc ) == NULL ) {
                                   return LDAP_INVALID_SYNTAX;
                           }
                   }
   
                   group_dn.bv_val++;
                   group_dn.bv_len = in->bv_len - ( group_dn.bv_val - in->bv_val );
   
                   rc = dnValidate( NULL, &group_dn );
                   if ( rc != LDAP_SUCCESS ) {
                           return rc;
                   }
   
                   return rc;
           }
   
           /*
            * ldap:///<base>??<scope>?<filter>
            * <scope> ::= {base|one|subtree}
            *
            * <scope> defaults to "base"
            * <base> must pass DN normalization
            * <filter> must pass str2filter()
            */
           rc = ldap_url_parse( in->bv_val, &ludp );
           switch ( rc ) {
           case LDAP_URL_SUCCESS:
                   /* FIXME: the check is pedantic, but I think it's necessary,
                    * because people tend to use things like ldaps:// which
                    * gives the idea SSL is being used.  Maybe we could
                    * accept ldapi:// as well, but the point is that we use
                    * an URL as an easy means to define bits of a search with
                    * little parsing.
                    */
                   if ( strcasecmp( ludp->lud_scheme, "ldap" ) != 0 ) {
                           /*
                            * must be ldap:///
                            */
                           rc = LDAP_INVALID_SYNTAX;
                           goto done;
                   }
                   break;
   
           case LDAP_URL_ERR_BADSCHEME:
                   /*
                    * last chance: assume it's a(n exact) DN ...
                    *
                    * NOTE: must pass DN normalization
                    */
                   ldap_free_urldesc( ludp );
                   bv.bv_val = in->bv_val;
                   scope = LDAP_X_SCOPE_EXACT;
                   goto is_dn;
   
           default:
                   rc = LDAP_INVALID_SYNTAX;
                   goto done;
           }
   
           if ( ( ludp->lud_host && *ludp->lud_host )
                   || ludp->lud_attrs || ludp->lud_exts )
           {
                   /* host part must be empty */
                   /* attrs and extensions parts must be empty */
                   rc = LDAP_INVALID_SYNTAX;
                   goto done;
           }
   
           /* Grab the filter */
           if ( ludp->lud_filter ) {
                   Filter  *f = str2filter( ludp->lud_filter );
                   if ( f == NULL ) {
                           rc = LDAP_INVALID_SYNTAX;
                           goto done;
                   }
                   filter_free( f );
           }
   
           /* Grab the searchbase */
           assert( ludp->lud_dn != NULL );
           ber_str2bv( ludp->lud_dn, 0, 0, &bv );
           rc = dnValidate( NULL, &bv );
   
   done:
           ldap_free_urldesc( ludp );
           return( rc );
   }
   
   #if 0
   int
   authzMatch(
           int             *matchp,
           slap_mask_t     flags,
           Syntax          *syntax,
           MatchingRule    *mr,
           struct berval   *value,
           void            *assertedValue )
   {
           return octetStringMatch( matchp, flags, syntax, mr, value, assertedValue );
   }
   #endif
   
   static int
   authzPrettyNormal(
           struct berval   *val,
           struct berval   *normalized,
           void            *ctx,
           int             normalize )
   {
           struct berval   bv;
           int             rc = LDAP_INVALID_SYNTAX;
           LDAPURLDesc     *ludp = NULL;
           char            *lud_dn = NULL,
                           *lud_filter = NULL;
           int             scope = -1;
   
           /*
            * 1) <DN>
            * 2) dn[.{exact|children|subtree|onelevel}]:{*|<DN>}
            * 3) dn.regex:<pattern>
            * 4) u[.mech[/realm]]:<ID>
            * 5) group[/<groupClass>[/<memberAttr>]]:<DN>
            * 6) <URL>
            */
   
           assert( val != NULL );
           assert( !BER_BVISNULL( val ) );
   
           /*
            * 2) dn[.{exact|children|subtree|onelevel}]:{*|<DN>}
            * 3) dn.regex:<pattern>
            *
            * <DN> must pass DN normalization
            */
           if ( !strncasecmp( val->bv_val, "dn", STRLENOF( "dn" ) ) ) {
                   struct berval   out = BER_BVNULL,
                                   prefix = BER_BVNULL;
                   char            *ptr;
   
                   bv.bv_val = val->bv_val + STRLENOF( "dn" );
   
                   if ( bv.bv_val[ 0 ] == '.' ) {
                           bv.bv_val++;
   
                           if ( !strncasecmp( bv.bv_val, "exact:", STRLENOF( "exact:" ) ) ) {
                                   bv.bv_val += STRLENOF( "exact:" );
                                   scope = LDAP_X_SCOPE_EXACT;
   
                           } else if ( !strncasecmp( bv.bv_val, "regex:", STRLENOF( "regex:" ) ) ) {
                                   bv.bv_val += STRLENOF( "regex:" );
                                   scope = LDAP_X_SCOPE_REGEX;
   
                           } else if ( !strncasecmp( bv.bv_val, "children:", STRLENOF( "children:" ) ) ) {
                                   bv.bv_val += STRLENOF( "children:" );
                                   scope = LDAP_X_SCOPE_CHILDREN;
   
                           } else if ( !strncasecmp( bv.bv_val, "subtree:", STRLENOF( "subtree:" ) ) ) {
                                   bv.bv_val += STRLENOF( "subtree:" );
                                   scope = LDAP_X_SCOPE_SUBTREE;
   
                           } else if ( !strncasecmp( bv.bv_val, "onelevel:", STRLENOF( "onelevel:" ) ) ) {
                                   bv.bv_val += STRLENOF( "onelevel:" );
                                   scope = LDAP_X_SCOPE_ONELEVEL;
   
                           } else {
                                   return LDAP_INVALID_SYNTAX;
                           }
   
                   } else {
                           if ( bv.bv_val[ 0 ] != ':' ) {
                                   return LDAP_INVALID_SYNTAX;
                           }
                           scope = LDAP_X_SCOPE_EXACT;
                           bv.bv_val++;
                   }
   
                   bv.bv_val += strspn( bv.bv_val, " " );
                   /* jump here in case no type specification was present
                    * and uri was not an URI... HEADS-UP: assuming EXACT */
   is_dn:          bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val );
   
                   /* a single '*' means any DN without using regexes */
                   if ( ber_bvccmp( &bv, '*' ) ) {
                           ber_str2bv_x( "dn:*", STRLENOF( "dn:*" ), 1, normalized, ctx );
                           return LDAP_SUCCESS;
                   }
   
                   switch ( scope ) {
                   case LDAP_X_SCOPE_EXACT:
                   case LDAP_X_SCOPE_CHILDREN:
                   case LDAP_X_SCOPE_SUBTREE:
                   case LDAP_X_SCOPE_ONELEVEL:
                           if ( normalize ) {
                                   rc = dnNormalize( 0, NULL, NULL, &bv, &out, ctx );
                           } else {
                                   rc = dnPretty( NULL, &bv, &out, ctx );
                           }
                           if( rc != LDAP_SUCCESS ) {
                                   return LDAP_INVALID_SYNTAX;
                           }
                           break;
   
                   case LDAP_X_SCOPE_REGEX:
                           normalized->bv_len = STRLENOF( "dn.regex:" ) + bv.bv_len;
                           normalized->bv_val = ber_memalloc_x( normalized->bv_len + 1, ctx );
                           ptr = lutil_strcopy( normalized->bv_val, "dn.regex:" );
                           ptr = lutil_strncopy( ptr, bv.bv_val, bv.bv_len );
                           ptr[ 0 ] = '\0';
                           return LDAP_SUCCESS;
   
                   default:
                           return LDAP_INVALID_SYNTAX;
                   }
   
                   /* prepare prefix */
                   switch ( scope ) {
                   case LDAP_X_SCOPE_EXACT:
                           BER_BVSTR( &prefix, "dn:" );
                           break;
   
                   case LDAP_X_SCOPE_CHILDREN:
                           BER_BVSTR( &prefix, "dn.children:" );
                           break;
   
                   case LDAP_X_SCOPE_SUBTREE:
                           BER_BVSTR( &prefix, "dn.subtree:" );
                           break;
   
                   case LDAP_X_SCOPE_ONELEVEL:
                           BER_BVSTR( &prefix, "dn.onelevel:" );
                           break;
   
                   default:
                           assert( 0 );
                           break;
                   }
   
                   normalized->bv_len = prefix.bv_len + out.bv_len;
                   normalized->bv_val = ber_memalloc_x( normalized->bv_len + 1, ctx );
                   
                   ptr = lutil_strcopy( normalized->bv_val, prefix.bv_val );
                   ptr = lutil_strncopy( ptr, out.bv_val, out.bv_len );
                   ptr[ 0 ] = '\0';
                   ber_memfree_x( out.bv_val, ctx );
   
                   return LDAP_SUCCESS;
   
           /*
            * 4) u[.mech[/realm]]:<ID>
            */
           } else if ( ( val->bv_val[ 0 ] == 'u' || val->bv_val[ 0 ] == 'U' )
                           && ( val->bv_val[ 1 ] == ':' 
                                   || val->bv_val[ 1 ] == '/' 
                                   || val->bv_val[ 1 ] == '.' ) )
           {
                   char            buf[ SLAP_LDAPDN_MAXLEN ];
                   struct berval   id,
                                   user = BER_BVNULL,
                                   realm = BER_BVNULL,
                                   mech = BER_BVNULL;
   
                   if ( sizeof( buf ) <= val->bv_len ) {
                           return LDAP_INVALID_SYNTAX;
                   }
   
                   id.bv_len = val->bv_len;
                   id.bv_val = buf;
                   strncpy( buf, val->bv_val, sizeof( buf ) );
   
                   rc = slap_parse_user( &id, &user, &realm, &mech );
                   if ( rc != LDAP_SUCCESS ) {
                           return LDAP_INVALID_SYNTAX;
                   }
   
                   ber_dupbv_x( normalized, val, ctx );
   
                   return rc;
   
           /*
            * 5) group[/groupClass[/memberAttr]]:<DN>
            *
            * <groupClass> defaults to "groupOfNames"
            * <memberAttr> defaults to "member"
            * 
            * <DN> must pass DN normalization
            */
           } else if ( strncasecmp( val->bv_val, "group", STRLENOF( "group" ) ) == 0 )
           {
                   struct berval   group_dn = BER_BVNULL,
                                   group_oc = BER_BVNULL,
                                   member_at = BER_BVNULL,
                                   out = BER_BVNULL;
                   char            *ptr;
   
                   bv.bv_val = val->bv_val + STRLENOF( "group" );
                   bv.bv_len = val->bv_len - STRLENOF( "group" );
                   group_dn.bv_val = ber_bvchr( &bv, ':' );
                   if ( group_dn.bv_val == NULL ) {
                           /* last chance: assume it's a(n exact) DN ... */
                           bv.bv_val = val->bv_val;
                           scope = LDAP_X_SCOPE_EXACT;
                           goto is_dn;
                   }
   
                   /*
                    * FIXME: we assume that "member" and "groupOfNames"
                    * are present in schema...
                    */
                   if ( bv.bv_val[ 0 ] == '/' ) {
                           ObjectClass             *oc = NULL;
   
                           group_oc.bv_val = &bv.bv_val[ 1 ];
                           group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
   
                           member_at.bv_val = ber_bvchr( &group_oc, '/' );
                           if ( member_at.bv_val ) {
                                   AttributeDescription    *ad = NULL;
                                   const char              *text = NULL;
   
                                   group_oc.bv_len = member_at.bv_val - group_oc.bv_val;
                                   member_at.bv_val++;
                                   member_at.bv_len = group_dn.bv_val - member_at.bv_val;
                                   rc = slap_bv2ad( &member_at, &ad, &text );
                                   if ( rc != LDAP_SUCCESS ) {
                                           return rc;
                                   }
   
                                   member_at = ad->ad_cname;
   
                           }
   
                           oc = oc_bvfind( &group_oc );
                           if ( oc == NULL ) {
                                   return LDAP_INVALID_SYNTAX;
                           }
   
                           group_oc = oc->soc_cname;
                   }
   
                   group_dn.bv_val++;
                   group_dn.bv_len = val->bv_len - ( group_dn.bv_val - val->bv_val );
   
                   if ( normalize ) {
                           rc = dnNormalize( 0, NULL, NULL, &group_dn, &out, ctx );
                   } else {
                           rc = dnPretty( NULL, &group_dn, &out, ctx );
                   }
                   if ( rc != LDAP_SUCCESS ) {
                           return rc;
                   }
   
                   normalized->bv_len = STRLENOF( "group" ":" ) + out.bv_len;
                   if ( !BER_BVISNULL( &group_oc ) ) {
                           normalized->bv_len += STRLENOF( "/" ) + group_oc.bv_len;
                           if ( !BER_BVISNULL( &member_at ) ) {
                                   normalized->bv_len += STRLENOF( "/" ) + member_at.bv_len;
                           }
                   }
   
                   normalized->bv_val = ber_memalloc_x( normalized->bv_len + 1, ctx );
                   ptr = lutil_strcopy( normalized->bv_val, "group" );
                   if ( !BER_BVISNULL( &group_oc ) ) {
                           ptr[ 0 ] = '/';
                           ptr++;
                           ptr = lutil_strncopy( ptr, group_oc.bv_val, group_oc.bv_len );
                           if ( !BER_BVISNULL( &member_at ) ) {
                                   ptr[ 0 ] = '/';
                                   ptr++;
                                   ptr = lutil_strncopy( ptr, member_at.bv_val, member_at.bv_len );
                           }
                   }
                   ptr[ 0 ] = ':';
                   ptr++;
                   ptr = lutil_strncopy( ptr, out.bv_val, out.bv_len );
                   ptr[ 0 ] = '\0';
                   ber_memfree_x( out.bv_val, ctx );
   
                   return rc;
           }
   
           /*
            * ldap:///<base>??<scope>?<filter>
            * <scope> ::= {base|one|subtree}
            *
            * <scope> defaults to "base"
            * <base> must pass DN normalization
            * <filter> must pass str2filter()
            */
           rc = ldap_url_parse( val->bv_val, &ludp );
           switch ( rc ) {
           case LDAP_URL_SUCCESS:
                   /* FIXME: the check is pedantic, but I think it's necessary,
                    * because people tend to use things like ldaps:// which
                    * gives the idea SSL is being used.  Maybe we could
                    * accept ldapi:// as well, but the point is that we use
                    * an URL as an easy means to define bits of a search with
                    * little parsing.
                    */
                   if ( strcasecmp( ludp->lud_scheme, "ldap" ) != 0 ) {
                           /*
                            * must be ldap:///
                            */
                           rc = LDAP_INVALID_SYNTAX;
                           goto done;
                   }
   
                   AC_MEMCPY( ludp->lud_scheme, "ldap", STRLENOF( "ldap" ) );
                   break;
   
           case LDAP_URL_ERR_BADSCHEME:
                   /*
                    * last chance: assume it's a(n exact) DN ...
                    *
                    * NOTE: must pass DN normalization
                    */
                   ldap_free_urldesc( ludp );
                   bv.bv_val = val->bv_val;
                   scope = LDAP_X_SCOPE_EXACT;
                   goto is_dn;
   
           default:
                   rc = LDAP_INVALID_SYNTAX;
                   goto done;
           }
   
           if ( ( ludp->lud_host && *ludp->lud_host )
                   || ludp->lud_attrs || ludp->lud_exts )
           {
                   /* host part must be empty */
                   /* attrs and extensions parts must be empty */
                   rc = LDAP_INVALID_SYNTAX;
                   goto done;
           }
   
           /* Grab the filter */
           if ( ludp->lud_filter ) {
                   struct berval   filterstr;
                   Filter          *f;
   
                   lud_filter = ludp->lud_filter;
   
                   f = str2filter( lud_filter );
                   if ( f == NULL ) {
                           rc = LDAP_INVALID_SYNTAX;
                           goto done;
                   }
                   filter2bv( f, &filterstr );
                   filter_free( f );
                   if ( BER_BVISNULL( &filterstr ) ) {
                           rc = LDAP_INVALID_SYNTAX;
                           goto done;
                   }
   
                   ludp->lud_filter = filterstr.bv_val;
           }
   
           /* Grab the searchbase */
           assert( ludp->lud_dn != NULL );
           if ( ludp->lud_dn ) {
                   struct berval   out = BER_BVNULL;
   
                   lud_dn = ludp->lud_dn;
   
                   ber_str2bv( lud_dn, 0, 0, &bv );
                   if ( normalize ) {
                           rc = dnNormalize( 0, NULL, NULL, &bv, &out, ctx );
                   } else {
                           rc = dnPretty( NULL, &bv, &out, ctx );
                   }
   
                   if ( rc != LDAP_SUCCESS ) {
                           goto done;
                   }
   
                   ludp->lud_dn = out.bv_val;
           }
   
           ludp->lud_port = 0;
           normalized->bv_val = ldap_url_desc2str( ludp );
           if ( normalized->bv_val ) {
                   normalized->bv_len = strlen( normalized->bv_val );
   
           } else {
                   rc = LDAP_INVALID_SYNTAX;
           }
   
   done:
           if ( lud_filter ) {
                   if ( ludp->lud_filter != lud_filter ) {
                           ber_memfree( ludp->lud_filter );
                   }
                   ludp->lud_filter = lud_filter;
           }
   
           if ( lud_dn ) {
                   if ( ludp->lud_dn != lud_dn ) {
                           ber_memfree( ludp->lud_dn );
                   }
                   ludp->lud_dn = lud_dn;
           }
   
           ldap_free_urldesc( ludp );
   
           return( rc );
   }
   
   int
   authzNormalize(
           slap_mask_t     usage,
           Syntax          *syntax,
           MatchingRule    *mr,
           struct berval   *val,
           struct berval   *normalized,
           void            *ctx )
   {
           int             rc;
   
           Debug( LDAP_DEBUG_TRACE, ">>> authzNormalize: <%s>\n",
                   val->bv_val, 0, 0 );
   
           rc = authzPrettyNormal( val, normalized, ctx, 1 );
   
           Debug( LDAP_DEBUG_TRACE, "<<< authzNormalize: <%s> (%d)\n",
                   normalized->bv_val, rc, 0 );
   
           return rc;
   }
   
   int
   authzPretty(
           Syntax *syntax,
           struct berval *val,
           struct berval *out,
           void *ctx)
   {
           int             rc;
   
           Debug( LDAP_DEBUG_TRACE, ">>> authzPretty: <%s>\n",
                   val->bv_val, 0, 0 );
   
           rc = authzPrettyNormal( val, out, ctx, 0 );
   
           Debug( LDAP_DEBUG_TRACE, "<<< authzPretty: <%s> (%d)\n",
                   out->bv_val, rc, 0 );
   
           return rc;
   }
   
   #endif /* SLAP_AUTHZ_SYNTAX */
   
   static int
   slap_parseURI(
           Operation       *op,
           struct berval   *uri,
           struct berval   *base,
           struct berval   *nbase,
           int             *scope,
           Filter          **filter,
           struct berval   *fstr,
           int             normalize )
   {
           struct berval   bv;
           int             rc;
           LDAPURLDesc     *ludp;
   
   #ifdef SLAP_ORDERED_PRETTYNORM
           struct berval   idx;
   #endif /* SLAP_ORDERED_PRETTYNORM */
   
         assert( uri != NULL && !BER_BVISNULL( uri ) );          assert( uri != NULL && !BER_BVISNULL( uri ) );
         BER_BVZERO( base );          BER_BVZERO( base );
Line 209  static int slap_parseURI( Operation *op, Line 951  static int slap_parseURI( Operation *op,
                 "slap_parseURI: parsing %s\n", uri->bv_val, 0, 0 );                  "slap_parseURI: parsing %s\n", uri->bv_val, 0, 0 );
   
         rc = LDAP_PROTOCOL_ERROR;          rc = LDAP_PROTOCOL_ERROR;
   
   #ifdef SLAP_ORDERED_PRETTYNORM
           idx = *uri;
           if ( idx.bv_val[ 0 ] == '{' ) {
                   char    *ptr;
   
                   ptr = ber_bvchr( &idx, '}' ) + 1;
   
                   assert( ptr != (void *)1 );
   
                   idx.bv_len -= ptr - idx.bv_val;
                   idx.bv_val = ptr;
                   uri = &idx;
           }
   #endif /* SLAP_ORDERED_PRETTYNORM */
   
         /*          /*
          * dn[.<dnstyle>]:<dnpattern>           * dn[.<dnstyle>]:<dnpattern>
          * <dnstyle> ::= {exact|regex|children|subtree|onelevel}           * <dnstyle> ::= {exact|regex|children|subtree|onelevel}
Line 269  is_dn:  bv.bv_len = uri->bv_len - (bv.bv Line 1027  is_dn:  bv.bv_len = uri->bv_len - (bv.bv
                 case LDAP_X_SCOPE_CHILDREN:                  case LDAP_X_SCOPE_CHILDREN:
                 case LDAP_X_SCOPE_SUBTREE:                  case LDAP_X_SCOPE_SUBTREE:
                 case LDAP_X_SCOPE_ONELEVEL:                  case LDAP_X_SCOPE_ONELEVEL:
                         rc = dnNormalize( 0, NULL, NULL, &bv, nbase, op->o_tmpmemctx );                          if ( normalize ) {
                         if( rc != LDAP_SUCCESS ) {                                  rc = dnNormalize( 0, NULL, NULL, &bv, nbase, op->o_tmpmemctx );
                                 *scope = -1;                                  if( rc != LDAP_SUCCESS ) {
                                           *scope = -1;
                                   }
                           } else {
                                   ber_dupbv_x( nbase, &bv, op->o_tmpmemctx );
                                   rc = LDAP_SUCCESS;
                         }                          }
                         break;                          break;
   
Line 348  is_dn:  bv.bv_len = uri->bv_len - (bv.bv Line 1111  is_dn:  bv.bv_len = uri->bv_len - (bv.bv
                 char            *tmp;                  char            *tmp;
   
                 bv.bv_val = uri->bv_val + STRLENOF( "group" );                  bv.bv_val = uri->bv_val + STRLENOF( "group" );
                 group_dn.bv_val = strchr( bv.bv_val, ':' );                  bv.bv_len = uri->bv_len - STRLENOF( "group" );
                   group_dn.bv_val = ber_bvchr( &bv, ':' );
                 if ( group_dn.bv_val == NULL ) {                  if ( group_dn.bv_val == NULL ) {
                         /* last chance: assume it's a(n exact) DN ... */                          /* last chance: assume it's a(n exact) DN ... */
                         bv.bv_val = uri->bv_val;                          bv.bv_val = uri->bv_val;
Line 358  is_dn:  bv.bv_len = uri->bv_len - (bv.bv Line 1122  is_dn:  bv.bv_len = uri->bv_len - (bv.bv
                                   
                 if ( bv.bv_val[ 0 ] == '/' ) {                  if ( bv.bv_val[ 0 ] == '/' ) {
                         group_oc.bv_val = &bv.bv_val[ 1 ];                          group_oc.bv_val = &bv.bv_val[ 1 ];
                           group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
   
                         member_at.bv_val = strchr( group_oc.bv_val, '/' );                          member_at.bv_val = ber_bvchr( &group_oc, '/' );
                         if ( member_at.bv_val ) {                          if ( member_at.bv_val ) {
                                 group_oc.bv_len = member_at.bv_val - group_oc.bv_val;                                  group_oc.bv_len = member_at.bv_val - group_oc.bv_val;
                                 member_at.bv_val++;                                  member_at.bv_val++;
                                 member_at.bv_len = group_dn.bv_val - member_at.bv_val;                                  member_at.bv_len = group_dn.bv_val - member_at.bv_val;
   
                         } else {                          } else {
                                 group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;                                  BER_BVSTR( &member_at, SLAPD_GROUP_ATTR );
                                 BER_BVSTR( &member_at, "member" );  
                         }                          }
   
                 } else {                  } else {
                         BER_BVSTR( &group_oc, "groupOfNames" );                          BER_BVSTR( &group_oc, SLAPD_GROUP_CLASS );
                 }                  }
                 group_dn.bv_val++;                  group_dn.bv_val++;
                 group_dn.bv_len = uri->bv_len - ( group_dn.bv_val - uri->bv_val );                  group_dn.bv_len = uri->bv_len - ( group_dn.bv_val - uri->bv_val );
   
                 rc = dnNormalize( 0, NULL, NULL, &group_dn, nbase, op->o_tmpmemctx );                  if ( normalize ) {
                 if ( rc != LDAP_SUCCESS ) {                          rc = dnNormalize( 0, NULL, NULL, &group_dn, nbase, op->o_tmpmemctx );
                         *scope = -1;                          if ( rc != LDAP_SUCCESS ) {
                         return rc;                                  *scope = -1;
                                   return rc;
                           }
                   } else {
                           ber_dupbv_x( nbase, &group_dn, op->o_tmpmemctx );
                           rc = LDAP_SUCCESS;
                 }                  }
                 *scope = LDAP_X_SCOPE_GROUP;                  *scope = LDAP_X_SCOPE_GROUP;
   
Line 422  is_dn:  bv.bv_len = uri->bv_len - (bv.bv Line 1191  is_dn:  bv.bv_len = uri->bv_len - (bv.bv
                         /*                          /*
                          * must be ldap:///                           * must be ldap:///
                          */                           */
                         return LDAP_PROTOCOL_ERROR;                          rc = LDAP_PROTOCOL_ERROR;
                           goto done;
                 }                  }
                 break;                  break;
   
Line 432  is_dn:  bv.bv_len = uri->bv_len - (bv.bv Line 1202  is_dn:  bv.bv_len = uri->bv_len - (bv.bv
                  *                   *
                  * NOTE: must pass DN normalization                   * NOTE: must pass DN normalization
                  */                   */
                   ldap_free_urldesc( ludp );
                 bv.bv_val = uri->bv_val;                  bv.bv_val = uri->bv_val;
                 *scope = LDAP_X_SCOPE_EXACT;                  *scope = LDAP_X_SCOPE_EXACT;
                 goto is_dn;                  goto is_dn;
   
         default:          default:
                 return LDAP_PROTOCOL_ERROR;                  rc = LDAP_PROTOCOL_ERROR;
                   goto done;
         }          }
   
         if ( ( ludp->lud_host && *ludp->lud_host )          if ( ( ludp->lud_host && *ludp->lud_host )
Line 464  is_dn:  bv.bv_len = uri->bv_len - (bv.bv Line 1236  is_dn:  bv.bv_len = uri->bv_len - (bv.bv
   
         /* Grab the searchbase */          /* Grab the searchbase */
         ber_str2bv( ludp->lud_dn, 0, 0, base );          ber_str2bv( ludp->lud_dn, 0, 0, base );
         rc = dnNormalize( 0, NULL, NULL, base, nbase, op->o_tmpmemctx );          if ( normalize ) {
                   rc = dnNormalize( 0, NULL, NULL, base, nbase, op->o_tmpmemctx );
           } else {
                   ber_dupbv_x( nbase, base, op->o_tmpmemctx );
                   rc = LDAP_SUCCESS;
           }
   
 done:  done:
         if( rc != LDAP_SUCCESS ) {          if( rc != LDAP_SUCCESS ) {
Line 481  done: Line 1258  done:
         return( rc );          return( rc );
 }  }
   
   #ifndef SLAP_AUTH_REWRITE
 static int slap_sasl_rx_off(char *rep, int *off)  static int slap_sasl_rx_off(char *rep, int *off)
 {  {
         const char *c;          const char *c;
Line 514  static int slap_sasl_rx_off(char *rep, i Line 1292  static int slap_sasl_rx_off(char *rep, i
         off[n] = -1;          off[n] = -1;
         return( LDAP_SUCCESS );          return( LDAP_SUCCESS );
 }  }
   #endif /* ! SLAP_AUTH_REWRITE */
   
 #ifdef SLAP_AUTH_REWRITE  #ifdef SLAP_AUTH_REWRITE
 int slap_sasl_rewrite_config(   int slap_sasl_rewrite_config( 
Line 592  int slap_sasl_regexp_rewrite_config( Line 1371  int slap_sasl_regexp_rewrite_config(
   
 int slap_sasl_regexp_config( const char *match, const char *replace )  int slap_sasl_regexp_config( const char *match, const char *replace )
 {  {
 #ifdef SLAP_AUTH_REWRITE  
         return slap_sasl_regexp_rewrite_config( "sasl-regexp", 0,  
                         match, replace, AUTHID_CONTEXT );  
 #else /* ! SLAP_AUTH_REWRITE */  
         int rc;          int rc;
         SaslRegexp_t *reg;          SaslRegexp_t *reg;
   
Line 607  int slap_sasl_regexp_config( const char Line 1382  int slap_sasl_regexp_config( const char
         reg->sr_match = ch_strdup( match );          reg->sr_match = ch_strdup( match );
         reg->sr_replace = ch_strdup( replace );          reg->sr_replace = ch_strdup( replace );
   
   #ifdef SLAP_AUTH_REWRITE
           rc = slap_sasl_regexp_rewrite_config( "sasl-regexp", 0,
                           match, replace, AUTHID_CONTEXT );
           if ( rc == LDAP_SUCCESS ) nSaslRegexp++;
           return rc;
   #else /* ! SLAP_AUTH_REWRITE */
   
         /* Precompile matching pattern */          /* Precompile matching pattern */
         rc = regcomp( &reg->sr_workspace, reg->sr_match, REG_EXTENDED|REG_ICASE );          rc = regcomp( &reg->sr_workspace, reg->sr_match, REG_EXTENDED|REG_ICASE );
         if ( rc ) {          if ( rc ) {
Line 614  int slap_sasl_regexp_config( const char Line 1396  int slap_sasl_regexp_config( const char
                 "SASL match pattern %s could not be compiled by regexp engine\n",                  "SASL match pattern %s could not be compiled by regexp engine\n",
                 reg->sr_match, 0, 0 );                  reg->sr_match, 0, 0 );
   
   #ifdef ENABLE_REWRITE
           /* Dummy block to force symbol references in librewrite */
           if ( slapMode == ( SLAP_SERVER_MODE|SLAP_TOOL_MODE )) {
                   rewrite_info_init( 0 );
           }
   #endif
                 return( LDAP_OTHER );                  return( LDAP_OTHER );
         }          }
   
Line 625  int slap_sasl_regexp_config( const char Line 1413  int slap_sasl_regexp_config( const char
 #endif /* ! SLAP_AUTH_REWRITE */  #endif /* ! SLAP_AUTH_REWRITE */
 }  }
   
   void slap_sasl_regexp_unparse( BerVarray *out )
   {
           int i;
           BerVarray bva = NULL;
           char ibuf[32], *ptr;
           struct berval idx;
   
           if ( !nSaslRegexp ) return;
   
           idx.bv_val = ibuf;
           bva = ch_malloc( (nSaslRegexp+1) * sizeof(struct berval) );
           BER_BVZERO(bva+nSaslRegexp);
           for ( i=0; i<nSaslRegexp; i++ ) {
                   idx.bv_len = sprintf( idx.bv_val, "{%d}", i);
                   bva[i].bv_len = idx.bv_len + strlen( SaslRegexp[i].sr_match ) +
                           strlen( SaslRegexp[i].sr_replace ) + 5;
                   bva[i].bv_val = ch_malloc( bva[i].bv_len+1 );
                   ptr = lutil_strcopy( bva[i].bv_val, ibuf );
                   *ptr++ = '"';
                   ptr = lutil_strcopy( ptr, SaslRegexp[i].sr_match );
                   ptr = lutil_strcopy( ptr, "\" \"" );
                   ptr = lutil_strcopy( ptr, SaslRegexp[i].sr_replace );
                   *ptr++ = '"';
                   *ptr = '\0';
           }
           *out = bva;
   }
   
   #ifndef SLAP_AUTH_REWRITE
 /* Perform replacement on regexp matches */  /* Perform replacement on regexp matches */
 static void slap_sasl_rx_exp(  static void slap_sasl_rx_exp(
         const char *rep,          const char *rep,
Line 676  static void slap_sasl_rx_exp( Line 1493  static void slap_sasl_rx_exp(
   
         out->bv_val[insert] = '\0';          out->bv_val[insert] = '\0';
 }  }
   #endif /* ! SLAP_AUTH_REWRITE */
   
 /* Take the passed in SASL name and attempt to convert it into an  /* Take the passed in SASL name and attempt to convert it into an
    LDAP URI to find the matching LDAP entry, using the pattern matching     LDAP URI to find the matching LDAP entry, using the pattern matching
Line 700  static int slap_authz_regexp( struct ber Line 1518  static int slap_authz_regexp( struct ber
                 if ( !BER_BVISNULL( out ) ) {                  if ( !BER_BVISNULL( out ) ) {
                         char *val = out->bv_val;                          char *val = out->bv_val;
                         ber_str2bv_x( val, 0, 1, out, ctx );                          ber_str2bv_x( val, 0, 1, out, ctx );
                         free( val );                          if ( val != in->bv_val ) {
                                   free( val );
                           }
                 } else {                  } else {
                         ber_dupbv_x( out, in, ctx );                          ber_dupbv_x( out, in, ctx );
                 }                  }
Line 835  slap_sasl_matches( Operation *op, BerVar Line 1655  slap_sasl_matches( Operation *op, BerVar
  * The assertDN should not have the dn: prefix   * The assertDN should not have the dn: prefix
  */   */
   
 static  static int
 int slap_sasl_match( Operation *opx, struct berval *rule,  slap_sasl_match( Operation *opx, struct berval *rule,
         struct berval *assertDN, struct berval *authc )          struct berval *assertDN, struct berval *authc )
 {  {
         int rc;           int rc; 
Line 855  int slap_sasl_match( Operation *opx, str Line 1675  int slap_sasl_match( Operation *opx, str
            "===>slap_sasl_match: comparing DN %s to rule %s\n",             "===>slap_sasl_match: comparing DN %s to rule %s\n",
                 assertDN->bv_val, rule->bv_val, 0 );                  assertDN->bv_val, rule->bv_val, 0 );
   
         rc = slap_parseURI( opx, rule, &base,          /* NOTE: don't normalize rule if authz syntax is enabled */
                 &op.o_req_ndn, &op.ors_scope, &op.ors_filter,          rc = slap_parseURI( opx, rule, &base, &op.o_req_ndn,
                 &op.ors_filterstr );                  &op.ors_scope, &op.ors_filter, &op.ors_filterstr, 
   #ifdef SLAP_AUTHZ_SYNTAX
                   0
   #else /* ! SLAP_AUTHZ_SYNTAX */
                   1
   #endif /* ! SLAP_AUTHZ_SYNTAX */
                   );
   
         if( rc != LDAP_SUCCESS ) goto CONCLUDED;          if( rc != LDAP_SUCCESS ) goto CONCLUDED;
   
         switch ( op.ors_scope ) {          switch ( op.ors_scope ) {
Line 1003  exact_match: Line 1830  exact_match:
         op.o_tag = LDAP_REQ_SEARCH;          op.o_tag = LDAP_REQ_SEARCH;
         op.o_ndn = *authc;          op.o_ndn = *authc;
         op.o_callback = &cb;          op.o_callback = &cb;
         op.o_time = slap_get_time();          slap_op_time( &op.o_time, &op.o_tincr );
         op.o_do_not_cache = 1;          op.o_do_not_cache = 1;
         op.o_is_auth_check = 1;          op.o_is_auth_check = 1;
         /* use req_ndn as req_dn instead of non-pretty base of uri */          /* use req_ndn as req_dn instead of non-pretty base of uri */
Line 1013  exact_match: Line 1840  exact_match:
                 BER_BVZERO( &base );                  BER_BVZERO( &base );
         }          }
         ber_dupbv_x( &op.o_req_dn, &op.o_req_ndn, op.o_tmpmemctx );          ber_dupbv_x( &op.o_req_dn, &op.o_req_ndn, op.o_tmpmemctx );
           op.ors_deref = LDAP_DEREF_NEVER;
         op.ors_slimit = 1;          op.ors_slimit = 1;
         op.ors_tlimit = SLAP_NO_LIMIT;          op.ors_tlimit = SLAP_NO_LIMIT;
         op.ors_attrs = slap_anlist_no_attrs;          op.ors_attrs = slap_anlist_no_attrs;
Line 1054  slap_sasl_check_authz( Operation *op, Line 1882  slap_sasl_check_authz( Operation *op,
         AttributeDescription *ad,          AttributeDescription *ad,
         struct berval *authc )          struct berval *authc )
 {  {
         int i, rc;          int rc;
         BerVarray vals = NULL;          BerVarray vals = NULL;
   
         Debug( LDAP_DEBUG_TRACE,          Debug( LDAP_DEBUG_TRACE,
Line 1085  COMPLETE: Line 1913  COMPLETE:
  * an internal search must be done, and if that search returns exactly one   * an internal search must be done, and if that search returns exactly one
  * entry, return the DN of that one entry.   * entry, return the DN of that one entry.
  */   */
 void slap_sasl2dn( Operation *opx,  void
         struct berval *saslname, struct berval *sasldn, int flags )  slap_sasl2dn(
           Operation       *opx,
           struct berval   *saslname,
           struct berval   *sasldn,
           int             flags )
 {  {
         int rc;          int rc;
         slap_callback cb = { NULL, sasl_sc_sasl2dn, NULL, NULL };          slap_callback cb = { NULL, sasl_sc_sasl2dn, NULL, NULL };
Line 1099  void slap_sasl2dn( Operation *opx, Line 1931  void slap_sasl2dn( Operation *opx,
                 "converting SASL name %s to a DN\n",                  "converting SASL name %s to a DN\n",
                 saslname->bv_val, 0,0 );                  saslname->bv_val, 0,0 );
   
         sasldn->bv_val = NULL;          BER_BVZERO( sasldn );
         sasldn->bv_len = 0;  
         cb.sc_private = sasldn;          cb.sc_private = sasldn;
   
         /* Convert the SASL name into a minimal URI */          /* Convert the SASL name into a minimal URI */
Line 1108  void slap_sasl2dn( Operation *opx, Line 1939  void slap_sasl2dn( Operation *opx,
                 goto FINISHED;                  goto FINISHED;
         }          }
   
         rc = slap_parseURI( opx, &regout, &base,          /* NOTE: always normalize regout because it results
                 &op.o_req_ndn, &op.ors_scope, &op.ors_filter,           * from string submatch expansion */
                 &op.ors_filterstr );          rc = slap_parseURI( opx, &regout, &base, &op.o_req_ndn,
                   &op.ors_scope, &op.ors_filter, &op.ors_filterstr, 1 );
         if ( !BER_BVISNULL( &regout ) ) slap_sl_free( regout.bv_val, opx->o_tmpmemctx );          if ( !BER_BVISNULL( &regout ) ) slap_sl_free( regout.bv_val, opx->o_tmpmemctx );
         if ( rc != LDAP_SUCCESS ) {          if ( rc != LDAP_SUCCESS ) {
                 goto FINISHED;                  goto FINISHED;
Line 1137  void slap_sasl2dn( Operation *opx, Line 1969  void slap_sasl2dn( Operation *opx,
         case LDAP_SCOPE_BASE:          case LDAP_SCOPE_BASE:
         case LDAP_SCOPE_ONELEVEL:          case LDAP_SCOPE_ONELEVEL:
         case LDAP_SCOPE_SUBTREE:          case LDAP_SCOPE_SUBTREE:
 #ifdef LDAP_SCOPE_SUBORDINATE  
         case LDAP_SCOPE_SUBORDINATE:          case LDAP_SCOPE_SUBORDINATE:
 #endif  
                 /* do a search */                  /* do a search */
                 break;                  break;
   
Line 1166  void slap_sasl2dn( Operation *opx, Line 1996  void slap_sasl2dn( Operation *opx,
         op.o_tag = LDAP_REQ_SEARCH;          op.o_tag = LDAP_REQ_SEARCH;
         op.o_ndn = opx->o_conn->c_ndn;          op.o_ndn = opx->o_conn->c_ndn;
         op.o_callback = &cb;          op.o_callback = &cb;
         op.o_time = slap_get_time();          slap_op_time( &op.o_time, &op.o_tincr );
         op.o_do_not_cache = 1;          op.o_do_not_cache = 1;
         op.o_is_auth_check = 1;          op.o_is_auth_check = 1;
         op.ors_deref = LDAP_DEREF_NEVER;          op.ors_deref = LDAP_DEREF_NEVER;

Removed from v.1.144  
changed lines
  Added in v.1.144.2.11


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org