Diff for /servers/slapd/saslauthz.c between versions 1.88 and 1.88.2.17

version 1.88, 2003/05/25 01:56:58 version 1.88.2.17, 2004/06/16 18:19:56
Line 1 Line 1
 /* $OpenLDAP$ */  /* $OpenLDAP: pkg/ldap/servers/slapd/saslauthz.c,v 1.88.2.16 2004/06/04 03:39:43 kurt Exp $ */
 /*  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.  
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file  
  */  
 /*  
  * Copyright (c) 2000, Mark Adamson, Carnegie Mellon.  All rights reserved.  
  * This software is not subject to any license of Carnegie Mellon University.  
  *   *
  * Redistribution and use in source and binary forms are permitted without    * Copyright 1998-2004 The OpenLDAP Foundation.
  * restriction or fee of any kind as long as this notice is preserved.   * Portions Copyright 2000 Mark Adamson, Carnegie Mellon.
    * All rights reserved.
  *   *
  * The name "Carnegie Mellon" must not be used to endorse or promote   * Redistribution and use in source and binary forms, with or without
  * products derived from this software without prior written permission.   * modification, are permitted only as authorized by the OpenLDAP
    * Public License.
  *   *
    * A copy of this license is available in the file LICENSE in the
    * top-level directory of the distribution or, alternatively, at
    * <http://www.OpenLDAP.org/license.html>.
  */   */
   
 #include "portable.h"  #include "portable.h"
Line 30 Line 29
   
 #define SASLREGEX_REPLACE 10  #define SASLREGEX_REPLACE 10
   
   #define LDAP_X_SCOPE_EXACT      ((ber_int_t) 0x0010)
   #define LDAP_X_SCOPE_REGEX      ((ber_int_t) 0x0020)
   #define LDAP_X_SCOPE_CHILDREN   ((ber_int_t) 0x0030)
   #define LDAP_X_SCOPE_SUBTREE    ((ber_int_t) 0x0040)
   #define LDAP_X_SCOPE_ONELEVEL   ((ber_int_t) 0x0050)
   
   /*
    * IDs in DNauthzid form can now have a type specifier, that
    * influences how they are used in related operations.
    *
    * syntax: dn[.{exact|regex}]:<val>
    *
    * dn.exact:    the value must pass normalization and is used 
    *              in exact DN match.
    * dn.regex:    the value is treated as a regular expression 
    *              in matching DN values in saslAuthz{To|From}
    *              attributes.
    * dn:          for backwards compatibility reasons, the value 
    *              is treated as a regular expression, and thus 
    *              it is not normalized nor validated; it is used
    *              in exact or regex comparisons based on the 
    *              context.
    *
    * IDs in DNauthzid form can now have a type specifier, that
    * influences how they are used in related operations.
    *
    * syntax: u[.mech[/realm]]:<val>
    * 
    * where mech is a SIMPLE, AUTHZ, or a SASL mechanism name
    * and realm is mechanism specific realm (separate to those
    * which are representable as part of the principal).
    */
   
 typedef struct sasl_regexp {  typedef struct sasl_regexp {
   char *sr_match;                                                       /* regexp match pattern */    char *sr_match;                                               /* regexp match pattern */
   char *sr_replace;                                             /* regexp replace pattern */    char *sr_replace;                                     /* regexp replace pattern */
   regex_t sr_workspace;                                         /* workspace for regexp engine */    regex_t sr_workspace;                                 /* workspace for regexp engine */
   int sr_offset[SASLREGEX_REPLACE+2];           /* offsets of $1,$2... in *replace */    int sr_offset[SASLREGEX_REPLACE+2];   /* offsets of $1,$2... in *replace */
 } SaslRegexp_t;  } SaslRegexp_t;
   
 static int nSaslRegexp = 0;  static int nSaslRegexp = 0;
 static SaslRegexp_t *SaslRegexp = NULL;  static SaslRegexp_t *SaslRegexp = NULL;
   
 /* What SASL proxy authorization policies are allowed? */  /* What SASL proxy authorization policies are allowed? */
 #define SASL_AUTHZ_NONE 0  #define SASL_AUTHZ_NONE 0x00
 #define SASL_AUTHZ_FROM 1  #define SASL_AUTHZ_FROM 0x01
 #define SASL_AUTHZ_TO   2  #define SASL_AUTHZ_TO   0x02
   #define SASL_AUTHZ_AND  0x10
   
 static int authz_policy = SASL_AUTHZ_NONE;  static int authz_policy = SASL_AUTHZ_NONE;
   
