[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: Bugfixes for OpenLDAP 2.0.7



Hi,

I've compiled OpenLDAP 2.0.7 in a Solaris 8 Sparc v9 (64 Bit), Solaris 8 Intel,
Solaris 8 Sparc v8 (32 Bit) environment.
using:

    * UltraSparc 5 Server
    * Sparc 10 Server
    * Pentium II 300 Server
    * SUN Forte (WorkShop) 6.0 Compiler Suite

and figured out some bugs, which lead to compilation errors and a SEGV in one
case.

Attached is a patch to the OpenLDAP 2.0.7 source, which solves these.
Except the Replication test, the testsiute succeeds once the patch is
applied on all of my systems.

The patch additionally works around the following probs:

    * Kerberos 5 version 1.2.1 support
    * Cyrus SASL which requires Kerberos IV libraries
    * Berkeley DB version 3.x shared library naming
    * SUN Forte C comlaining about #endif being the last 
      line in a source file
    * Replacement of // comment by /* ... */ comments. This
      is due to complains of the SUN Forte compiler, which 
      (as I later figured out) also could be worked around by
      using the -xCC compiler switch ...
    * Static inclusion of the libwrap.a
      Systems which install the wrapper library in /usr/lib
      get confused in 64 bit mode, because the -R/usr/lib linker
      flag forces 32 bit libraries being used instead of 64 bit
      ones.
    * File: libraries/liblber/decode.c
      The signed value for netlen in ber_skip_tag got expanded
      to a very hughe unsigned value used in the boolean operation
      in line 133 of this function. This resulted in the *len pointer
      being negative. Finally a very long loop got encountered, which 
      ended in a SEGV
      This is only visible on 64 Bit systems because of the value
      expansion.

Hope, the included patches are worthfull information for you.

Regards
-- Jens

--------------------------------------------------------------------------------
     /
 +##+|##+   STRAWBERRY                     Jens Hamisch
+v#+v v##+  EDV-Systeme GmbH               Managing director
/ v    v\v
| . .  . |  Brauneckweg 2                  Car (Voice):  (+49 172) 81 04 162
|     .  |  D-82549 Koenigsdorf            Voice:        (+49 8179) 9305-50
 | .     |                                 Fax:          (+49 8179) 9305-38
 \   .  /   Tel./Fax: (+49 8179) 9305-50   Email:        jens@Strawberry.COM
  \____/    Strawberry@Strawberry.COM      


*** ./build/openldap.m4.FCS	Wed Jan 17 09:06:12 2001
--- ./build/openldap.m4	Wed Jan 17 09:55:26 2001
***************
*** 290,295 ****
--- 290,296 ----
  OL_BERKELEY_DB_TRY(ol_cv_db_none)
  OL_BERKELEY_DB_TRY(ol_cv_db_db,[-ldb])
  OL_BERKELEY_DB_TRY(ol_cv_db_db3,[-ldb3])
+ OL_BERKELEY_DB_TRY(ol_cv_db_db_3,[-ldb-3])
  OL_BERKELEY_DB_TRY(ol_cv_db_db2,[-ldb2])
  OL_BERKELEY_DB_TRY(ol_cv_db_db1,[-ldb1])
  ])
*** ./clients/tools/ldapsearch.c.FCS	Thu Jan 18 20:42:38 2001
--- ./clients/tools/ldapsearch.c	Sat Jan 20 18:36:38 2001
***************
*** 1316,1322 ****
  			b64->bv_val = ber_memalloc( b64->bv_len + 1 );
  
  			b64->bv_len = lutil_b64_ntop(
! 				ctrls[i]->ldctl_value.bv_val, ctrls[i]->ldctl_value.bv_len,
  				b64->bv_val, b64->bv_len );
  		}
  
--- 1316,1323 ----
  			b64->bv_val = ber_memalloc( b64->bv_len + 1 );
  
  			b64->bv_len = lutil_b64_ntop(
! 				(unsigned char *) ctrls[i]->ldctl_value.bv_val,
! 				ctrls[i]->ldctl_value.bv_len,
  				b64->bv_val, b64->bv_len );
  		}
  
No differences encountered
*** ./libraries/liblber/decode.c.FCS	Thu Jan 18 16:59:33 2001
--- ./libraries/liblber/decode.c	Sun Jan 21 15:13:38 2001
***************
*** 81,87 ****
  	ber_tag_t	tag;
  	unsigned char	lc;
  	ber_len_t	i, noctets;
! 	unsigned char netlen[sizeof(ber_len_t)];
  
  	assert( ber != NULL );
  	assert( len != NULL );
--- 81,87 ----
  	ber_tag_t	tag;
  	unsigned char	lc;
  	ber_len_t	i, noctets;
! 	unsigned char 	netlen[sizeof(ber_len_t)];
  
  	assert( ber != NULL );
  	assert( len != NULL );
***************
*** 124,130 ****
  			return LBER_DEFAULT;
  		}
  
! 		if( (unsigned) ber_read( ber, netlen, noctets ) != noctets ) {
  			return LBER_DEFAULT;
  		}
  
--- 124,130 ----
  			return LBER_DEFAULT;
  		}
  
! 		if( (unsigned) ber_read( ber, (char *) netlen, noctets ) != noctets ) {
  			return LBER_DEFAULT;
  		}
  
***************
*** 440,445 ****
--- 440,446 ----
  	}
  
  	*last = ber->ber_ptr + *len;
+ 	assert( *last >= ber->ber_buf);	/* unsigned prob on Sparc v9! */
  
  	if ( *last == ber->ber_ptr ) {
  		return LBER_DEFAULT;
*** ./libraries/liblber/encode.c.FCS	Thu Jan 18 17:01:56 2001
--- ./libraries/liblber/encode.c	Thu Jan 18 17:03:09 2001
***************
*** 83,89 ****
  	}
  
  	rc = ber_write( ber,
! 		&nettag[sizeof(ber_tag_t) - taglen],
  	    taglen, nosos );
  
  	return rc;
--- 83,89 ----
  	}
  
  	rc = ber_write( ber,
! 		(const char *) &nettag[sizeof(ber_tag_t) - taglen],
  	    taglen, nosos );
  
  	return rc;
***************
*** 165,171 ****
  
  	/* write the length itself */
  	rc = ber_write( ber,
! 		&netlen[sizeof(ber_len_t)-i],
  		i, nosos );
  
  	return rc == i ?  i+1 : -1;
--- 165,171 ----
  
  	/* write the length itself */
  	rc = ber_write( ber,
! 		(const char *) &netlen[sizeof(ber_len_t)-i],
  		i, nosos );
  
  	return rc == i ?  i+1 : -1;
***************
*** 230,236 ****
  	}
  
  	rc = ber_write( ber,
! 		&netnum[sizeof(ber_int_t) - i],
  		i, 0 );
  
  	/* length of tag + length + contents */
--- 230,236 ----
  	}
  
  	rc = ber_write( ber,
! 		(const char *) &netnum[sizeof(ber_int_t) - i],
  		i, 0 );
  
  	/* length of tag + length + contents */
