Diff for /servers/slapd/ad.c between versions 1.74 and 1.74.2.14

version 1.74, 2004/11/12 11:45:40 version 1.74.2.14, 2006/05/09 19:26:26
Line 1 Line 1
 /* ad.c - routines for dealing with attribute descriptions */  /* ad.c - routines for dealing with attribute descriptions */
 /* $OpenLDAP: pkg/ldap/servers/slapd/ad.c,v 1.73 2004/09/26 20:58:47 ando Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/ad.c,v 1.74.2.13 2006/04/05 18:26:36 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-2006 The OpenLDAP Foundation.
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 124  int slap_str2ad( Line 124  int slap_str2ad(
 }  }
   
 static char *strchrlen(  static char *strchrlen(
         const char *p,           const char *beg, 
           const char *end,
         const char ch,           const char ch, 
         int *len )          int *len )
 {  {
         int i;          const char *p;
   
         for( i=0; p[i]; i++ ) {          for( p=beg; *p && p < end; p++ ) {
                 if( p[i] == ch ) {                  if( *p == ch ) {
                         *len = i;                          *len = p - beg;
                         return (char *) &p[i];                          return (char *) p;
                 }                  }
         }          }
   
         *len = i;          *len = p - beg;
         return NULL;          return NULL;
 }  }
   
Line 148  int slap_bv2ad( Line 149  int slap_bv2ad(
 {  {
         int rtn = LDAP_UNDEFINED_TYPE;          int rtn = LDAP_UNDEFINED_TYPE;
         AttributeDescription desc, *d2;          AttributeDescription desc, *d2;
         char *name, *options;          char *name, *options, *optn;
         char *opt, *next;          char *opt, *next;
         int ntags;          int ntags;
         int tagslen;          int tagslen;
Line 174  int slap_bv2ad( Line 175  int slap_bv2ad(
         }          }
   
         /* find valid base attribute type; parse in place */          /* find valid base attribute type; parse in place */
         memset( &desc, 0, sizeof( desc ));          memset( &desc, 0, sizeof( desc ) );
         desc.ad_cname = *bv;          desc.ad_cname = *bv;
         name = bv->bv_val;          name = bv->bv_val;
         options = strchr(name, ';');          options = ber_bvchr( bv, ';' );
         if( options != NULL ) {          if ( options != NULL && (unsigned) ( options - name ) < bv->bv_len ) {
                   /* don't go past the end of the berval! */
                 desc.ad_cname.bv_len = options - name;                  desc.ad_cname.bv_len = options - name;
           } else {
                   options = NULL;
         }          }
         desc.ad_type = at_bvfind( &desc.ad_cname );          desc.ad_type = at_bvfind( &desc.ad_cname );
         if( desc.ad_type == NULL ) {          if( desc.ad_type == NULL ) {
Line 198  int slap_bv2ad( Line 202  int slap_bv2ad(
         ntags = 0;          ntags = 0;
         memset( tags, 0, sizeof( tags ));          memset( tags, 0, sizeof( tags ));
         tagslen = 0;          tagslen = 0;
           optn = bv->bv_val + bv->bv_len;
   
         for( opt=options; opt != NULL; opt=next ) {          for( opt=options; opt != NULL; opt=next ) {
                 int optlen;                  int optlen;
                 opt++;                   opt++; 
                 next = strchrlen( opt, ';', &optlen );                  next = strchrlen( opt, optn, ';', &optlen );
   
                 if( optlen == 0 ) {                  if( optlen == 0 ) {
                         *text = "zero length option is invalid";                          *text = "zero length option is invalid";
Line 247  int slap_bv2ad( Line 252  int slap_bv2ad(
   
                                 rc = strncasecmp( opt, tags[i].bv_val,                                  rc = strncasecmp( opt, tags[i].bv_val,
                                         (unsigned) optlen < tags[i].bv_len                                          (unsigned) optlen < tags[i].bv_len
                                                 ? optlen : tags[i].bv_len );                                                  ? (unsigned) optlen : tags[i].bv_len );
   
                                 if( rc == 0 && (unsigned)optlen == tags[i].bv_len ) {                                  if( rc == 0 && (unsigned)optlen == tags[i].bv_len ) {
                                         /* duplicate (ignore) */                                          /* duplicate (ignore) */
Line 385  done:; Line 390  done:;
                                         if( lp != desc.ad_tags.bv_val ) {                                          if( lp != desc.ad_tags.bv_val ) {
                                                 *cp++ = ';';                                                  *cp++ = ';';
                                                 j = (lp                                                  j = (lp
                                                      ? lp - desc.ad_tags.bv_val - 1                                                       ? (unsigned) (lp - desc.ad_tags.bv_val - 1)
                                                      : strlen( desc.ad_tags.bv_val ));                                                       : strlen( desc.ad_tags.bv_val ));
                                                 cp = lutil_strncopy(cp, desc.ad_tags.bv_val, j);                                                  cp = lutil_strncopy(cp, desc.ad_tags.bv_val, j);
                                         }                                          }
Line 440  static int is_ad_subtags( Line 445  static int is_ad_subtags(
         struct berval *subtagsbv,           struct berval *subtagsbv, 
         struct berval *suptagsbv )          struct berval *suptagsbv )
 {  {
         const char *suptags, *supp, *supdelimp;          const char *suptags, *supp, *supdelimp, *supn;
         const char *subtags, *subp, *subdelimp;          const char *subtags, *subp, *subdelimp, *subn;
         int  suplen, sublen;          int  suplen, sublen;
   
         subtags =subtagsbv->bv_val;          subtags =subtagsbv->bv_val;
         suptags =suptagsbv->bv_val;          suptags =suptagsbv->bv_val;
           subn = subtags + subtagsbv->bv_len;
           supn = suptags + suptagsbv->bv_len;
   
         for( supp=suptags ; supp; supp=supdelimp ) {          for( supp=suptags ; supp; supp=supdelimp ) {
                 supdelimp = strchrlen( supp, ';', &suplen );                  supdelimp = strchrlen( supp, supn, ';', &suplen );
                 if( supdelimp ) supdelimp++;                  if( supdelimp ) supdelimp++;
   
                 for( subp=subtags ; subp; subp=subdelimp ) {                  for( subp=subtags ; subp; subp=subdelimp ) {
                         subdelimp = strchrlen( subp, ';', &sublen );                          subdelimp = strchrlen( subp, subn, ';', &sublen );
                         if( subdelimp ) subdelimp++;                          if( subdelimp ) subdelimp++;
   
                         if ( suplen > sublen                          if ( suplen > sublen
Line 510  int ad_inlist( Line 517  int ad_inlist(
         for( ; attrs->an_name.bv_val; attrs++ ) {          for( ; attrs->an_name.bv_val; attrs++ ) {
                 AttributeType *a;                  AttributeType *a;
                 ObjectClass *oc;                  ObjectClass *oc;
                 int rc;  
                                   
                 if ( attrs->an_desc ) {                  if ( attrs->an_desc ) {
                         int lr;                          int lr;
Line 555  int ad_inlist( Line 561  int ad_inlist(
                         continue;                          continue;
                 }                  }
   
                   if ( ber_bvccmp( &attrs->an_name, '*' ) ) {
                           if ( !is_at_operational( desc->ad_type ) ) {
                                   return 1;
                           }
                           continue;
                   }
   
                   if ( ber_bvccmp( &attrs->an_name, '+' ) ) {
                           if ( is_at_operational( desc->ad_type ) ) {
                                   return 1;
                           }
                           continue;
                   }
   
                 /*                  /*
                  * EXTENSION: see if requested description is @objectClass                   * EXTENSION: see if requested description is @objectClass
                  * if so, return attributes which the class requires/allows                   * if so, return attributes which the class requires/allows
Line 584  int ad_inlist( Line 604  int ad_inlist(
                 }                  }
                 if( oc != NULL ) {                  if( oc != NULL ) {
                         if ( attrs->an_oc_exclude ) {                          if ( attrs->an_oc_exclude ) {
                                 int gotit = 0;  
   
                                 if ( oc == slap_schema.si_oc_extensibleObject ) {                                  if ( oc == slap_schema.si_oc_extensibleObject ) {
                                         /* extensibleObject allows the return of anything */                                          /* extensibleObject allows the return of anything */
                                         return 0;                                          return 0;
Line 650  int ad_inlist( Line 668  int ad_inlist(
                         }                          }
   
                 } else {                  } else {
                         /* short-circuit this search next time around */                          const char      *text;
                         if (!slap_schema.si_at_undefined->sat_ad) {  
                                 const char *text;                          /* give it a chance of being retrieved by a proxy... */
                                 slap_bv2undef_ad(&attrs->an_name,                          (void)slap_bv2undef_ad( &attrs->an_name,
                                         &attrs->an_desc, &text);                                  &attrs->an_desc, &text,
                         } else {                                  SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
                                 attrs->an_desc =  
                                         slap_schema.si_at_undefined->sat_ad;  
                         }  
                 }                  }
         }          }
   
Line 669  int ad_inlist( Line 684  int ad_inlist(
 int slap_str2undef_ad(  int slap_str2undef_ad(
         const char *str,          const char *str,
         AttributeDescription **ad,          AttributeDescription **ad,
         const char **text )          const char **text,
           unsigned flags )
 {  {
         struct berval bv;          struct berval bv;
         bv.bv_val = (char *) str;          bv.bv_val = (char *) str;
         bv.bv_len = strlen( str );          bv.bv_len = strlen( str );
   
         return slap_bv2undef_ad( &bv, ad, text );          return slap_bv2undef_ad( &bv, ad, text, flags );
 }  }
   
 int slap_bv2undef_ad(  int slap_bv2undef_ad(
         struct berval *bv,          struct berval *bv,
         AttributeDescription **ad,          AttributeDescription **ad,
         const char **text )          const char **text,
           unsigned flags )
 {  {
         AttributeDescription *desc;          AttributeDescription *desc;
           AttributeType *at;
   
         assert( ad != NULL );          assert( ad != NULL );
   
Line 698  int slap_bv2undef_ad( Line 716  int slap_bv2undef_ad(
                 return LDAP_UNDEFINED_TYPE;                  return LDAP_UNDEFINED_TYPE;
         }          }
   
         for( desc = slap_schema.si_at_undefined->sat_ad; desc;          /* use the appropriate type */
                 desc=desc->ad_next )           if ( flags & SLAP_AD_PROXIED ) {
         {                  at = slap_schema.si_at_proxied;
   
           } else {
                   at = slap_schema.si_at_undefined;
           }
   
           for( desc = at->sat_ad; desc; desc=desc->ad_next ) {
                 if( desc->ad_cname.bv_len == bv->bv_len &&                  if( desc->ad_cname.bv_len == bv->bv_len &&
                     !strcasecmp( desc->ad_cname.bv_val, bv->bv_val ))                      !strcasecmp( desc->ad_cname.bv_val, bv->bv_val ) )
                 {                  {
                         break;                          break;
                 }                  }
         }          }
           
         if( !desc ) {          if( !desc ) {
                   if ( flags & SLAP_AD_NOINSERT ) {
                           *text = NULL;
                           return LDAP_UNDEFINED_TYPE;
                   }
           
                 desc = ch_malloc(sizeof(AttributeDescription) + 1 +                  desc = ch_malloc(sizeof(AttributeDescription) + 1 +
                         bv->bv_len);                          bv->bv_len);
                                   
                 desc->ad_flags = SLAP_DESC_NONE;                  desc->ad_flags = SLAP_DESC_NONE;
                 desc->ad_tags.bv_val = NULL;                  BER_BVZERO( &desc->ad_tags );
                 desc->ad_tags.bv_len = 0;  
   
                 desc->ad_cname.bv_len = bv->bv_len;                  desc->ad_cname.bv_len = bv->bv_len;
                 desc->ad_cname.bv_val = (char *)(desc+1);                  desc->ad_cname.bv_val = (char *)(desc+1);
Line 723  int slap_bv2undef_ad( Line 751  int slap_bv2undef_ad(
                 /* canonical to upper case */                  /* canonical to upper case */
                 ldap_pvt_str2upper( desc->ad_cname.bv_val );                  ldap_pvt_str2upper( desc->ad_cname.bv_val );
   
                 desc->ad_type = slap_schema.si_at_undefined;                  /* shouldn't we protect this for concurrency? */
                   desc->ad_type = at;
                   ldap_pvt_thread_mutex_lock( &ad_undef_mutex );
                 desc->ad_next = desc->ad_type->sat_ad;                  desc->ad_next = desc->ad_type->sat_ad;
                 desc->ad_type->sat_ad = desc;                  desc->ad_type->sat_ad = desc;
                   ldap_pvt_thread_mutex_unlock( &ad_undef_mutex );
   
                   Debug( LDAP_DEBUG_ANY,
                           "%s attributeDescription \"%s\" inserted.\n",
                           ( flags & SLAP_AD_PROXIED ) ? "PROXIED" : "UNKNOWN",
                           desc->ad_cname.bv_val, 0 );
         }          }
   
         if( !*ad ) {          if( !*ad ) {
Line 737  int slap_bv2undef_ad( Line 773  int slap_bv2undef_ad(
         return LDAP_SUCCESS;          return LDAP_SUCCESS;
 }  }
   
   static int
   undef_promote(
           AttributeType   *at,
           char            *name,
           AttributeType   *nat )
   {
           AttributeDescription    **u_ad, **n_ad;
   
           /* Get to last ad on the new type */
           for ( n_ad = &nat->sat_ad; *n_ad; n_ad = &(*n_ad)->ad_next ) ;
   
           for ( u_ad = &at->sat_ad; *u_ad; ) {
                   struct berval   bv;
   
                   ber_str2bv( name, 0, 0, &bv );
   
                   /* remove iff undef == name or undef == name;tag */
                   if ( (*u_ad)->ad_cname.bv_len >= bv.bv_len
                           && strncasecmp( (*u_ad)->ad_cname.bv_val, bv.bv_val, bv.bv_len ) == 0
                           && ( (*u_ad)->ad_cname.bv_val[ bv.bv_len ] == '\0'
                                   || (*u_ad)->ad_cname.bv_val[ bv.bv_len ] == ';' ) )
                   {
                           AttributeDescription    *tmp = *u_ad;
   
                           *u_ad = (*u_ad)->ad_next;
   
                           tmp->ad_next = NULL;
                           *n_ad = tmp;
                           n_ad = &tmp->ad_next;
                   } else {
                           u_ad = &(*u_ad)->ad_next;
                   }
           }
   
           return 0;
   }
   
   int
   slap_ad_undef_promote(
           char *name,
           AttributeType *at )
   {
           int     rc;
   
           ldap_pvt_thread_mutex_lock( &ad_undef_mutex );
   
           rc = undef_promote( slap_schema.si_at_undefined, name, at );
           if ( rc == 0 ) {
                   rc = undef_promote( slap_schema.si_at_proxied, name, at );
           }
   
           ldap_pvt_thread_mutex_unlock( &ad_undef_mutex );
   
           return rc;
   }
   
 int  int
 an_find(  an_find(
     AttributeName *a,      AttributeName *a,
Line 778  str2anlist( AttributeName *an, char *in, Line 870  str2anlist( AttributeName *an, char *in,
         AttributeName *anew;          AttributeName *anew;
   
         /* find last element in list */          /* find last element in list */
         for (i = 0; an && an[i].an_name.bv_val; i++);          i = 0;
           if ( an != NULL ) {
                   for ( i = 0; !BER_BVISNULL( &an[ i ].an_name ) ; i++)
                           ;
           }
                   
         /* protect the input string from strtok */          /* protect the input string from strtok */
         str = ch_strdup( in );          str = ch_strdup( in );
   
         /* Count words in string */          /* Count words in string */
         j=1;          j = 1;
         for ( s = str; *s; s++ ) {          for ( s = str; *s; s++ ) {
                 if ( strchr( brkstr, *s ) != NULL ) {                  if ( strchr( brkstr, *s ) != NULL ) {
                         j++;                          j++;
Line 842  str2anlist( AttributeName *an, char *in, Line 938  str2anlist( AttributeName *an, char *in,
                 anew++;                  anew++;
         }          }
   
         anew->an_name.bv_val = NULL;          BER_BVZERO( &anew->an_name );
         free( str );          free( str );
         return( an );          return( an );
   
Line 896  anlist2attrs( AttributeName * anlist ) Line 992  anlist2attrs( AttributeName * anlist )
         char **attrs;          char **attrs;
         ObjectClass *oc;          ObjectClass *oc;
   
         attrs = anlist2charray( anlist, 1 );          if ( anlist == NULL )
                                                                                                   return NULL;
   
         for ( i = 0; anlist[i].an_name.bv_val; i++ ) {          for ( i = 0; anlist[i].an_name.bv_val; i++ ) {
                 if ( ( oc = anlist[i].an_oc ) ) {                  if ( ( oc = anlist[i].an_oc ) ) {
                         for ( j = 0; oc->soc_required && oc->soc_required[j]; j++ ) ;                          for ( j = 0; oc->soc_required && oc->soc_required[j]; j++ ) ;
Line 910  anlist2attrs( AttributeName * anlist ) Line 1007  anlist2attrs( AttributeName * anlist )
         if ( i == 0 )          if ( i == 0 )
                 return NULL;                  return NULL;
                                                                                                                                                                   
           attrs = anlist2charray( anlist, 1 );
                                                                                   
         n = i;          n = i;
                                                                                                                                                                   
         if ( k )          if ( k )
Line 934  anlist2attrs( AttributeName * anlist ) Line 1033  anlist2attrs( AttributeName * anlist )
         i = 0;          i = 0;
         while ( attrs && attrs[i] ) {          while ( attrs && attrs[i] ) {
                 if ( *attrs[i] == '@' ) {                  if ( *attrs[i] == '@' ) {
                           ch_free( attrs[i] );
                         for ( j = i; attrs[j]; j++ ) {                          for ( j = i; attrs[j]; j++ ) {
                                 if ( j == i )  
                                         ch_free( attrs[i] );  
                                 attrs[j] = attrs[j+1];                                  attrs[j] = attrs[j+1];
                         }                          }
                 } else {                  } else {
Line 948  anlist2attrs( AttributeName * anlist ) Line 1046  anlist2attrs( AttributeName * anlist )
                 j = i + 1;                  j = i + 1;
                 while ( attrs && attrs[j] ) {                  while ( attrs && attrs[j] ) {
                         if ( !strcmp( attrs[i], attrs[j] )) {                          if ( !strcmp( attrs[i], attrs[j] )) {
                                   ch_free( attrs[j] );
                                 for ( k = j; attrs && attrs[k]; k++ ) {                                  for ( k = j; attrs && attrs[k]; k++ ) {
                                         if ( k == j )  
                                                 ch_free( attrs[j] );  
                                         attrs[k] = attrs[k+1];                                          attrs[k] = attrs[k+1];
                                 }                                  }
                         } else {                          } else {
Line 993  file2anlist( AttributeName *an, const ch Line 1090  file2anlist( AttributeName *an, const ch
         }          }
   
         while ( fgets( lcur, LBUFSIZ, fp ) != NULL ) {          while ( fgets( lcur, LBUFSIZ, fp ) != NULL ) {
                 char *str, *s, *next;  
                 const char *delimstr = brkstr;  
                 if ( ( c = strchr( lcur, '\n' ) ) ) {                  if ( ( c = strchr( lcur, '\n' ) ) ) {
                         if ( c == line ) {                          if ( c == line ) {
                                 *c = '\0';                                  *c = '\0';
Line 1086  ad_define_option( const char *name, cons Line 1181  ad_define_option( const char *name, cons
         return 0;          return 0;
 }  }
   
   void
   ad_unparse_options( BerVarray *res )
   {
           int i;
           for ( i = 0; i < option_count; i++ ) {
                   value_add_one( res, &options[i].name );
           }
   }
   
 /* Find the definition of the option name or prefix matching the arguments */  /* Find the definition of the option name or prefix matching the arguments */
 static Attr_option *  static Attr_option *
 ad_find_option_definition( const char *opt, int optlen )  ad_find_option_definition( const char *opt, int optlen )

Removed from v.1.74  
changed lines
  Added in v.1.74.2.14


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