Line 57  int slap_sasl_setpolicy( const char *arg Line 90  int slap_sasl_setpolicy( const char *arg
                 authz_policy = SASL_AUTHZ_FROM;                  authz_policy = SASL_AUTHZ_FROM;
         } else if ( strcasecmp( arg, "to" ) == 0 ) {          } else if ( strcasecmp( arg, "to" ) == 0 ) {
                 authz_policy = SASL_AUTHZ_TO;                  authz_policy = SASL_AUTHZ_TO;
         } else if ( strcasecmp( arg, "both" ) == 0 ) {          } else if ( strcasecmp( arg, "both" ) == 0 || strcasecmp( arg, "any" ) == 0 ) {
                 authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO;                  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 {          } else {
                 rc = LDAP_OTHER;                  rc = LDAP_OTHER;
         }          }
         return rc;          return rc;
 }  }
   
 /* URI format: ldap://<host>/<base>[?[<attrs>][?[<scope>][?[<filter>]]]] */  int slap_parse_user( struct berval *id, struct berval *user,
                   struct berval *realm, struct berval *mech )
   {
           char    u;
           
           assert( id );
           assert( id->bv_val );
           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 ( user->bv_val == NULL ) {
                   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 ( mech->bv_val != NULL ) {
                   mech->bv_val[ 0 ] = '\0';
                   mech->bv_val++;
   
                   realm->bv_val = strchr( mech->bv_val, '/' );
   
                   if ( realm->bv_val ) {
                           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 {
                   realm->bv_val = NULL;
           }
   
           if ( id->bv_val[ 1 ] != '\0' ) {
                   return LDAP_PROTOCOL_ERROR;
           }
   
           if ( mech->bv_val != NULL ) {
                   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 ( realm->bv_val ) {
                   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,  static int slap_parseURI( Operation *op, struct berval *uri,
         struct berval *searchbase, int *scope, Filter **filter )          struct berval *base, struct berval *nbase,
           int *scope, Filter **filter, struct berval *fstr )
 {  {
         struct berval bv;          struct berval bv;
         int rc;          int rc;
         LDAPURLDesc *ludp;          LDAPURLDesc *ludp;
   
         assert( uri != NULL && uri->bv_val != NULL );          assert( uri != NULL && uri->bv_val != NULL );
         searchbase->bv_val = NULL;          base->bv_val = NULL;
         searchbase->bv_len = 0;          base->bv_len = 0;
           nbase->bv_val = NULL;
           nbase->bv_len = 0;
           fstr->bv_val = NULL;
           fstr->bv_len = 0;
         *scope = -1;          *scope = -1;
         *filter = NULL;          *filter = NULL;
   
Line 84  static int slap_parseURI( Operation *op, Line 199  static int slap_parseURI( Operation *op,
         LDAP_LOG( TRANSPORT, ENTRY,           LDAP_LOG( TRANSPORT, ENTRY, 
                 "slap_parseURI: parsing %s\n", uri->bv_val, 0, 0 );                  "slap_parseURI: parsing %s\n", uri->bv_val, 0, 0 );
 #else  #else
         Debug( LDAP_DEBUG_TRACE, "slap_parseURI: parsing %s\n", uri->bv_val, 0, 0 );          Debug( LDAP_DEBUG_TRACE,
                   "slap_parseURI: parsing %s\n", uri->bv_val, 0, 0 );
 #endif  #endif
   
         /* If it does not look like a URI, assume it is a DN */          rc = LDAP_PROTOCOL_ERROR;
         if( !strncasecmp( uri->bv_val, "dn:", sizeof("dn:")-1 ) ) {          if ( !strncasecmp( uri->bv_val, "dn", sizeof( "dn" ) - 1 ) ) {
                 bv.bv_val = uri->bv_val + sizeof("dn:")-1;                  bv.bv_val = uri->bv_val + sizeof( "dn" ) - 1;
   
                   if ( bv.bv_val[ 0 ] == '.' ) {
                           bv.bv_val++;
   
                           if ( !strncasecmp( bv.bv_val, "exact:", sizeof( "exact:" ) - 1 ) ) {
                                   bv.bv_val += sizeof( "exact:" ) - 1;
                                   *scope = LDAP_X_SCOPE_EXACT;
   
                           } else if ( !strncasecmp( bv.bv_val, "regex:", sizeof( "regex:" ) - 1 ) ) {
                                   bv.bv_val += sizeof( "regex:" ) - 1;
                                   *scope = LDAP_X_SCOPE_REGEX;
   
                           } else if ( !strncasecmp( bv.bv_val, "children:", sizeof( "chldren:" ) - 1 ) ) {
                                   bv.bv_val += sizeof( "children:" ) - 1;
                                   *scope = LDAP_X_SCOPE_CHILDREN;
   
                           } else if ( !strncasecmp( bv.bv_val, "subtree:", sizeof( "subtree:" ) - 1 ) ) {
                                   bv.bv_val += sizeof( "subtree:" ) - 1;
                                   *scope = LDAP_X_SCOPE_SUBTREE;
   
                           } else if ( !strncasecmp( bv.bv_val, "onelevel:", sizeof( "onelevel:" ) - 1 ) ) {
                                   bv.bv_val += sizeof( "onelevel:" ) - 1;
                                   *scope = LDAP_X_SCOPE_ONELEVEL;
   
                           } else {
                                   return LDAP_PROTOCOL_ERROR;
                           }
                   } else {
                           if ( bv.bv_val[ 0 ] != ':' ) {
                                   return LDAP_PROTOCOL_ERROR;
                           }
                           *scope = LDAP_X_SCOPE_EXACT;
                           bv.bv_val++;
                   }
   
                 bv.bv_val += strspn( bv.bv_val, " " );                  bv.bv_val += strspn( bv.bv_val, " " );
                   /* jump here in case no type specification was present
                    * and uir was not an URI... HEADS-UP: assuming EXACT */
   is_dn:          bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
   
                   switch ( *scope ) {
                   case LDAP_X_SCOPE_EXACT:
                   case LDAP_X_SCOPE_CHILDREN:
                   case LDAP_X_SCOPE_SUBTREE:
                   case LDAP_X_SCOPE_ONELEVEL:
                           rc = dnNormalize( 0, NULL, NULL, &bv, nbase, op->o_tmpmemctx );
                           if( rc != LDAP_SUCCESS ) {
                                   *scope = -1;
                           }
                           break;
   
 is_dn:  bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);                  case LDAP_X_SCOPE_REGEX:
                           ber_dupbv_x( nbase, &bv, op->o_tmpmemctx );
                           rc = LDAP_SUCCESS;
                           break;
   
                 rc = dnNormalize( 0, NULL, NULL, &bv, searchbase, op->o_tmpmemctx );                  default:
                 if( rc == LDAP_SUCCESS ) {                          *scope = -1;
                         *scope = LDAP_SCOPE_BASE;                          break;
                 }                  }
                 return( rc );  
         }  
   
                   return rc;
   
           } else if ( ( uri->bv_val[ 0 ] == 'u' || uri->bv_val[ 0 ] == 'U' )
                           && ( uri->bv_val[ 1 ] == ':' 
                                   || uri->bv_val[ 1 ] == '/' 
                                   || uri->bv_val[ 1 ] == '.' ) )
           {
                   Connection      c = *op->o_conn;
                   char            buf[ SLAP_LDAPDN_MAXLEN ];
                   struct berval   id,
                                   user = BER_BVNULL,
                                   realm = BER_BVNULL,
                                   mech = BER_BVNULL;
   
                   if ( sizeof( buf ) <= uri->bv_len ) {
                           return LDAP_INVALID_SYNTAX;
                   }
   
                   id.bv_len = uri->bv_len;
                   id.bv_val = buf;
                   strncpy( buf, uri->bv_val, sizeof( buf ) );
   
                   rc = slap_parse_user( &id, &user, &realm, &mech );
                   if ( rc != LDAP_SUCCESS ) {
                           return rc;
                   }
   
                   if ( mech.bv_val ) {
                           c.c_sasl_bind_mech = mech;
                   } else {
                           c.c_sasl_bind_mech.bv_val = "AUTHZ";
                           c.c_sasl_bind_mech.bv_len = sizeof( "AUTHZ" ) - 1;
                   }
                   
                   rc = slap_sasl_getdn( &c, op, user.bv_val, user.bv_len,
                                   realm.bv_val, nbase, SLAP_GETDN_AUTHZID );
   
                   if ( rc == LDAP_SUCCESS ) {
                           *scope = LDAP_X_SCOPE_EXACT;
                   }
   
                   return rc;
           }
                   
         rc = ldap_url_parse( uri->bv_val, &ludp );          rc = ldap_url_parse( uri->bv_val, &ludp );
         if ( rc == LDAP_URL_ERR_BADSCHEME ) {          if ( rc == LDAP_URL_ERR_BADSCHEME ) {
                   /* last chance: assume it's a(n exact) DN ... */
                 bv.bv_val = uri->bv_val;                  bv.bv_val = uri->bv_val;
                   *scope = LDAP_X_SCOPE_EXACT;
                 goto is_dn;                  goto is_dn;
         }          }
   
Line 114  is_dn: bv.bv_len = uri->bv_len - (bv.bv_ Line 326  is_dn: bv.bv_len = uri->bv_len - (bv.bv_
         if (( ludp->lud_host && *ludp->lud_host )          if (( ludp->lud_host && *ludp->lud_host )
                 || ludp->lud_attrs || ludp->lud_exts )                  || ludp->lud_attrs || ludp->lud_exts )
         {          {
                 /* host part should be empty */                  /* host part must be empty */
                 /* attrs and extensions parts should be empty */                  /* attrs and extensions parts must be empty */
                 return LDAP_PROTOCOL_ERROR;                  rc = LDAP_PROTOCOL_ERROR;
                   goto done;
         }          }
   
         /* Grab the scope */          /* Grab the scope */
Line 129  is_dn: bv.bv_len = uri->bv_len - (bv.bv_ Line 342  is_dn: bv.bv_len = uri->bv_len - (bv.bv_
                         rc = LDAP_PROTOCOL_ERROR;                          rc = LDAP_PROTOCOL_ERROR;
                         goto done;                          goto done;
                 }                  }
                   ber_str2bv( ludp->lud_filter, 0, 0, fstr );
         }          }
   
         /* Grab the searchbase */          /* Grab the searchbase */
         bv.bv_val = ludp->lud_dn;          ber_str2bv( ludp->lud_dn, 0, 0, base );
         bv.bv_len = strlen( bv.bv_val );          rc = dnNormalize( 0, NULL, NULL, base, nbase, op->o_tmpmemctx );
         rc = dnNormalize( 0, NULL, NULL, &bv, searchbase, op->o_tmpmemctx );  
   
 done:  done:
         if( rc != LDAP_SUCCESS ) {          if( rc != LDAP_SUCCESS ) {
                 if( *filter ) filter_free_x( op, *filter );                  if( *filter ) filter_free_x( op, *filter );
                   base->bv_val = NULL;
                   base->bv_len = 0;
                   fstr->bv_val = NULL;
                   fstr->bv_len = 0;
           } else {
                   /* Don't free these, return them to caller */
                   ludp->lud_filter = NULL;
                   ludp->lud_dn = NULL;
         }          }
   
         ldap_free_urldesc( ludp );          ldap_free_urldesc( ludp );
Line 278  static void slap_sasl_rx_exp( Line 499  static void slap_sasl_rx_exp(
    LDAP URI to find the matching LDAP entry, using the pattern matching     LDAP URI to find the matching LDAP entry, using the pattern matching
    strings given in the saslregexp config file directive(s) */     strings given in the saslregexp config file directive(s) */
   
 static int slap_sasl_regexp( struct berval *in, struct berval *out, void *ctx )  static int slap_sasl_regexp( struct berval *in, struct berval *out,
                   int flags, void *ctx )
 {  {
         char *saslname = in->bv_val;          char *saslname = in->bv_val;
         SaslRegexp_t *reg;          SaslRegexp_t *reg;
Line 340  static int sasl_sc_sasl2dn( Operation *o Line 562  static int sasl_sc_sasl2dn( Operation *o
         if( ndn->bv_val ) {          if( ndn->bv_val ) {
                 o->o_tmpfree(ndn->bv_val, o->o_tmpmemctx);                  o->o_tmpfree(ndn->bv_val, o->o_tmpmemctx);
                 ndn->bv_val = NULL;                  ndn->bv_val = NULL;
                   ndn->bv_len = 0;
   
 #ifdef NEW_LOGGING  #ifdef NEW_LOGGING
                 LDAP_LOG( TRANSPORT, DETAIL1,                  LDAP_LOG( TRANSPORT, DETAIL1,
                         "slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );                          "slap_sc_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
 #else  #else
                 Debug( LDAP_DEBUG_TRACE,                  Debug( LDAP_DEBUG_TRACE,
                         "slap_sasl2dn: search DN returned more than 1 entry\n", 0,0,0 );                          "slap_sc_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
 #endif  #endif
                 return -1;                  return -1;
         }          }
Line 385  static int sasl_sc_smatch( Operation *o, Line 608  static int sasl_sc_smatch( Operation *o,
  */   */
   
 static  static
 int slap_sasl_match(Operation *opx, struct berval *rule, struct berval *assertDN, struct berval *authc )  int slap_sasl_match( Operation *opx, struct berval *rule,
           struct berval *assertDN, struct berval *authc )
 {  {
         int rc;           int rc; 
         regex_t reg;          regex_t reg;
         smatch_info sm;          smatch_info sm;
         slap_callback cb = { sasl_sc_smatch, NULL };          slap_callback cb = { NULL, sasl_sc_smatch, NULL, NULL };
         Operation op = {0};          Operation op = {0};
         SlapReply rs = {REP_RESULT};          SlapReply rs = {REP_RESULT};
   
Line 404  int slap_sasl_match(Operation *opx, stru Line 628  int slap_sasl_match(Operation *opx, stru
                 assertDN->bv_val, rule->bv_val, 0 );                  assertDN->bv_val, rule->bv_val, 0 );
 #endif  #endif
   
         rc = slap_parseURI( opx, rule, &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter );          rc = slap_parseURI( opx, rule, &op.o_req_dn,
                   &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter,
                   &op.ors_filterstr );
         if( rc != LDAP_SUCCESS ) goto CONCLUDED;          if( rc != LDAP_SUCCESS ) goto CONCLUDED;
   
         /* Massive shortcut: search scope == base */          switch ( op.oq_search.rs_scope ) {
         if( op.oq_search.rs_scope == LDAP_SCOPE_BASE ) {          case LDAP_X_SCOPE_EXACT:
   exact_match:
                   if ( dn_match( &op.o_req_ndn, assertDN ) ) {
                           rc = LDAP_SUCCESS;
                   } else {
                           rc = LDAP_INAPPROPRIATE_AUTH;
                   }
                   goto CONCLUDED;
   
           case LDAP_X_SCOPE_CHILDREN:
           case LDAP_X_SCOPE_SUBTREE:
           case LDAP_X_SCOPE_ONELEVEL:
           {
                   int     d = assertDN->bv_len - op.o_req_ndn.bv_len;
   
                   rc = LDAP_INAPPROPRIATE_AUTH;
   
                   if ( d == 0 && op.oq_search.rs_scope == LDAP_X_SCOPE_SUBTREE ) {
                           goto exact_match;
   
                   } else if ( d > 0 ) {
                           struct berval bv;
   
                           bv.bv_len = op.o_req_ndn.bv_len;
                           bv.bv_val = assertDN->bv_val + d;
   
                           if ( bv.bv_val[ -1 ] == ',' && dn_match( &op.o_req_ndn, &bv ) ) {
                                   switch ( op.oq_search.rs_scope ) {
                                   case LDAP_X_SCOPE_SUBTREE:
                                   case LDAP_X_SCOPE_CHILDREN:
                                           rc = LDAP_SUCCESS;
                                           break;
   
                                   case LDAP_X_SCOPE_ONELEVEL:
                                   {
                                           struct berval   pdn;
   
                                           dnParent( assertDN, &pdn );
                                           /* the common portion of the DN
                                            * already matches, so only check
                                            * if parent DN of assertedDN 
                                            * is all the pattern */
                                           if ( pdn.bv_len == op.o_req_ndn.bv_len ) {
                                                   rc = LDAP_SUCCESS;
                                           }
                                           break;
                                   }
                                   default:
                                           /* at present, impossible */
                                           assert( 0 );
                                   }
                           }
                   }
                   goto CONCLUDED;
           }
   
           case LDAP_X_SCOPE_REGEX:
                 rc = regcomp(&reg, op.o_req_ndn.bv_val,                  rc = regcomp(&reg, op.o_req_ndn.bv_val,
                         REG_EXTENDED|REG_ICASE|REG_NOSUB);                          REG_EXTENDED|REG_ICASE|REG_NOSUB);
                 if ( rc == 0 ) {                  if ( rc == 0 ) {
Line 421  int slap_sasl_match(Operation *opx, stru Line 703  int slap_sasl_match(Operation *opx, stru
                         rc = LDAP_INAPPROPRIATE_AUTH;                          rc = LDAP_INAPPROPRIATE_AUTH;
                 }                  }
                 goto CONCLUDED;                  goto CONCLUDED;
   
           default:
                   break;
         }          }
   
         /* Must run an internal search. */          /* Must run an internal search. */
           if ( op.oq_search.rs_filter == NULL ) {
                   rc = LDAP_FILTER_ERROR;
                   goto CONCLUDED;
           }
   
 #ifdef NEW_LOGGING  #ifdef NEW_LOGGING
         LDAP_LOG( TRANSPORT, DETAIL1,           LDAP_LOG( TRANSPORT, DETAIL1, 
Line 455  int slap_sasl_match(Operation *opx, stru Line 744  int slap_sasl_match(Operation *opx, stru
         op.o_threadctx = opx->o_threadctx;          op.o_threadctx = opx->o_threadctx;
         op.o_tmpmemctx = opx->o_tmpmemctx;          op.o_tmpmemctx = opx->o_tmpmemctx;
         op.o_tmpmfuncs = opx->o_tmpmfuncs;          op.o_tmpmfuncs = opx->o_tmpmfuncs;
   #ifdef LDAP_SLAPI
           op.o_pb = opx->o_pb;
   #endif
         op.o_conn = opx->o_conn;          op.o_conn = opx->o_conn;
         op.o_connid = opx->o_connid;          op.o_connid = opx->o_connid;
           op.o_req_dn = op.o_req_ndn;
           op.oq_search.rs_slimit = 1;
           op.oq_search.rs_tlimit = SLAP_NO_LIMIT;
           op.o_sync_slog_size = -1;
   
         op.o_bd->be_search( &op, &rs );          op.o_bd->be_search( &op, &rs );
   
Line 467  int slap_sasl_match(Operation *opx, stru Line 763  int slap_sasl_match(Operation *opx, stru
         }          }
   
 CONCLUDED:  CONCLUDED:
         if( op.o_req_ndn.bv_len ) sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );          if( op.o_req_dn.bv_val && op.o_req_dn.bv_val != op.o_req_ndn.bv_val ) ch_free( op.o_req_dn.bv_val );
           if( op.o_req_ndn.bv_val ) sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );
         if( op.oq_search.rs_filter ) filter_free_x( opx, op.oq_search.rs_filter );          if( op.oq_search.rs_filter ) filter_free_x( opx, op.oq_search.rs_filter );
           if( op.ors_filterstr.bv_val ) ch_free( op.ors_filterstr.bv_val );
   
 #ifdef NEW_LOGGING  #ifdef NEW_LOGGING
         LDAP_LOG( TRANSPORT, ENTRY,           LDAP_LOG( TRANSPORT, ENTRY, 
Line 515  slap_sasl_check_authz( Operation *op, Line 813  slap_sasl_check_authz( Operation *op,
         if( rc != LDAP_SUCCESS ) goto COMPLETE;          if( rc != LDAP_SUCCESS ) goto COMPLETE;
   
         /* Check if the *assertDN matches any **vals */          /* Check if the *assertDN matches any **vals */
         for( i=0; vals[i].bv_val != NULL; i++ ) {          if( vals != NULL ) {
                 rc = slap_sasl_match( op, &vals[i], assertDN, authc );                  for( i=0; vals[i].bv_val != NULL; i++ ) {
                 if ( rc == LDAP_SUCCESS ) goto COMPLETE;                          rc = slap_sasl_match( op, &vals[i], assertDN, authc );
                           if ( rc == LDAP_SUCCESS ) goto COMPLETE;
                   }
         }          }
         rc = LDAP_INAPPROPRIATE_AUTH;          rc = LDAP_INAPPROPRIATE_AUTH;
   
Line 546  COMPLETE: Line 846  COMPLETE:
  * entry, return the DN of that one entry.   * entry, return the DN of that one entry.
  */   */
 void slap_sasl2dn( Operation *opx,  void slap_sasl2dn( Operation *opx,
         struct berval *saslname, struct berval *sasldn )          struct berval *saslname, struct berval *sasldn, int flags )
 {  {
         int rc;          int rc;
         slap_callback cb = { sasl_sc_sasl2dn, NULL };          slap_callback cb = { NULL, sasl_sc_sasl2dn, NULL, NULL };
         Operation op = {0};          Operation op = {0};
         SlapReply rs = {REP_RESULT};          SlapReply rs = {REP_RESULT};
         struct berval regout = { 0, NULL };          struct berval regout = BER_BVNULL;
   
 #ifdef NEW_LOGGING  #ifdef NEW_LOGGING
         LDAP_LOG( TRANSPORT, ENTRY,           LDAP_LOG( TRANSPORT, ENTRY, 
Line 569  void slap_sasl2dn( Operation *opx, Line 869  void slap_sasl2dn( Operation *opx,
         cb.sc_private = sasldn;          cb.sc_private = sasldn;
   
         /* Convert the SASL name into a minimal URI */          /* Convert the SASL name into a minimal URI */
         if( !slap_sasl_regexp( saslname, &regout, opx->o_tmpmemctx ) ) {          if( !slap_sasl_regexp( saslname, &regout, flags, opx->o_tmpmemctx ) ) {
                 goto FINISHED;                  goto FINISHED;
         }          }
   
         rc = slap_parseURI( opx, &regout, &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter );          rc = slap_parseURI( opx, &regout, &op.o_req_dn,
                   &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter,
                   &op.ors_filterstr );
         if( regout.bv_val ) sl_free( regout.bv_val, opx->o_tmpmemctx );          if( regout.bv_val ) sl_free( regout.bv_val, opx->o_tmpmemctx );
         if( rc != LDAP_SUCCESS ) {          if( rc != LDAP_SUCCESS ) {
                 goto FINISHED;                  goto FINISHED;
Line 582  void slap_sasl2dn( Operation *opx, Line 884  void slap_sasl2dn( Operation *opx,
         /* Must do an internal search */          /* Must do an internal search */
         op.o_bd = select_backend( &op.o_req_ndn, 0, 1 );          op.o_bd = select_backend( &op.o_req_ndn, 0, 1 );
   
         /* Massive shortcut: search scope == base */          switch ( op.oq_search.rs_scope ) {
         if( op.oq_search.rs_scope == LDAP_SCOPE_BASE ) {          case LDAP_X_SCOPE_EXACT:
                 *sasldn = op.o_req_ndn;                  *sasldn = op.o_req_ndn;
                 op.o_req_ndn.bv_len = 0;                  op.o_req_ndn.bv_len = 0;
                 op.o_req_ndn.bv_val = NULL;                  op.o_req_ndn.bv_val = NULL;
                   /* intentionally continue to next case */
   
           case LDAP_X_SCOPE_REGEX:
           case LDAP_X_SCOPE_SUBTREE:
           case LDAP_X_SCOPE_CHILDREN:
           case LDAP_X_SCOPE_ONELEVEL:
                   /* correctly parsed, but illegal */
                 goto FINISHED;                  goto FINISHED;
   
           case LDAP_SCOPE_BASE:
           case LDAP_SCOPE_ONELEVEL:
           case LDAP_SCOPE_SUBTREE:
   #ifdef LDAP_SCOPE_SUBORDINATE
           case LDAP_SCOPE_SUBORDINATE:
   #endif
                   /* do a search */
                   break;
   
           default:
                   /* catch unhandled cases (there shouldn't be) */
                   assert( 0 );
         }          }
   
 #ifdef NEW_LOGGING  #ifdef NEW_LOGGING
Line 616  void slap_sasl2dn( Operation *opx, Line 938  void slap_sasl2dn( Operation *opx,
         op.o_threadctx = opx->o_threadctx;          op.o_threadctx = opx->o_threadctx;
         op.o_tmpmemctx = opx->o_tmpmemctx;          op.o_tmpmemctx = opx->o_tmpmemctx;
         op.o_tmpmfuncs = opx->o_tmpmfuncs;          op.o_tmpmfuncs = opx->o_tmpmfuncs;
   #ifdef LDAP_SLAPI
           op.o_pb = opx->o_pb;
   #endif
         op.oq_search.rs_deref = LDAP_DEREF_NEVER;          op.oq_search.rs_deref = LDAP_DEREF_NEVER;
         op.oq_search.rs_slimit = 1;          op.oq_search.rs_slimit = 1;
           op.oq_search.rs_tlimit = SLAP_NO_LIMIT;
         op.oq_search.rs_attrsonly = 1;          op.oq_search.rs_attrsonly = 1;
           op.o_req_dn = op.o_req_ndn;
   
         op.o_bd->be_search( &op, &rs );          op.o_bd->be_search( &op, &rs );
                   
Line 626  FINISHED: Line 953  FINISHED:
         if( sasldn->bv_len ) {          if( sasldn->bv_len ) {
                 opx->o_conn->c_authz_backend = op.o_bd;                  opx->o_conn->c_authz_backend = op.o_bd;
         }          }
         if( op.o_req_ndn.bv_len ) ch_free( op.o_req_ndn.bv_val );          if( op.o_req_dn.bv_len ) ch_free( op.o_req_dn.bv_val );
           if( op.o_req_ndn.bv_len ) sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );
         if( op.oq_search.rs_filter ) filter_free_x( opx, op.oq_search.rs_filter );          if( op.oq_search.rs_filter ) filter_free_x( opx, op.oq_search.rs_filter );
           if( op.ors_filterstr.bv_len ) ch_free( op.ors_filterstr.bv_val );
   
 #ifdef NEW_LOGGING  #ifdef NEW_LOGGING
         LDAP_LOG( TRANSPORT, ENTRY,           LDAP_LOG( TRANSPORT, ENTRY, 
Line 674  int slap_sasl_authorized( Operation *op, Line 1003  int slap_sasl_authorized( Operation *op,
         }          }
   
         /* Allow the manager to authorize as any DN. */          /* Allow the manager to authorize as any DN. */
         if( op->o_conn->c_authz_backend && be_isroot( op->o_conn->c_authz_backend, authcDN )) {          if( op->o_conn->c_authz_backend &&
                   be_isroot_dn( op->o_conn->c_authz_backend, authcDN ))
           {
                 rc = LDAP_SUCCESS;                  rc = LDAP_SUCCESS;
                 goto DONE;                  goto DONE;
         }          }
Line 683  int slap_sasl_authorized( Operation *op, Line 1014  int slap_sasl_authorized( Operation *op,
         if( authz_policy & SASL_AUTHZ_TO ) {          if( authz_policy & SASL_AUTHZ_TO ) {
                 rc = slap_sasl_check_authz( op, authcDN, authzDN,                  rc = slap_sasl_check_authz( op, authcDN, authzDN,
                         slap_schema.si_ad_saslAuthzTo, authcDN );                          slap_schema.si_ad_saslAuthzTo, authcDN );
                 if( rc == LDAP_SUCCESS ) {                  if( rc == LDAP_SUCCESS && !(authz_policy & SASL_AUTHZ_AND) ) {
                         goto DONE;                          goto DONE;
                 }                  }
         }          }

Removed from v.1.88  
changed lines
  Added in v.1.88.2.17


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