***************
*** 565,571 ****
  
  			/* the length itself */
  			rc  = ber_write( ber,
! 				&netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN-1)],
  				FOUR_BYTE_LEN-1, 1 );
  
  			if( rc != FOUR_BYTE_LEN - 1 ) {
--- 565,571 ----
  
  			/* the length itself */
  			rc  = ber_write( ber,
! 				(const char *) &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN-1)],
  				FOUR_BYTE_LEN-1, 1 );
  
  			if( rc != FOUR_BYTE_LEN - 1 ) {
*** ./libraries/liblber/io.c.FCS	Sat Jan 20 13:10:24 2001
--- ./libraries/liblber/io.c	Sat Jan 20 13:27:25 2001
***************
*** 77,82 ****
--- 77,85 ----
  
  	assert( BER_VALID( ber ) );
  
+ 	if( ber->ber_end < ber->ber_ptr)
+ 	    return( 0);
+ 
  	nleft = ber->ber_end - ber->ber_ptr;
  	actuallen = nleft < len ? nleft : len;
  
*** ./libraries/libldap/utf-8.c.FCS	Thu Jan 18 20:35:49 2001
--- ./libraries/libldap/utf-8.c	Thu Jan 18 20:38:25 2001
***************
*** 111,117 ****
  /* conv UTF-8 to UCS-4, useful for comparisons */
  ldap_ucs4_t ldap_utf8_to_ucs4( const char * p )
  {
!     const unsigned char *c = p;
      ldap_ucs4_t ch;
  	int len, i;
  	static unsigned char mask[] = {
--- 111,117 ----
  /* conv UTF-8 to UCS-4, useful for comparisons */
  ldap_ucs4_t ldap_utf8_to_ucs4( const char * p )
  {
!     const unsigned char *c = (const unsigned char *) p;
      ldap_ucs4_t ch;
  	int len, i;
  	static unsigned char mask[] = {
***************
*** 139,145 ****
  int ldap_ucs4_to_utf8( ldap_ucs4_t c, char *buf )
  {
  	int len=0;
! 	unsigned char* p = buf;
  	if(buf == NULL) return 0;
  
  	if ( c < 0 ) {
--- 139,145 ----
  int ldap_ucs4_to_utf8( ldap_ucs4_t c, char *buf )
  {
  	int len=0;
! 	unsigned char* p = (unsigned char*) buf;
  	if(buf == NULL) return 0;
  
  	if ( c < 0 ) {
***************
*** 195,201 ****
  char* ldap_utf8_next( const char * p )
  {
  	int i;
! 	const unsigned char *u = p;
  
  	if( LDAP_UTF8_ISASCII(u) ) {
  		return (char *) &p[1];
--- 195,201 ----
  char* ldap_utf8_next( const char * p )
  {
  	int i;
! 	const unsigned char *u = (const unsigned char *) p;
  
  	if( LDAP_UTF8_ISASCII(u) ) {
  		return (char *) &p[1];
***************
*** 222,228 ****
  char* ldap_utf8_prev( const char * p )
  {
  	int i;
! 	const unsigned char *u = p;
  
  	for( i=-1; i>-6 ; i-- ) {
  		if ( ( u[i] & 0xc0 ) != 0x80 ) {
--- 222,228 ----
  char* ldap_utf8_prev( const char * p )
  {
  	int i;
! 	const unsigned char *u = (const unsigned char *) p;
  
  	for( i=-1; i>-6 ; i-- ) {
  		if ( ( u[i] & 0xc0 ) != 0x80 ) {
***************
*** 246,252 ****
  int ldap_utf8_copy( char* dst, const char *src )
  {
  	int i;
! 	const unsigned char *u = src;
  
  	dst[0] = src[0];
  
--- 246,252 ----
  int ldap_utf8_copy( char* dst, const char *src )
  {
  	int i;
! 	const unsigned char *u = (const unsigned char *) src;
  
  	dst[0] = src[0];
  
*** ./libraries/libldap_r/tpool.c.FCS	Thu Jan 18 20:38:51 2001
--- ./libraries/libldap_r/tpool.c	Fri Jan 19 06:28:43 2001
***************
*** 201,207 ****
  
  	if (need_thread) {
  		int rc = ldap_pvt_thread_create( &thr, 1,
! 			(void *)ldap_int_thread_pool_wrapper, pool );
  		ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
  		if (rc == 0) {
  			pool->ltp_starting--;
--- 201,207 ----
  
  	if (need_thread) {
  		int rc = ldap_pvt_thread_create( &thr, 1,
! 			(void *(*)(void *))ldap_int_thread_pool_wrapper, pool );
  		ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
  		if (rc == 0) {
  			pool->ltp_starting--;
*** ./libraries/liblutil/entropy.c.FCS	Thu Jan 18 16:48:28 2001
--- ./libraries/liblutil/entropy.c	Thu Jan 18 16:48:34 2001
***************
*** 119,125 ****
  
  		for( n = 0; n < nbytes; n += 16 ) {
  			struct lutil_MD5Context ctx;
! 			char digest[16];
  
  			/* poor resolution */
  #ifdef HAVE_GETTIMEOFDAY
--- 119,125 ----
  
  		for( n = 0; n < nbytes; n += 16 ) {
  			struct lutil_MD5Context ctx;
! 			unsigned char digest[16];
  
  			/* poor resolution */
  #ifdef HAVE_GETTIMEOFDAY
*** ./libraries/liblutil/passwd.c.FCS	Thu Jan 18 16:58:22 2001
--- ./libraries/liblutil/passwd.c	Thu Jan 18 19:32:41 2001
***************
*** 311,317 ****
  		return NULL;
  	}
  
! 	if( lutil_entropy( pw->bv_val, pw->bv_len) < 0 ) {
  		ber_bvfree( pw );
  		return NULL; 
  	}
--- 311,317 ----
  		return NULL;
  	}
  
! 	if( lutil_entropy( (unsigned char *) pw->bv_val, pw->bv_len) < 0 ) {
  		ber_bvfree( pw );
  		return NULL; 
  	}
***************
*** 405,411 ****
  	AC_MEMCPY(b64->bv_val, sc->name.bv_val, sc->name.bv_len);
  
  	rc = lutil_b64_ntop(
! 		string.bv_val, string.bv_len,
  		&b64->bv_val[sc->name.bv_len], b64len );
  
  	if( salt ) ber_memfree( string.bv_val );
--- 405,411 ----
  	AC_MEMCPY(b64->bv_val, sc->name.bv_val, sc->name.bv_len);
  
  	rc = lutil_b64_ntop(
! 		(const unsigned char *) string.bv_val, string.bv_len,
  		&b64->bv_val[sc->name.bv_len], b64len );
  
  	if( salt ) ber_memfree( string.bv_val );
***************
*** 924,935 ****
  	struct berval digest;
  	struct berval salt;
  
! 	digest.bv_val = SHA1digest;
  	digest.bv_len = sizeof(SHA1digest);
! 	salt.bv_val = saltdata;
  	salt.bv_len = sizeof(saltdata);
  
! 	if( lutil_entropy( salt.bv_val, salt.bv_len) < 0 ) {
  		return NULL; 
  	}
  
--- 924,935 ----
  	struct berval digest;
  	struct berval salt;
  
! 	digest.bv_val = (char *) SHA1digest;
  	digest.bv_len = sizeof(SHA1digest);
! 	salt.bv_val = (char *) saltdata;
  	salt.bv_len = sizeof(saltdata);
  
! 	if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
  		return NULL; 
  	}
  
***************
*** 950,956 ****
  	lutil_SHA1_CTX  SHA1context;
  	unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
  	struct berval digest;
! 	digest.bv_val = SHA1digest;
  	digest.bv_len = sizeof(SHA1digest);
       
  	lutil_SHA1Init( &SHA1context );
--- 950,956 ----
  	lutil_SHA1_CTX  SHA1context;
  	unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
  	struct berval digest;
! 	digest.bv_val = (char *) SHA1digest;
  	digest.bv_len = sizeof(SHA1digest);
       
  	lutil_SHA1Init( &SHA1context );
***************
*** 971,982 ****
  	struct berval digest;
  	struct berval salt;
  
! 	digest.bv_val = MD5digest;
  	digest.bv_len = sizeof(MD5digest);
! 	salt.bv_val = saltdata;
  	salt.bv_len = sizeof(saltdata);
  
! 	if( lutil_entropy( salt.bv_val, salt.bv_len) < 0 ) {
  		return NULL; 
  	}
  
--- 971,982 ----
  	struct berval digest;
  	struct berval salt;
  
! 	digest.bv_val = (char *) MD5digest;
  	digest.bv_len = sizeof(MD5digest);
! 	salt.bv_val = (char *) saltdata;
  	salt.bv_len = sizeof(saltdata);
  
! 	if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
  		return NULL; 
  	}
  
***************
*** 999,1005 ****
  
  	struct berval digest;
  
! 	digest.bv_val = MD5digest;
  	digest.bv_len = sizeof(MD5digest);
  
  	lutil_MD5Init( &MD5context );
--- 999,1005 ----
  
  	struct berval digest;
  
! 	digest.bv_val = (char *) MD5digest;
  	digest.bv_len = sizeof(MD5digest);
  
  	lutil_MD5Init( &MD5context );
***************
*** 1038,1044 ****
  	salt[1] = crypt64[ salt[1] % (sizeof(crypt64)-1) ];
  	salt[2] = '\0';
  
! 	hash.bv_val = crypt( passwd->bv_val, salt );
  
  	if( hash.bv_val == NULL ) return NULL;
  
--- 1038,1044 ----
  	salt[1] = crypt64[ salt[1] % (sizeof(crypt64)-1) ];
  	salt[2] = '\0';
  
! 	hash.bv_val = crypt( passwd->bv_val, (const char *) salt );
  
  	if( hash.bv_val == NULL ) return NULL;
  
*** ./servers/slapd/back-sql/back-sql.h.FCS	Wed Jan 17 09:33:11 2001
--- ./servers/slapd/back-sql/back-sql.h	Wed Jan 17 09:38:03 2001
***************
*** 22,29 ****
   char *dbuser;
   char *dbpasswd;
   char *dbname;
!  //SQL condition for subtree searches differs in syntax:
!  //"LIKE CONCAT('%',?)" or "LIKE '%'+?" or smth else
   char *subtree_cond;
   char *oc_query,*at_query;
   char *insentry_query,*delentry_query;
--- 22,29 ----
   char *dbuser;
   char *dbpasswd;
   char *dbname;
!  /* SQL condition for subtree searches differs in syntax: */
!  /* "LIKE CONCAT('%',?)" or "LIKE '%'+?" or smth else */
   char *subtree_cond;
   char *oc_query,*at_query;
   char *insentry_query,*delentry_query;
***************
*** 39,41 ****
--- 39,42 ----
  }backsql_info;
  
  #endif
+ 
*** ./servers/slapd/back-sql/entry-id.c.FCS	Wed Jan 17 09:33:54 2001
--- ./servers/slapd/back-sql/entry-id.c	Wed Jan 17 09:34:01 2001
***************
*** 34,40 ****
  {
   SQLHSTMT sth; 
   BACKSQL_ROW_NTS row;
!  //SQLINTEGER nrows=0;
   RETCODE rc;
  
   Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): dn='%s'\n",dn,0,0);
--- 34,40 ----
  {
   SQLHSTMT sth; 
   BACKSQL_ROW_NTS row;
!  /* SQLINTEGER nrows=0; */
   RETCODE rc;
  
   Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): dn='%s'\n",dn,0,0);
***************
*** 121,130 ****
        {
         backsql_entry_addattr(bsi->e,row.col_names[i],row.cols[i],/*row.col_prec[i]*/
  					strlen(row.cols[i]));
! //       Debug(LDAP_DEBUG_TRACE,"prec=%d\n",(int)row.col_prec[i],0,0);
        }
!     // else
!     //  Debug(LDAP_DEBUG_TRACE,"NULL value in this row for attribute '%s'\n",row.col_names[i],0,0);
      }
    }
   backsql_FreeRow(&row);
--- 121,130 ----
        {
         backsql_entry_addattr(bsi->e,row.col_names[i],row.cols[i],/*row.col_prec[i]*/
  					strlen(row.cols[i]));
! /*        Debug(LDAP_DEBUG_TRACE,"prec=%d\n",(int)row.col_prec[i],0,0); */
        }
!     /*  else */
!     /*   Debug(LDAP_DEBUG_TRACE,"NULL value in this row for attribute '%s'\n",row.col_names[i],0,0); */
      }
    }
   backsql_FreeRow(&row);
***************
*** 147,153 ****
   e->e_attrs=NULL;
   e->e_private=NULL;
   
! // if (bsi->base_dn != NULL)???
  
   e->e_id=eid->id;
   e->e_dn=ch_strdup(bsi->c_eid->dn);
--- 147,153 ----
   e->e_attrs=NULL;
   e->e_private=NULL;
   
! /*  if (bsi->base_dn != NULL)??? */
  
   e->e_id=eid->id;
   e->e_dn=ch_strdup(bsi->c_eid->dn);
***************
*** 160,166 ****
    {
     if (!strcasecmp(*c_at_name,"objectclass") || !strcasecmp(*c_at_name,"0.10"))
     {
! 	//backsql_entry_addattr(bsi->e,"objectclass",bsi->oc->name,strlen(bsi->oc->name));
      continue;
     }
     at=backsql_at_with_name(bsi->oc,*c_at_name);
--- 160,166 ----
    {
     if (!strcasecmp(*c_at_name,"objectclass") || !strcasecmp(*c_at_name,"0.10"))
     {
! 	/* backsql_entry_addattr(bsi->e,"objectclass",bsi->oc->name,strlen(bsi->oc->name)); */
      continue;
     }
     at=backsql_at_with_name(bsi->oc,*c_at_name);
*** ./servers/slapd/back-sql/entry-id.h.FCS	Wed Jan 17 09:34:15 2001
--- ./servers/slapd/back-sql/entry-id.h	Wed Jan 17 09:38:12 2001
***************
*** 21,26 ****
  }backsql_entryID;
  
  backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID* id,SQLHDBC dbh,char *dn);
! backsql_entryID* backsql_free_entryID(backsql_entryID* id);//returns next
  
  #endif
--- 21,27 ----
  }backsql_entryID;
  
  backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID* id,SQLHDBC dbh,char *dn);
! backsql_entryID* backsql_free_entryID(backsql_entryID* id);/* returns next */
  
  #endif
+ 
*** ./servers/slapd/back-sql/modify.c.FCS	Wed Jan 17 09:34:52 2001
--- ./servers/slapd/back-sql/modify.c	Thu Jan 18 21:05:23 2001
***************
*** 35,42 ****
   backsql_at_map_rec *at=NULL;
   struct berval *at_val;
   int i;
!  int pno,po;//first parameter no, parameter order
!  int prc; //procedure return code
  
   Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",ndn,0,0);
   dbh=backsql_get_db_conn(be,conn);
--- 35,42 ----
   backsql_at_map_rec *at=NULL;
   struct berval *at_val;
   int i;
!  int pno,po;/* first parameter no, parameter order */
!  int prc; /* procedure return code */
  
   Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",ndn,0,0);
   dbh=backsql_get_db_conn(be,conn);
***************
*** 128,138 ****
  			    pno=0;
  			   po=(at->param_order & BACKSQL_DEL)>0;
  			   SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
! 			   //check for syntax needed here - maybe need binary bind?
  			   SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,row.cols[i],strlen(row.cols[i]),0);
  			
  			   Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
! 			   rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
  			   if (rc!=SQL_SUCCESS)
  				{
  			     Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
--- 128,138 ----
  			    pno=0;
  			   po=(at->param_order & BACKSQL_DEL)>0;
  			   SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
! 			   /* check for syntax needed here - maybe need binary bind? */
  			   SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,row.cols[i],strlen(row.cols[i]),0);
  			
  			   Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
! 			   rc=SQLExecDirect(sth,(unsigned char *) at->delete_proc,SQL_NTS);
  			   if (rc!=SQL_SUCCESS)
  				{
  			     Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
***************
*** 143,149 ****
  			backsql_FreeRow(&row);
               SQLFreeStmt(asth,SQL_DROP);
  			}
! 			//PASSTHROUGH - to add new attributes -- do NOT add break
    case LDAP_MOD_ADD:
  			if (at->add_proc==NULL)
  			{
--- 143,149 ----
  			backsql_FreeRow(&row);
               SQLFreeStmt(asth,SQL_DROP);
  			}
! 			/* PASSTHROUGH - to add new attributes -- do NOT add break */
    case LDAP_MOD_ADD:
  			if (at->add_proc==NULL)
  			{
***************
*** 167,177 ****
  			  pno=0;
  			po=(at->param_order & BACKSQL_ADD)>0;
  			SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
! 			//check for syntax needed here - maybe need binary bind?
  			SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
  			
  			Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->add_proc,0,0);
! 			rc=SQLExecDirect(sth,at->add_proc,SQL_NTS);
  			if (rc!=SQL_SUCCESS)
  			{
  			  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add_proc execution failed\n",0,0,0);
--- 167,177 ----
  			  pno=0;
  			po=(at->param_order & BACKSQL_ADD)>0;
  			SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
! 			/* check for syntax needed here - maybe need binary bind? */
  			SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
  			
  			Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->add_proc,0,0);
! 			rc=SQLExecDirect(sth,(unsigned char *) at->add_proc,SQL_NTS);
  			if (rc!=SQL_SUCCESS)
  			{
  			  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add_proc execution failed\n",0,0,0);
***************
*** 202,212 ****
  			  pno=0;
  			po=(at->param_order & BACKSQL_DEL)>0;
  			SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
! 			//check for syntax needed here - maybe need binary bind?
  			SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
  			   
  			Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
! 			rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
  			if (rc!=SQL_SUCCESS)
  			{
  			  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
--- 202,212 ----
  			  pno=0;
  			po=(at->param_order & BACKSQL_DEL)>0;
  			SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
! 			/* check for syntax needed here - maybe need binary bind? */
  			SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
  			   
  			Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
! 			rc=SQLExecDirect(sth,(unsigned char *) at->delete_proc,SQL_NTS);
  			if (rc!=SQL_SUCCESS)
  			{
  			  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
***************
*** 306,312 ****
  
   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): executing delentry_query\n",0,0,0);
   SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
!  rc=SQLExecDirect(sth,bi->delentry_query,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): failed to delete record from ldap_entries\n",0,0,0);
--- 306,312 ----
  
   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): executing delentry_query\n",0,0,0);
   SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
!  rc=SQLExecDirect(sth,(unsigned char *) bi->delentry_query,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): failed to delete record from ldap_entries\n",0,0,0);
***************
*** 322,328 ****
   SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&e_id.oc_id,0,0);
   SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_pid.id,0,0);
   SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
!  rc=SQLExecDirect(sth,bi->insentry_query,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not insert ldap_entries record\n",0,0,0);
--- 322,328 ----
   SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&e_id.oc_id,0,0);
   SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_pid.id,0,0);
   SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
!  rc=SQLExecDirect(sth,(unsigned char *) bi->insentry_query,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not insert ldap_entries record\n",0,0,0);
***************
*** 331,337 ****
    goto modrdn_return;
   }
  
!  //should process deleteoldrdn here...
  
   send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
  modrdn_return:
--- 331,337 ----
    goto modrdn_return;
   }
  
!  /* should process deleteoldrdn here... */
  
   send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
  modrdn_return:
***************
*** 360,367 ****
   Attribute *at;
   struct berval *at_val;
   char *pdn;
!  int pno,po;//first parameter no, parameter order
!  int prc; //procedure return code
  
   Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): adding entry '%s'\n",e->e_dn,0,0);
   if (dn_validate(e->e_dn)==NULL)
--- 360,367 ----
   Attribute *at;
   struct berval *at_val;
   char *pdn;
!  int pno,po;/* first parameter no, parameter order */
!  int prc; /* procedure return code */
  
   Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): adding entry '%s'\n",e->e_dn,0,0);
   if (dn_validate(e->e_dn)==NULL)
***************
*** 370,376 ****
   }
   for(at=e->e_attrs;at!=NULL;at=at->a_next)
   {
!   //Debug(LDAP_DEBUG_TRACE,"backsql_add(): scanning entry -- %s\n",at->a_type,0,0);
    if (!strcasecmp(at->a_desc->ad_cname->bv_val,"objectclass"))
    {
     oc=backsql_oc_with_name(bi,at->a_vals[0]->bv_val);
--- 370,376 ----
   }
   for(at=e->e_attrs;at!=NULL;at=at->a_next)
   {
!   /* Debug(LDAP_DEBUG_TRACE,"backsql_add(): scanning entry -- %s\n",at->a_type,0,0); */
    if (!strcasecmp(at->a_desc->ad_cname->bv_val,"objectclass"))
    {
     oc=backsql_oc_with_name(bi,at->a_vals[0]->bv_val);
***************
*** 403,409 ****
   SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
  
   Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",oc->create_proc,0,0);
!  rc=SQLExecDirect(sth,oc->create_proc,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc execution failed\n",0,0,0);
--- 403,409 ----
   SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
  
   Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",oc->create_proc,0,0);
!  rc=SQLExecDirect(sth,(unsigned char *) oc->create_proc,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc execution failed\n",0,0,0);
***************
*** 441,450 ****
  	pno=0;
  	po=(at_rec->param_order & BACKSQL_ADD)>0;
  	SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
! 	//check for syntax needed here - maybe need binary bind?
  	SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
     Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",at_rec->add_proc,0,0);
!    rc=SQLExecDirect(sth,at_rec->add_proc,SQL_NTS);
     if (rc!=SQL_SUCCESS)
     {
  	Debug(LDAP_DEBUG_TRACE,"backsql_add(): add_proc execution failed\n",0,0,0);
--- 441,450 ----
  	pno=0;
  	po=(at_rec->param_order & BACKSQL_ADD)>0;
  	SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
! 	/* check for syntax needed here - maybe need binary bind? */
  	SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
     Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",at_rec->add_proc,0,0);
!    rc=SQLExecDirect(sth,(unsigned char *) at_rec->add_proc,SQL_NTS);
     if (rc!=SQL_SUCCESS)
     {
  	Debug(LDAP_DEBUG_TRACE,"backsql_add(): add_proc execution failed\n",0,0,0);
***************
*** 467,478 ****
   SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&oc->id,0,0);
   SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&parent_id.id,0,0);
   SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0);
!  rc=SQLExecDirect(sth,bi->insentry_query,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not insert ldap_entries record\n",0,0,0);
    backsql_PrintErrors(bi->db_env,dbh,sth,rc);
!   //execute delete_proc to delete data added !!!
    SQLFreeStmt(sth,SQL_DROP);
    send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
    return 1;
--- 467,478 ----
   SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&oc->id,0,0);
   SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&parent_id.id,0,0);
   SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0);
!  rc=SQLExecDirect(sth,(unsigned char *) bi->insentry_query,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not insert ldap_entries record\n",0,0,0);
    backsql_PrintErrors(bi->db_env,dbh,sth,rc);
!   /* execute delete_proc to delete data added !!! */
    SQLFreeStmt(sth,SQL_DROP);
    send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
    return 1;
***************
*** 491,497 ****
   RETCODE rc;
   backsql_oc_map_rec *oc=NULL;
   backsql_entryID e_id,*res;
!  int pno;//first parameter no, parameter order
  
   Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",ndn,0,0);
   dbh=backsql_get_db_conn(be,conn);
--- 491,497 ----
   RETCODE rc;
   backsql_oc_map_rec *oc=NULL;
   backsql_entryID e_id,*res;
!  int pno;/* first parameter no, parameter order */
  
   Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",ndn,0,0);
   dbh=backsql_get_db_conn(be,conn);
***************
*** 532,541 ****
   else
    pno=0;
   SQLBindParameter(sth,(SQLUSMALLINT)(pno+1),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
!  //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0);
  
   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): executing '%s'\n",oc->delete_proc,0,0);
!  rc=SQLExecDirect(sth,oc->delete_proc,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete_proc execution failed\n",0,0,0);
--- 532,541 ----
   else
    pno=0;
   SQLBindParameter(sth,(SQLUSMALLINT)(pno+1),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
!  /* SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0); */
  
   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): executing '%s'\n",oc->delete_proc,0,0);
!  rc=SQLExecDirect(sth,(unsigned char *) oc->delete_proc,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete_proc execution failed\n",0,0,0);
***************
*** 547,553 ****
   SQLFreeStmt(sth,SQL_RESET_PARAMS);
  
   SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
!  rc=SQLExecDirect(sth,bi->delentry_query,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_delete(): failed to delete record from ldap_entries\n",0,0,0);
--- 547,553 ----
   SQLFreeStmt(sth,SQL_RESET_PARAMS);
  
   SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
!  rc=SQLExecDirect(sth,(unsigned char *) bi->delentry_query,SQL_NTS);
   if (rc != SQL_SUCCESS)
   {
    Debug(LDAP_DEBUG_TRACE,"backsql_delete(): failed to delete record from ldap_entries\n",0,0,0);
*** ./servers/slapd/back-sql/schema-map.c.FCS	Wed Jan 17 09:35:08 2001
--- ./servers/slapd/back-sql/schema-map.c	Wed Jan 17 09:35:17 2001
***************
*** 208,220 ****
  {
   backsql_oc_map_rec tmp,*res;
   
! // Debug(LDAP_DEBUG_TRACE,"==>oc_with_name(): searching for objectclass with name='%s'\n",objclass,0,0);
   tmp.name=objclass;
   res=(backsql_oc_map_rec*)avl_find(si->oc_by_name,&tmp,(AVL_CMP)backsql_cmp_oc_name);
! // if (res!=NULL)
! //  Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0);
! // else
! //  Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0);
   return res;
  }
  
--- 208,220 ----
  {
   backsql_oc_map_rec tmp,*res;
   
! /*  Debug(LDAP_DEBUG_TRACE,"==>oc_with_name(): searching for objectclass with name='%s'\n",objclass,0,0); */
   tmp.name=objclass;
   res=(backsql_oc_map_rec*)avl_find(si->oc_by_name,&tmp,(AVL_CMP)backsql_cmp_oc_name);
! /*  if (res!=NULL) */
! /*   Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0); */
! /*  else */
! /*   Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0); */
   return res;
  }
  
***************
*** 222,234 ****
  {
   backsql_oc_map_rec tmp,*res;
   
! // Debug(LDAP_DEBUG_TRACE,"==>oc_with_id(): searching for objectclass with id='%d'\n",id,0,0);
   tmp.id=id;
   res=(backsql_oc_map_rec*)avl_find(si->oc_by_id,&tmp,(AVL_CMP)backsql_cmp_oc_id);
! // if (res!=NULL)
! //  Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0);
! // else
! //  Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0);
   return res;
  }
  
--- 222,234 ----
  {
   backsql_oc_map_rec tmp,*res;
   
! /*  Debug(LDAP_DEBUG_TRACE,"==>oc_with_id(): searching for objectclass with id='%d'\n",id,0,0); */
   tmp.id=id;
   res=(backsql_oc_map_rec*)avl_find(si->oc_by_id,&tmp,(AVL_CMP)backsql_cmp_oc_id);
! /*  if (res!=NULL) */
! /*   Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0); */
! /*  else */
! /*   Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0); */
   return res;
  }
  
***************
*** 236,250 ****
  {
   backsql_at_map_rec tmp,*res;
   
!  //Debug(LDAP_DEBUG_TRACE,"==>at_with_name(): searching for attribute with name='%s' (for objectclass '%s')\n",
!  //                attr,objclass->name,0);
   tmp.name=attr;
   res=(backsql_at_map_rec*)avl_find(objclass->attrs,&tmp,(AVL_CMP)backsql_cmp_attr);
!  //if (res!=NULL)
!   //Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): found name='%s', sel_expr='%s'\n",
!   //            res->name,res->sel_expr,0);
!  //else
!  // Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): not found\n",0,0,0);
   return res;
  }
  
--- 236,250 ----
  {
   backsql_at_map_rec tmp,*res;
   
!  /* Debug(LDAP_DEBUG_TRACE,"==>at_with_name(): searching for attribute with name='%s' (for objectclass '%s')\n", */
!  /*                 attr,objclass->name,0); */
   tmp.name=attr;
   res=(backsql_at_map_rec*)avl_find(objclass->attrs,&tmp,(AVL_CMP)backsql_cmp_attr);
!  /* if (res!=NULL) */
!   /* Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): found name='%s', sel_expr='%s'\n", */
!   /*             res->name,res->sel_expr,0); */
!  /* else */
!  /*  Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): not found\n",0,0,0); */
   return res;
  }
  
*** ./servers/slapd/back-sql/schema-map.h.FCS	Wed Jan 17 09:35:23 2001
--- ./servers/slapd/back-sql/schema-map.h	Wed Jan 17 09:38:40 2001
***************
*** 16,24 ****
   char *name;
   char *keytbl;
   char *keycol;
!  char *create_proc;//expected to return keyval of newly created entry
!  char *delete_proc;//supposed to expect keyval as parameter and delete all the attributes as well
!  int expect_return; //flags whether delete_proc is a function (whether back-sql should bind first parameter as output for return code)
   unsigned long id;
   Avlnode *attrs;
  }backsql_oc_map_rec;
--- 16,24 ----
   char *name;
   char *keytbl;
   char *keycol;
!  char *create_proc;/* expected to return keyval of newly created entry */
!  char *delete_proc;/* supposed to expect keyval as parameter and delete all the attributes as well */
!  int expect_return; /* flags whether delete_proc is a function (whether back-sql should bind first parameter as output for return code) */
   unsigned long id;
   Avlnode *attrs;
  }backsql_oc_map_rec;
***************
*** 25,43 ****
  
  typedef struct
  {
!  char *name;//literal name of corresponding LDAP attribute type
   char *from_tbls;
   char *join_where;
   char *sel_expr;
!  char *add_proc; //supposed to expect 2 binded values: entry keyval and attr. value to add, like "add_name(?,?,?)"
!  char *delete_proc; //supposed to expect 2 binded values: entry keyval and attr. value to delete
!  char *query; //for optimization purposes attribute load query is preconstructed from parts on schemamap load time
!  //following flags are bitmasks (first bit used for add_proc, second - for modify, third - for delete_proc)
!  int param_order; //order of parameters for procedures above; 1 means "data then keyval", 0 means "keyval then data"
!  int expect_return; //flags whether one or more of procedures is a function (whether back-sql should bind first parameter as output for return code)
  }backsql_at_map_rec;
  
! //defines to support bitmasks above
  #define BACKSQL_ADD	1
  #define BACKSQL_DEL	2
  
--- 25,43 ----
  
  typedef struct
  {
!  char *name;/* literal name of corresponding LDAP attribute type */
   char *from_tbls;
   char *join_where;
   char *sel_expr;
!  char *add_proc; /* supposed to expect 2 binded values: entry keyval and attr. value to add, like "add_name(?,?,?)" */
!  char *delete_proc; /* supposed to expect 2 binded values: entry keyval and attr. value to delete */
!  char *query; /* for optimization purposes attribute load query is preconstructed from parts on schemamap load time */
!  /* following flags are bitmasks (first bit used for add_proc, second - for modify, third - for delete_proc) */
!  int param_order; /* order of parameters for procedures above; 1 means "data then keyval", 0 means "keyval then data" */
!  int expect_return; /* flags whether one or more of procedures is a function (whether back-sql should bind first parameter as output for return code) */
  }backsql_at_map_rec;
  
! /* defines to support bitmasks above */
  #define BACKSQL_ADD	1
  #define BACKSQL_DEL	2
  
***************
*** 48,50 ****
--- 48,51 ----
  int backsql_destroy_schema_map(backsql_info *si);
  
  #endif
+ 
*** ./servers/slapd/back-sql/search.c.FCS	Wed Jan 17 09:35:52 2001
--- ./servers/slapd/back-sql/search.c	Wed Jan 17 09:36:24 2001
***************
*** 143,149 ****
   if (f->f_sub_any!=NULL)
    for(i=0;f->f_sub_any[i]!=NULL;i++)
    {
!    //Debug(LDAP_DEBUG_TRACE,"==>backsql_process_sub_filter(): sub_any='%s'\n",f->f_sub_any[i]->bv_val,0,0);
     if (bsi->bi->upper_func)
     {
      bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,ldap_pvt_str2upper(f->f_sub_any[i]->bv_val),"%",NULL);
--- 143,149 ----
   if (f->f_sub_any!=NULL)
    for(i=0;f->f_sub_any[i]!=NULL;i++)
    {
!    /* Debug(LDAP_DEBUG_TRACE,"==>backsql_process_sub_filter(): sub_any='%s'\n",f->f_sub_any[i]->bv_val,0,0); */
     if (bsi->bi->upper_func)
     {
      bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,ldap_pvt_str2upper(f->f_sub_any[i]->bv_val),"%",NULL);
***************
*** 221,242 ****
   }
  			
   backsql_merge_from_clause(&bsi->from,&bsi->from_len,at->from_tbls);
!  //need to add this attribute to list of attrs to load, so that we could do test_filter() later
   backsql_attrlist_add(bsi,at_name);
  
   if (at->join_where != NULL && strstr(bsi->join_where,at->join_where)==NULL)
    bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len," AND ",at->join_where,NULL);
  
!  //if (at!=&oc_attr)
!  // bsi->sel=backsql_strcat(bsi->sel,&bsi->sel_len,",",at->sel_expr," AS ",at->name,NULL);
  
   switch(f->f_choice)
   {
    case LDAP_FILTER_EQUALITY:
! 			//maybe we should check type of at->sel_expr here somehow,
! 			//to know whether upper_func is applicable, but for now
! 			//upper_func stuff is made for Oracle, where UPPER is
! 			//safely applicable to NUMBER etc.
  			if (bsi->bi->upper_func)
  			bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",
  					bsi->bi->upper_func,"(",at->sel_expr,")='",
--- 221,242 ----
   }
  			
   backsql_merge_from_clause(&bsi->from,&bsi->from_len,at->from_tbls);
!  /* need to add this attribute to list of attrs to load, so that we could do test_filter() later */
   backsql_attrlist_add(bsi,at_name);
  
   if (at->join_where != NULL && strstr(bsi->join_where,at->join_where)==NULL)
    bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len," AND ",at->join_where,NULL);
  
!  /* if (at!=&oc_attr) */
!  /*  bsi->sel=backsql_strcat(bsi->sel,&bsi->sel_len,",",at->sel_expr," AS ",at->name,NULL); */
  
   switch(f->f_choice)
   {
    case LDAP_FILTER_EQUALITY:
! 			/* maybe we should check type of at->sel_expr here somehow, */
! 			/* to know whether upper_func is applicable, but for now */
! 			/* upper_func stuff is made for Oracle, where UPPER is */
! 			/* safely applicable to NUMBER etc. */
  			if (bsi->bi->upper_func)
  			bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",
  					bsi->bi->upper_func,"(",at->sel_expr,")='",
***************
*** 335,343 ****
   SQLHSTMT sth;
   RETCODE rc;
   backsql_entryID base_id,*res,*c_id;
!  //Entry *e;
   BACKSQL_ROW_NTS row;
!  //int i;
   
   Debug(LDAP_DEBUG_TRACE,"==>backsql_oc_get_candidates(): oc='%s'\n",oc->name,0,0);
   bsi->oc=oc;
--- 335,343 ----
   SQLHSTMT sth;
   RETCODE rc;
   backsql_entryID base_id,*res,*c_id;
!  /* Entry *e; */
   BACKSQL_ROW_NTS row;
!  /* int i; */
   
   Debug(LDAP_DEBUG_TRACE,"==>backsql_oc_get_candidates(): oc='%s'\n",oc->name,0,0);
   bsi->oc=oc;
***************
*** 403,409 ****
   backsql_BindRowAsStrings(sth,&row);
   while ((rc=SQLFetch(sth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
    {
!    /*
     e=(Entry*)ch_calloc(1,sizeof(Entry)); 
     for (i=1;i<row.ncols;i++)
      {
--- 403,409 ----
   backsql_BindRowAsStrings(sth,&row);
   while ((rc=SQLFetch(sth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
    {
! #if 0
     e=(Entry*)ch_calloc(1,sizeof(Entry)); 
     for (i=1;i<row.ncols;i++)
      {
***************
*** 410,421 ****
       if (row.is_null[i]>0)
        {
         backsql_entry_addattr(e,row.col_names[i],row.cols[i],row.col_prec[i]);
! //       Debug(LDAP_DEBUG_TRACE,"prec=%d\n",(int)row.col_prec[i],0,0);
        }
!     // else
!     //  Debug(LDAP_DEBUG_TRACE,"NULL value in this row for attribute '%s'\n",row.col_names[i],0,0);
      }
!    */
  
     c_id=(backsql_entryID*)ch_calloc(1,sizeof(backsql_entryID));
     c_id->id=atoi(row.cols[0]);
--- 410,421 ----
       if (row.is_null[i]>0)
        {
         backsql_entry_addattr(e,row.col_names[i],row.cols[i],row.col_prec[i]);
! /*        Debug(LDAP_DEBUG_TRACE,"prec=%d\n",(int)row.col_prec[i],0,0); */
        }
!     /*  else */
!     /*   Debug(LDAP_DEBUG_TRACE,"NULL value in this row for attribute '%s'\n",row.col_names[i],0,0); */
      }
! #endif
  
     c_id=(backsql_entryID*)ch_calloc(1,sizeof(backsql_entryID));
     c_id->id=atoi(row.cols[0]);
***************
*** 485,498 ****
   backsql_init_search(&srch_info,bi,(char*)nbase,scope,slimit,tlimit,stoptime,filter,dbh,
  		be,conn,op,attrs);
  
!  //for each objectclass we try to construct query which gets IDs
!  //of entries matching LDAP query filter and scope (or at least candidates),
!  //and get the IDs
   avl_apply(bi->oc_by_name,(AVL_APPLY)backsql_oc_get_candidates,&srch_info,0,AVL_INORDER);
  	     
   nentries=0;
!  //now we load candidate entries (only those attrubutes mentioned in attrs and filter),
!  //test it against full filter and then send to client
   for(eid=srch_info.id_list;eid!=NULL;eid=eid->next)
    {
     /* check for abandon */
--- 485,498 ----
   backsql_init_search(&srch_info,bi,(char*)nbase,scope,slimit,tlimit,stoptime,filter,dbh,
  		be,conn,op,attrs);
  
!  /* for each objectclass we try to construct query which gets IDs */
!  /* of entries matching LDAP query filter and scope (or at least candidates), */
!  /* and get the IDs */
   avl_apply(bi->oc_by_name,(AVL_APPLY)backsql_oc_get_candidates,&srch_info,0,AVL_INORDER);
  	     
   nentries=0;
!  /* now we load candidate entries (only those attrubutes mentioned in attrs and filter), */
!  /* test it against full filter and then send to client */
   for(eid=srch_info.id_list;eid!=NULL;eid=eid->next)
    {
     /* check for abandon */
*** ./servers/slapd/back-sql/sql-wrap.c.FCS	Wed Jan 17 09:36:42 2001
--- ./servers/slapd/back-sql/sql-wrap.c	Fri Jan 19 06:30:54 2001
***************
*** 19,24 ****
--- 19,25 ----
  #include "sql-types.h"
  #include "sql-wrap.h"
  #include "schema-map.h"
+ #include "ldap_pvt.h"
  
  #define MAX_ATTR_LEN 16384
  
***************
*** 62,74 ****
   if (rc != SQL_SUCCESS)
    return rc;
   
!  //Debug(LDAP_DEBUG_TRACE,"==>_SQLPrepare()\n", 0,0,0);
   SQLGetInfo(dbh,SQL_DRIVER_NAME,drv_name,30,&len);
!  //Debug(LDAP_DEBUG_TRACE,"_SQLPrepare(): driver name='%s'\n", drv_name,0,0);
   if (!strncmp(ldap_pvt_str2upper(drv_name),"SQLSRV32.DLL",30))
    {
!    //stupid default result set in MS SQL Server does not support multiple active statements
!    //on the same connection -- so we are trying to make it not to use default result set...
     Debug(LDAP_DEBUG_TRACE,"_SQLprepare(): enabling MS SQL Server default result set workaround\n", 0,0,0);
     rc=SQLSetStmtOption(*sth,SQL_CONCURRENCY,SQL_CONCUR_ROWVER);
     if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
--- 63,75 ----
   if (rc != SQL_SUCCESS)
    return rc;
   
!  /* Debug(LDAP_DEBUG_TRACE,"==>_SQLPrepare()\n", 0,0,0); */
   SQLGetInfo(dbh,SQL_DRIVER_NAME,drv_name,30,&len);
!  /* Debug(LDAP_DEBUG_TRACE,"_SQLPrepare(): driver name='%s'\n", drv_name,0,0); */
   if (!strncmp(ldap_pvt_str2upper(drv_name),"SQLSRV32.DLL",30))
    {
!    /* stupid default result set in MS SQL Server does not support multiple active statements */
!    /* on the same connection -- so we are trying to make it not to use default result set... */
     Debug(LDAP_DEBUG_TRACE,"_SQLprepare(): enabling MS SQL Server default result set workaround\n", 0,0,0);
     rc=SQLSetStmtOption(*sth,SQL_CONCURRENCY,SQL_CONCUR_ROWVER);
     if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
***************
*** 86,93 ****
      }
    }
   
!  //Debug(LDAP_DEBUG_TRACE,"<==_SQLPrepare() calling SQLPrepare()\n", 0,0,0);
!  return SQLPrepare(*sth,query,SQL_NTS);
  }
  
  RETCODE backsql_BindParamStr(SQLHSTMT sth,int par_ind,char *str,int maxlen)
--- 87,94 ----
      }
    }
   
!  /* Debug(LDAP_DEBUG_TRACE,"<==_SQLPrepare() calling SQLPrepare()\n", 0,0,0); */
!  return SQLPrepare(*sth,(unsigned char *) query,SQL_NTS);
  }
  
  RETCODE backsql_BindParamStr(SQLHSTMT sth,int par_ind,char *str,int maxlen)
***************
*** 118,133 ****
   if (row == NULL)
    return SQL_ERROR;
   
!  //Debug(LDAP_DEBUG_TRACE,"==> backsql_BindRowAsStrings()\n",0,0,0);
   rc=SQLNumResultCols(sth,&row->ncols);
   if (rc != SQL_SUCCESS)
   {
!   //Debug(LDAP_DEBUG_TRACE,"_SQLBindRowAsStrings(): SQLNumResultCols() failed:\n",0,0,0);
    backsql_PrintErrors(SQL_NULL_HENV,SQL_NULL_HDBC,sth,rc);
   }
   else
   {
!   //Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: ncols=%d\n",(int)row->ncols,0,0);
    row->col_names=(char**)ch_calloc(row->ncols,sizeof(char*));
    row->cols=(char**)ch_calloc(row->ncols,sizeof(char*));
    row->col_prec=(UDWORD*)ch_calloc(row->ncols,sizeof(UDWORD));
--- 119,134 ----
   if (row == NULL)
    return SQL_ERROR;
   
!  /* Debug(LDAP_DEBUG_TRACE,"==> backsql_BindRowAsStrings()\n",0,0,0); */
   rc=SQLNumResultCols(sth,&row->ncols);
   if (rc != SQL_SUCCESS)
   {
!   /* Debug(LDAP_DEBUG_TRACE,"_SQLBindRowAsStrings(): SQLNumResultCols() failed:\n",0,0,0); */
    backsql_PrintErrors(SQL_NULL_HENV,SQL_NULL_HDBC,sth,rc);
   }
   else
   {
!   /* Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: ncols=%d\n",(int)row->ncols,0,0); */
    row->col_names=(char**)ch_calloc(row->ncols,sizeof(char*));
    row->cols=(char**)ch_calloc(row->ncols,sizeof(char*));
    row->col_prec=(UDWORD*)ch_calloc(row->ncols,sizeof(UDWORD));
***************
*** 134,151 ****
    row->is_null=(SQLINTEGER*)ch_calloc(row->ncols,sizeof(SQLINTEGER));
    for (i=1;i<=row->ncols;i++)
    {
!    rc=SQLDescribeCol(sth,(SQLSMALLINT)i,&colname[0],(SQLUINTEGER)sizeof(colname)-1,&name_len,&col_type,
            (UDWORD*) &col_prec,&col_scale,&col_null);
!    row->col_names[i-1]=ch_strdup(colname);
!    //Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: col_name=%s, col_prec[%d]=%d\n",colname,(int)i,(int)col_prec);
     if (col_type == SQL_LONGVARCHAR || col_type== SQL_LONGVARBINARY)
     {
! 	//row->cols[i-1]=NULL;
!     //row->col_prec[i-1]=-1;
! 	//such fields must be handled in some other way since they return 2G 
! 	//as their precision (at least it does so with MS SQL Server w/native driver)
! 	//for now, we just set fixed precision for such fields - dirty hack, but...
! 	//no time to deal with SQLGetData()
  	col_prec=MAX_ATTR_LEN;
  	row->cols[i-1]=(char*)ch_calloc((col_prec+1),sizeof(char));
      row->col_prec[i-1]=col_prec;
--- 135,152 ----
    row->is_null=(SQLINTEGER*)ch_calloc(row->ncols,sizeof(SQLINTEGER));
    for (i=1;i<=row->ncols;i++)
    {
!    rc=SQLDescribeCol((void *)sth,(SQLSMALLINT)i,&colname[0],(SQLUINTEGER)sizeof(colname)-1,&name_len,&col_type,
            (UDWORD*) &col_prec,&col_scale,&col_null);
!    row->col_names[i-1]=ch_strdup((const char *) colname);
!    /* Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: col_name=%s, col_prec[%d]=%d\n",colname,(int)i,(int)col_prec); */
     if (col_type == SQL_LONGVARCHAR || col_type== SQL_LONGVARBINARY)
     {
! 	/* row->cols[i-1]=NULL; */
!     /* row->col_prec[i-1]=-1; */
! 	/* such fields must be handled in some other way since they return 2G  */
! 	/* as their precision (at least it does so with MS SQL Server w/native driver) */
! 	/* for now, we just set fixed precision for such fields - dirty hack, but... */
! 	/* no time to deal with SQLGetData() */
  	col_prec=MAX_ATTR_LEN;
  	row->cols[i-1]=(char*)ch_calloc((col_prec+1),sizeof(char));
      row->col_prec[i-1]=col_prec;
***************
*** 161,167 ****
     }
    }
   }
!  //Debug(LDAP_DEBUG_TRACE,"<== backsql_BindRowAsStrings()\n",0,0,0);
   return rc;
  }
  
--- 162,168 ----
     }
    }
   }
!  /* Debug(LDAP_DEBUG_TRACE,"<== backsql_BindRowAsStrings()\n",0,0,0); */
   return rc;
  }
  
***************
*** 217,226 ****
  int backsql_free_db_env(backsql_info *si)
  {
   Debug(LDAP_DEBUG_TRACE,"==>backsql_free_db_env()\n",0,0,0);
!  //Debug(LDAP_DEBUG_TRACE,"free_db_env(): delete AVL tree here!!!\n",0,0,0);
   
!  //stop, if frontend waits for all threads to shutdown before calling this --
!  //then what we are going to delete?? everything is deleted already...
   Debug(LDAP_DEBUG_TRACE,"<==backsql_free_db_env()\n",0,0,0);
   return SQL_SUCCESS;
  }
--- 218,227 ----
  int backsql_free_db_env(backsql_info *si)
  {
   Debug(LDAP_DEBUG_TRACE,"==>backsql_free_db_env()\n",0,0,0);
!  /* Debug(LDAP_DEBUG_TRACE,"free_db_env(): delete AVL tree here!!!\n",0,0,0); */
   
!  /* stop, if frontend waits for all threads to shutdown before calling this -- */
!  /* then what we are going to delete?? everything is deleted already... */
   Debug(LDAP_DEBUG_TRACE,"<==backsql_free_db_env()\n",0,0,0);
   return SQL_SUCCESS;
  }
***************
*** 238,245 ****
     backsql_PrintErrors(si->db_env,SQL_NULL_HDBC,SQL_NULL_HENV,rc);
     return NULL;
    }
!  if ((rc=SQLConnect(dbc->dbh,si->dbname,SQL_NTS,si->dbuser,SQL_NTS,
!                       si->dbpasswd,SQL_NTS) != SQL_SUCCESS))
    {
     if (rc != SQL_SUCCESS_WITH_INFO)
      Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLConnect() failed:\n",0,0,0);
--- 239,246 ----
     backsql_PrintErrors(si->db_env,SQL_NULL_HDBC,SQL_NULL_HENV,rc);
     return NULL;
    }
!  if ((rc=SQLConnect(dbc->dbh,(unsigned char *)si->dbname,SQL_NTS,(unsigned char *)si->dbuser,SQL_NTS,
!                       (unsigned char *)si->dbpasswd,SQL_NTS) != SQL_SUCCESS))
    {
     if (rc != SQL_SUCCESS_WITH_INFO)
      Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLConnect() failed:\n",0,0,0);
***************
*** 268,275 ****
   ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
   conn=(backsql_db_conn*)avl_delete(&si->db_conns,&tmp,(AVL_CMP)backsql_cmp_connid);
   ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
!  //we have one thread per connection, as I understand -- so we can
!  //get this out of critical section
   if (conn!=NULL)
    { 
     Debug(LDAP_DEBUG_TRACE,"backsql_free_db_conn(): closing db connection\n",0,0,0);
--- 269,276 ----
   ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
   conn=(backsql_db_conn*)avl_delete(&si->db_conns,&tmp,(AVL_CMP)backsql_cmp_connid);
   ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
!  /* we have one thread per connection, as I understand -- so we can */
!  /* get this out of critical section */
   if (conn!=NULL)
    { 
     Debug(LDAP_DEBUG_TRACE,"backsql_free_db_conn(): closing db connection\n",0,0,0);
***************
*** 288,295 ****
   Debug(LDAP_DEBUG_TRACE,"==>backsql_get_db_conn()\n",0,0,0);
   
   tmp.ldap_cid=ldapc->c_connid;
!  //we have one thread per connection, as I understand -- so we do not need
!  // locking here
   dbc=(backsql_db_conn*)avl_find(si->db_conns,&tmp,(AVL_CMP)backsql_cmp_connid);
   if (!dbc)
    dbc=backsql_open_db_conn(si,ldapc->c_connid);
--- 289,296 ----
   Debug(LDAP_DEBUG_TRACE,"==>backsql_get_db_conn()\n",0,0,0);
   
   tmp.ldap_cid=ldapc->c_connid;
!  /* we have one thread per connection, as I understand -- so we do not need */
!  /*  locking here */
   dbc=(backsql_db_conn*)avl_find(si->db_conns,&tmp,(AVL_CMP)backsql_cmp_connid);
   if (!dbc)
    dbc=backsql_open_db_conn(si,ldapc->c_connid);
*** ./servers/slapd/back-sql/util.c.FCS	Wed Jan 17 09:36:58 2001
--- ./servers/slapd/back-sql/util.c	Wed Jan 17 09:37:04 2001
***************
*** 34,40 ****
   int cdlen,cslen,grow;
   char *cstr;
   
!  //Debug(LDAP_DEBUG_TRACE,"==>my_strcat()\n");
   va_start(strs,buflen);
   if (dest==NULL || *buflen<=0)
    {
--- 34,40 ----
   int cdlen,cslen,grow;
   char *cstr;
   
!  /* Debug(LDAP_DEBUG_TRACE,"==>my_strcat()\n"); */
   va_start(strs,buflen);
   if (dest==NULL || *buflen<=0)
    {
***************
*** 48,55 ****
     grow=BACKSQL_MAX(BACKSQL_STR_GROW,cslen);
     if (*buflen-cdlen < cslen)
      {
!      //Debug(LDAP_DEBUG_TRACE,"my_strcat(): buflen=%d, cdlen=%d, cslen=%d -- reallocating dest\n",
!      //                     *buflen,cdlen,cslen);
       dest=(char*)ch_realloc(dest,(*buflen)+grow*sizeof(char));
       if (dest == NULL)
        {
--- 48,55 ----
     grow=BACKSQL_MAX(BACKSQL_STR_GROW,cslen);
     if (*buflen-cdlen < cslen)
      {
!      /* Debug(LDAP_DEBUG_TRACE,"my_strcat(): buflen=%d, cdlen=%d, cslen=%d -- reallocating dest\n", */
!      /*                      *buflen,cdlen,cslen); */
       dest=(char*)ch_realloc(dest,(*buflen)+grow*sizeof(char));
       if (dest == NULL)
        {
***************
*** 56,68 ****
         Debug(LDAP_DEBUG_ANY,"my_strcat(): could not reallocate string buffer.\n",0,0,0);
        }
       *buflen+=grow;
!      //Debug(LDAP_DEBUG_TRACE,"my_strcat(): new buflen=%d, dest=%p\n",*buflen,dest,0);
      }
     strcat(dest,cstr);
     cdlen+=cslen;
    }
   va_end(strs);
!  //Debug(LDAP_DEBUG_TRACE,"<==my_strcat() (dest='%s')\n",dest,0,0);
   return dest;
  } 
  
--- 56,68 ----
         Debug(LDAP_DEBUG_ANY,"my_strcat(): could not reallocate string buffer.\n",0,0,0);
        }
       *buflen+=grow;
!      /* Debug(LDAP_DEBUG_TRACE,"my_strcat(): new buflen=%d, dest=%p\n",*buflen,dest,0); */
      }
     strcat(dest,cstr);
     cdlen+=cslen;
    }
   va_end(strs);
!  /* Debug(LDAP_DEBUG_TRACE,"<==my_strcat() (dest='%s')\n",dest,0,0); */
   return dest;
  } 
  
***************
*** 115,121 ****
  
  #define BACKSQL_NEXT_WORD  {while (*s && isspace(*s)) s++; if (!*s) return res; q=s; while (*q && !isspace(*q)) q++; if (*q) *q++='\0';}
   BACKSQL_NEXT_WORD;
!  res=backsql_strcat(res,&res_len,s,NULL);//table name
   s=q;
  
   BACKSQL_NEXT_WORD;
--- 115,121 ----
  
  #define BACKSQL_NEXT_WORD  {while (*s && isspace(*s)) s++; if (!*s) return res; q=s; while (*q && !isspace(*q)) q++; if (*q) *q++='\0';}
   BACKSQL_NEXT_WORD;
!  res=backsql_strcat(res,&res_len,s,NULL);/* table name */
   s=q;
  
   BACKSQL_NEXT_WORD;
***************
*** 124,132 ****
    s=q;
    BACKSQL_NEXT_WORD;
   }
!  //res=backsql_strcat(res,&res_len," AS ",s,NULL);//table alias
!  //oracle doesn't understand AS :(
!  res=backsql_strcat(res,&res_len," ",s,NULL);//table alias
   return res;
  }
  
--- 124,132 ----
    s=q;
    BACKSQL_NEXT_WORD;
   }
!  /* res=backsql_strcat(res,&res_len," AS ",s,NULL);//table alias */
!  /* oracle doesn't understand AS :( */
!  res=backsql_strcat(res,&res_len," ",s,NULL);/* table alias */
   return res;
  }
  
***************
*** 134,147 ****
  {
   char *s,*p,*srcc,*pos,e;
  
!  //Debug(LDAP_DEBUG_TRACE,"==>backsql_merge_from_clause(): dest_from='%s',src_from='%s'\n",
!  //				dest_from,src_from,0);
   srcc=ch_strdup(src_from);
   p=srcc;
   while(*p)
   {
    s=backsql_get_table_spec(&p);
!  // Debug(LDAP_DEBUG_TRACE,"backsql_merge_from_clause(): p='%s' s='%s'\n",p,s,0);  
    if (*dest_from==NULL)
     *dest_from=backsql_strcat(*dest_from,dest_len,s,NULL);
    else
--- 134,147 ----
  {
   char *s,*p,*srcc,*pos,e;
  
!  /* Debug(LDAP_DEBUG_TRACE,"==>backsql_merge_from_clause(): dest_from='%s',src_from='%s'\n", */
!  /* 				dest_from,src_from,0); */
   srcc=ch_strdup(src_from);
   p=srcc;
   while(*p)
   {
    s=backsql_get_table_spec(&p);
!  /*  Debug(LDAP_DEBUG_TRACE,"backsql_merge_from_clause(): p='%s' s='%s'\n",p,s,0);   */
    if (*dest_from==NULL)
     *dest_from=backsql_strcat(*dest_from,dest_len,s,NULL);
    else
***************
*** 152,158 ****
    if (s)
  	ch_free(s);
   }
! // Debug(LDAP_DEBUG_TRACE,"<==backsql_merge_from_clause()\n",0,0,0);
   free(srcc);
   return 1;
  }
--- 152,158 ----
    if (s)
  	ch_free(s);
   }
! /*  Debug(LDAP_DEBUG_TRACE,"<==backsql_merge_from_clause()\n",0,0,0); */
   free(srcc);
   return 1;
  }
*** ./servers/slapd/back-sql/sql-types.h.FCS	Wed Jan 17 09:39:03 2001
--- ./servers/slapd/back-sql/sql-types.h	Wed Jan 17 09:39:06 2001
***************
*** 23,25 ****
--- 23,26 ----
  }BACKSQL_ROW_NTS;
  
  #endif
+ 
*** ./servers/slapd/back-sql/sql-wrap.h.FCS	Wed Jan 17 09:39:30 2001
--- ./servers/slapd/back-sql/sql-wrap.h	Wed Jan 17 09:39:33 2001
***************
*** 26,28 ****
--- 26,29 ----
  int backsql_free_db_conn(Backend *be,Connection *ldapc);
  
  #endif
+ 
*** ./servers/slapd/back-sql/util.h.FCS	Wed Jan 17 09:39:51 2001
--- ./servers/slapd/back-sql/util.h	Wed Jan 17 09:40:00 2001
***************
*** 59,61 ****
--- 59,62 ----
  
  
  #endif
+ 
*** ./servers/slapd/back-sql/bind.c.FCS	Thu Jan 18 20:46:57 2001
--- ./servers/slapd/back-sql/bind.c	Thu Jan 18 20:47:30 2001
***************
*** 56,62 ****
       return 1;
      }
    
!    res=backsql_dn2id(bi,&user_id,dbh,ndn);
     if (res==NULL)
      {
       Debug(LDAP_DEBUG_TRACE,"backsql_bind(): could not retrieve bind dn id - no such entry\n",0,0,0);
--- 56,62 ----
       return 1;
      }
    
!    res=backsql_dn2id(bi,&user_id,dbh,(char *)ndn);
     if (res==NULL)
      {
       Debug(LDAP_DEBUG_TRACE,"backsql_bind(): could not retrieve bind dn id - no such entry\n",0,0,0);
*** ./configure.in.FCS	Wed Jan 17 08:47:55 2001
--- ./configure.in	Thu Jan 18 21:14:15 2001
***************
*** 791,797 ****
  			AC_CHECK_LIB(krb5, main,
  				[have_krb5=yes
  				KRB5_LIBS="-lkrb5 -lcrypto -lcom_err"],
! 				[have_krb5=no],
  				[-lcrypto -lcom_err])
  
  		elif test $krb5_impl = heimdal; then
--- 791,801 ----
  			AC_CHECK_LIB(krb5, main,
  				[have_krb5=yes
  				KRB5_LIBS="-lkrb5 -lcrypto -lcom_err"],
! 				AC_CHECK_LIB(krb5, main,
! 				    [have_krb5=yes
! 				    KRB5_LIBS="-lkrb5 -lk5crypto -lcom_err"],
! 				    [have_krb5=no],
! 				    [-lk5crypto -lcom_err]),
  				[-lcrypto -lcom_err])
  
  		elif test $krb5_impl = heimdal; then
***************
*** 837,843 ****
  	if test $ac_cv_header_kerberosIV_krb_h = yes ; then
  		if test $krb5_impl = mit; then
  			AC_CHECK_LIB(krb4, main, [have_k425=yes
! 				KRB4_LIBS="-lkrb4 -ldes425"], [have_k425=no],
  				[-ldes425 -lkrb5 -lcrypto -lcom_err])
  
  		elif test $krb5_impl = heimdal; then
--- 841,851 ----
  	if test $ac_cv_header_kerberosIV_krb_h = yes ; then
  		if test $krb5_impl = mit; then
  			AC_CHECK_LIB(krb4, main, [have_k425=yes
! 				KRB4_LIBS="-lkrb4 -ldes425"],
! 				AC_CHECK_LIB(krb4, main, [have_k425=yes
! 				    KRB4_LIBS="-lkrb4 -ldes425"],
! 				    [have_k425=no],
! 				    [-ldes425 -lkrb5 -lk5crypto -lcom_err]),
  				[-ldes425 -lkrb5 -lcrypto -lcom_err])
  
  		elif test $krb5_impl = heimdal; then
***************
*** 1704,1711 ****
  
  	if test $have_wrappers = yes ; then
  		AC_DEFINE(HAVE_TCPD,1, [define if you have -lwrap])
- 		WRAP_LIBS="-lwrap"
  
  		dnl We add another check for -lnsl since some libwrap's
  		dnl need it, but it isn't always included from above
  		AC_CHECK_LIB(nsl, main)
--- 1712,1731 ----
  
  	if test $have_wrappers = yes ; then
  		AC_DEFINE(HAVE_TCPD,1, [define if you have -lwrap])
  
+ 		dnl We try to link statically if ever possible. This
+ 		dnl avois library probs in a Solaris v9 environment
+ 
+ 		WRAP_LIBS=""
+ 		for dir in /usr/lib /usr/local/lib `echo $LIBS | sed 's/:/ /'`
+ 		do
+ 		    if test -f $dir/libwrap.a; then
+ 			WRAP_LIBS="$dir/libwrap.a"
+ 			break
+ 		    fi
+ 		done
+ 		test "X$WRAP_LIBS" = "X" && WRAP_LIBS="-lwrap"
+ 
  		dnl We add another check for -lnsl since some libwrap's
  		dnl need it, but it isn't always included from above
  		AC_CHECK_LIB(nsl, main)
***************
*** 1782,1787 ****
--- 1802,1813 ----
  
  dnl ----------------------------------------------------------------
  dnl
+ dnl Check for libpam which is conditionally required by Cyrus SASL
+ dnl
+ AC_CHECK_LIB(pam, pam_authenticate, [PAM_LIBS='-lpam'], [PAM_LIBS=''])
+ 
+ dnl ----------------------------------------------------------------
+ dnl
  dnl Check for Cyrus SASL
  dnl
  ol_link_sasl=no
***************
*** 1791,1800 ****
  
  	if test $ac_cv_header_sasl_h = yes ; then
  		AC_CHECK_LIB(sasl, sasl_client_init,
! 			[have_cyrus_sasl=yes], [have_cyrus_sasl=no])
  
  		if test $have_cyrus_sasl != no ; then
! 			SASL_LIBS="-lsasl"
  			AC_DEFINE(HAVE_CYRUS_SASL,1,[define if you have Cyrus SASL])
  			ol_link_sasl=yes
  		fi
--- 1817,1838 ----
  
  	if test $ac_cv_header_sasl_h = yes ; then
  		AC_CHECK_LIB(sasl, sasl_client_init,
! 			[have_cyrus_sasl=yes], 
! 			[have_cyrus_sasl=no])
  
+ 		EXTRA_SASL_LIBS=""
+ 		if test $have_cyrus_sasl = no -a \
+ 		    $ol_with_kerberos != no -a $ol_link_krb5 = yes ; then
+ 		    unset ac_cv_lib_$ac_lib_var
+ 		    AC_CHECK_LIB(sasl, sasl_client_init,
+ 			[have_cyrus_sasl=yes;
+ 			EXTRA_SASL_LIBS="-lkrb4 $PAM_LIBS"],
+ 			[have_cyrus_sasl=no],
+ 			[-lkrb4 $PAM_LIBS])
+ 		fi
+ 
  		if test $have_cyrus_sasl != no ; then
! 			SASL_LIBS="-lsasl $EXTRA_SASL_LIBS"
  			AC_DEFINE(HAVE_CYRUS_SASL,1,[define if you have Cyrus SASL])
  			ol_link_sasl=yes
  		fi