]> git.sur5r.net Git - openldap/commitdiff
changes:
authorPierangelo Masarati <ando@openldap.org>
Tue, 13 Aug 2002 17:12:27 +0000 (17:12 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 13 Aug 2002 17:12:27 +0000 (17:12 +0000)
- re-style according to the style giudelines for better readability
- updated to recent frontend/backend API changes
- fixed a few quirks about normalization
- "optimized" a few memory allocation/string handling functions
- fixed a few quirks about add/modify (still have to look ad modrdn)

todo:
- there is still something broken (at least with PostgreSQL and IBM db2,
  the two RDBMS O have at hand) when adding
- move everything to struct bervals and try to save a few strlen
- try some LDAP/SQL syntax relation to use appropriate value bind if possible
- ...

17 files changed:
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/bind.c
servers/slapd/back-sql/config.c
servers/slapd/back-sql/docs/install
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/entry-id.h
servers/slapd/back-sql/init.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/other.c
servers/slapd/back-sql/schema-map.c
servers/slapd/back-sql/schema-map.h
servers/slapd/back-sql/search.c
servers/slapd/back-sql/sql-types.h
servers/slapd/back-sql/sql-wrap.c
servers/slapd/back-sql/sql-wrap.h
servers/slapd/back-sql/util.c
servers/slapd/back-sql/util.h

index d38b9d0120e01c4e13dbab02e66b32d5c0a78594..02614e3ff2a3412e5ac5fb8bafdfc329f12ad34f 100644 (file)
  *      in file LICENSE in the top-level directory of the distribution.
  */
 
-
 #include "external.h"
 #include "sql-types.h"
-#define BACKSQL_MAX_DN_LEN 255
-
-typedef struct
-{
- char *dbhost;
- int dbport;
- 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;
- char *id_query;
- char *upper_func;
- Avlnode *db_conns;
- Avlnode *oc_by_name;
- Avlnode *oc_by_id;
- int schema_loaded;
- ldap_pvt_thread_mutex_t dbconn_mutex;
- ldap_pvt_thread_mutex_t schema_mutex;
- SQLHENV db_env;
- int   isTimesTen; /* TimesTen */
- int   has_ldapinfo_dn_ru;  /* Does ldapinfo.dn_ru exist in schema? */
-}backsql_info;
-
-#endif
+
+/*
+ * Better use the standard length of 8192 (as of servers/slapd/dn.c) ?
+ */
+#define BACKSQL_MAX_DN_LEN     255
+
+typedef struct {
+       char            *dbhost;
+       int             dbport;
+       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;
+       char            *id_query;
+       char            *upper_func;
+       char            *strcast_func;
+       Avlnode         *db_conns;
+       Avlnode         *oc_by_name;
+       Avlnode         *oc_by_id;
+       int             schema_loaded;
+       ldap_pvt_thread_mutex_t         dbconn_mutex;
+       ldap_pvt_thread_mutex_t         schema_mutex;
+       SQLHENV         db_env;
+       int             isTimesTen;
+
+       /* 
+        * Does ldapinfo.dn_ru exist in schema?
+        */
+       int             has_ldapinfo_dn_ru;  
+} backsql_info;
+
+#define BACKSQL_SUCCESS( rc ) \
+       ( (rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO )
+
+#endif /* __BACKSQL_H__ */
 
index 35847d0bff5d73e74e6296e6428925aaba998d22..9c112c19605c81742e46e868af662a90d26ac2b7 100644 (file)
 #include "util.h"
 #include "entry-id.h"
 
-int backsql_bind(BackendDB *be,Connection *conn,Operation *op,
-       struct berval *dn,struct berval *ndn,int method,struct berval *cred,struct berval *edn)
+int 
+backsql_bind(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       struct berval   *dn,
+       struct berval   *ndn,
+       int method,
+       struct berval   *cred,
+       struct berval   *edn )
 {
backsql_info *bi=(backsql_info*)be->be_private;
backsql_entryID user_id,*res;
SQLHDBC dbh;
AttributeDescription *password = slap_schema.si_ad_userPassword;
Entry         *e,user_entry;
Attribute     *a;
backsql_srch_info bsi;
      backsql_info            *bi = (backsql_info*)be->be_private;
      backsql_entryID         user_id;
      SQLHDBC                 dbh;
      AttributeDescription    *password = slap_schema.si_ad_userPassword;
      Entry                   *e, user_entry;
      Attribute               *a;
      backsql_srch_info       bsi;
  
- Debug(LDAP_DEBUG_TRACE,"==>backsql_bind()\n",0,0,0);
- if ( be_isroot_pw( be, conn, ndn, cred ) )
-    {
-     ber_dupbv(edn, be_root_dn(be));
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_bind() root bind\n",0,0,0);
-     return LDAP_SUCCESS;
-    }
- ber_dupbv(edn, ndn);
- if (method == LDAP_AUTH_SIMPLE)
-  {     
-   dbh=backsql_get_db_conn(be,conn);
-
-   if (!dbh)
-    {
-     Debug(LDAP_DEBUG_TRACE,"backsql_bind(): could not get connection handle - exiting\n",0,0,0);
-     send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-     return 1;
-    }
-  
-   res=backsql_dn2id(bi,&user_id,dbh,ndn->bv_val);
-   if (res==NULL)
-    {
-     Debug(LDAP_DEBUG_TRACE,"backsql_bind(): could not retrieve bind dn id - no such entry\n",0,0,0);
-     send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,NULL, NULL, NULL, NULL );
-     return 1;
-    }
-    
-   backsql_init_search(&bsi,bi,(char*)ndn->bv_val,LDAP_SCOPE_BASE,-1,-1,-1,NULL,dbh,
-                be,conn,op,NULL);
-   e=backsql_id2entry(&bsi,&user_entry,&user_id);
-   if (e==NULL)
-    {
-     Debug(LDAP_DEBUG_TRACE,"backsql_bind(): error in backsql_id2entry() - auth failed\n",0,0,0);
-     send_ldap_result( conn, op, LDAP_OTHER,NULL, NULL, NULL, NULL );
-     return 1;
-    }
-    
-   if ( ! access_allowed( be, conn, op, e, password, NULL, ACL_AUTH, NULL ) )
-    {
-     send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, NULL, NULL, NULL, NULL );
-     return 1;
-    }
-
-   if ( (a = attr_find( e->e_attrs, password )) == NULL )
-    {
-     send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, NULL, NULL );
-     return 1;
-    }
-
-   if ( slap_passwd_check( conn, a, cred ) != 0 ) 
-    {
-     send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,NULL, NULL, NULL, NULL );
-     return 1;
-    }
-  }  
- else /*method != SIMPLE */
-  {
-   send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
-                   NULL, "authentication method not supported", NULL, NULL );
-   return 1;
-  }
- Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0);
- return 0;
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 );
+
+       if ( be_isroot_pw( be, conn, ndn, cred ) ) {
+               ber_dupbv( edn, be_root_dn( be ) );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_bind() root bind\n", 
+                               0, 0, 0 );
+               return LDAP_SUCCESS;
+       }
+
+       ber_dupbv( edn, ndn );
+
+       if ( method != LDAP_AUTH_SIMPLE ) {
+               send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
+                       NULL, "authentication method not supported", 
+                       NULL, NULL );
+               return 1;
+       }
+
+       /*
+        * method = LDAP_AUTH_SIMPLE
+        */
+       dbh = backsql_get_db_conn( be, conn );
+       if (!dbh) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
+                       "could not get connection handle - exiting\n",
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       if ( backsql_dn2id( bi, &user_id, dbh, ndn ) != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
+                       "could not retrieve bind dn id - no such entry\n", 
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
+                               NULL, NULL, NULL, NULL );
+               return 1;
+       }
+
+       backsql_init_search( &bsi, bi, ndn, LDAP_SCOPE_BASE, -1, -1, -1,
+                       NULL, dbh, be, conn, op, NULL );
+       e = backsql_id2entry( &bsi, &user_entry, &user_id );
+       if ( e == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
+                       "error in backsql_id2entry() - auth failed\n",
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                               NULL, NULL, NULL, NULL );
+               return 1;
+       }
+
+       if ( ! access_allowed( be, conn, op, e, password, NULL, 
+                               ACL_AUTH, NULL ) ) {
+               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, 
+                               NULL, NULL, NULL, NULL );
+               return 1;
+       }
+
+       if ( ( a = attr_find( e->e_attrs, password ) ) == NULL ) {
+               send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH, 
+                               NULL, NULL, NULL, NULL );
+               return 1;
+       }
+
+       if ( slap_passwd_check( conn, a, cred ) != 0 ) {
+               send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
+                               NULL, NULL, NULL, NULL );
+               return 1;
+       }
+
+       Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0);
+       return 0;
 }
  
-int backsql_unbind(BackendDB *be,Connection *conn,Operation *op)
+int
+backsql_unbind(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op )
 {
Debug(LDAP_DEBUG_TRACE,"==>backsql_unbind()\n",0,0,0);
send_ldap_result(conn,op,LDAP_SUCCESS,NULL,NULL,NULL,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_unbind()\n",0,0,0);
- return 0;
      Debug( LDAP_DEBUG_TRACE, "==>backsql_unbind()\n", 0, 0, 0 );
      send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, 0 );
      Debug( LDAP_DEBUG_TRACE, "<==backsql_unbind()\n", 0, 0, 0 );
      return 0;
 }
 
 #endif /* SLAPD_SQL */
+
index 85c9cabf09f7cf231d8ebfbbc5b007a5be43ded0..7403cc1d6e9e33be40fff8ad64e9908848309888 100644 (file)
 #include "back-sql.h"
 #include "sql-wrap.h"
 
-int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char **argv)
+int
+backsql_db_config(
+       BackendDB       *be,
+       const char      *fname,
+       int             lineno,
+       int             argc,
+       char            **argv )
 {
- backsql_info *si=(backsql_info*) be->be_private;
-
- Debug(LDAP_DEBUG_TRACE,"==>backsql_db_config()\n",0,0,0);
- if (!si)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_db_config: be_private is NULL!!!\n",0,0,0);
-   exit(1);
-  }
-  
- if (!strcasecmp(argv[0],"dbhost"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing hostname in dbhost directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->dbhost=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): hostname=%s\n",si->dbhost,0,0);
-    }
-   return(0);
-  }
-  
- if (!strcasecmp(argv[0],"dbuser"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing username in dbuser directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->dbuser=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbuser=%s\n",argv[1],0,0);
-    }
-   return(0);
-  }
- if (!strcasecmp(argv[0],"dbpasswd"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing password in dbpasswd directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->dbpasswd=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbpasswd=%s\n",si->dbpasswd,0,0);
-    }
-   return(0);
-  }
+       backsql_info    *si = (backsql_info *)be->be_private;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_db_config()\n", 0, 0, 0 );
+       assert( si );
   
- if (!strcasecmp(argv[0],"dbname"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing database name in dbname directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->dbname=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbname=%s\n",si->dbname,0,0);
-    }
-   return(0);
-  }
-
- if (!strcasecmp(argv[0],"subtree_cond"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL condition in subtree_cond directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->subtree_cond=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): subtree_cond=%s\n",si->subtree_cond,0,0);
-    }
-   return(0);
-  }
-
- if (!strcasecmp(argv[0],"oc_query"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL statement in oc_query directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->oc_query=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): oc_query=%s\n",si->oc_query,0,0);
-    }
-   return(0);
-  }
-
- if (!strcasecmp(argv[0],"at_query"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL statement in at_query directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->at_query=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): at_query=%s\n",si->at_query,0,0);
-    }
-   return(0);
-  }
-
- if (!strcasecmp(argv[0],"insentry_query"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL statement in insentry_query directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->insentry_query=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): insentry_query=%s\n",si->insentry_query,0,0);
-    }
-   return(0);
-  }
-
- if (!strcasecmp(argv[0],"upper_func"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing function name in upper_func directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->upper_func=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): upper_func=%s\n",si->upper_func,0,0);
-    }
-   return(0);
-  }
-
- if (!strcasecmp(argv[0],"delentry_query"))
-  {
-   if (argc<2)
-    {
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL statement in delentry_query directive\n",
-                     fname,lineno,0);
-    }
-   else
-    {
-     si->delentry_query=ch_strdup(argv[1]);
-     Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): delentry_query=%s\n",si->delentry_query,0,0);
-    }
-   return(0);
-  }
- Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): unknown directive '%s' (ignored)\n",
-                     fname,lineno,argv[0]);
- return 0;
+       if ( !strcasecmp( argv[ 0 ], "dbhost" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "<==backsql_db_config (%s line %d): "
+                               "missing hostname in dbhost directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->dbhost = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE,
+                       "<==backsql_db_config(): hostname=%s\n",
+                       si->dbhost, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "dbuser" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "<==backsql_db_config (%s line %d): "
+                               "missing username in dbuser directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->dbuser = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbuser=%s\n",
+                       si->dbuser, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "dbpasswd" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "<==backsql_db_config (%s line %d): "
+                               "missing password in dbpasswd directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->dbpasswd = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "dbpasswd=%s\n", /* si->dbpasswd */ "xxxx", 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "dbname" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "<==backsql_db_config (%s line %d): "
+                               "missing database name in dbname directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->dbname = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbname=%s\n",
+                       si->dbname, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "subtree_cond" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "<==backsql_db_config (%s line %d): "
+                               "missing SQL condition "
+                               "in subtree_cond directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->subtree_cond = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "subtree_cond=%s\n", si->subtree_cond, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "<==backsql_db_config (%s line %d): "
+                               "missing SQL statement "
+                               "in oc_query directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->oc_query = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "oc_query=%s\n", si->oc_query, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "at_query" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_db_config (%s line %d): "
+                               "missing SQL statement "
+                               "in at_query directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->at_query = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "at_query=%s\n", si->at_query, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "insentry_query" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "<==backsql_db_config (%s line %d): "
+                               "missing SQL statement "
+                               "in insentry_query directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->insentry_query = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "insentry_query=%s\n", si->insentry_query, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "upper_func" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_db_config (%s line %d): "
+                               "missing function name "
+                               "in upper_func directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->upper_func = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "upper_func=%s\n", si->upper_func, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "strcast_func" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_db_config (%s line %d): "
+                               "missing function name "
+                               "in strcast_func directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->strcast_func = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "strcast_func=%s\n", si->strcast_func, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "delentry_query" ) ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_db_config (%s line %d): "
+                               "missing SQL statement "
+                               "in delentry_query directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+               si->delentry_query = ch_strdup( argv[ 1 ] );
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "delentry_query=%s\n", si->delentry_query, 0, 0 );
+
+       } else if ( !strcasecmp( argv[ 0 ], "has_ldapinfo_dn_ru") ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_db_config (%s line %d): "
+                               "missing { yes | no }"
+                               "in has_ldapinfo_dn_ru directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+
+               if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+                       si->has_ldapinfo_dn_ru = 1;
+               } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+                       si->has_ldapinfo_dn_ru = 0;
+               } else {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_db_config (%s line %d): "
+                               "has_ldapinfo_dn_ru directive arg "
+                               "must be \"yes\" or \"no\"\n",
+                               fname, lineno, 0 );
+                       return 1;
+
+               }
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "has_ldapinfo_dn_ru=%s\n", 
+                       si->has_ldapinfo_dn_ru == 0 ? "no" : "yes", 0, 0 );
+
+       } else {
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): "
+                       "unknown directive '%s' (ignored)\n",
+                       fname, lineno, argv[ 0 ] );
+       }
+
+       return 0;
 }
 
 #endif /* SLAPD_SQL */
+
index daa686367eca8aefd186b857802fe532b458c12a..230bf0ad624900e653c7dc677da7f88861629fd5 100644 (file)
@@ -10,7 +10,7 @@ Then, at top of OpenLDAP source tree, run
 this should build back-sql-enabled slapd, provided that you have iODBC/unixODBC
 libraries and include files in include/library paths, "make install"...
 In other words, follow installation procedure described in OpenLDAP 
-Administrators Guide, adding --enbale-sql option to configure, and
+Administrators Guide, adding --enable-sql option to configure, and
 having iODBC/unixODBC libraries installed an accessible by compiler.
 
 Under Win32/MSVC++, I modified the workspace so that back-sql is built into
@@ -41,7 +41,7 @@ Several things worth noting about ODBC:
   Also worth noting are: ODBC-ODBC bridge by EasySoft (which was claimed
    by several people to be far more effective and stable than OpenLink),
    OpenRDA package etc.
-- be carefull defining RDBMS connection parameters, you'll probably need only
+- be careful defining RDBMS connection parameters, you'll probably need only
   "dbname" directive - all the rest can be defined in datasource. Every other
   directive is used to override value stored in datasource definition.
   Maybe you will want to use dbuser/dbpasswd to override credentials defined in datasource
index 73086850f458dfbbb137f956f1bd669028236f6b..eab33bbc140462d3fe4b2635781479331353603f 100644 (file)
@@ -13,7 +13,8 @@
 
 #include <stdio.h>
 #include <sys/types.h>
-#include <string.h>
+#include "ac/string.h"
+#include "ldap_pvt.h"
 #include "slap.h"
 #include "back-sql.h"
 #include "sql-wrap.h"
 #include "entry-id.h"
 #include "util.h"
 
-backsql_entryID* backsql_free_entryID(backsql_entryID* id)
+backsql_entryID *
+backsql_free_entryID( backsql_entryID *id, int freeit )
 {
- backsql_entryID* next=id->next;
- if (id->dn!=NULL)
-  free(id->dn);
- free(id);
- return next;
+       backsql_entryID         *next;
+
+       assert( id );
+
+       next = id->next;
+
+       if ( id->dn.bv_val != NULL ) {
+               free( id->dn.bv_val );
+       }
+
+       if ( freeit ) {
+               free( id );
+       }
+
+       return next;
 }
 
-backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID *id,SQLHDBC dbh,char *dn)
+/*
+ * FIXME: need to change API to pass backsql_entryID **id 
+ * and return an error code, to distinguish LDAP_OTHER from
+ * LDAP_NO_SUCH_OBJECT
+ */
+int
+backsql_dn2id(
+       backsql_info            *bi,
+       backsql_entryID         *id,
+       SQLHDBC                 dbh,
+       struct berval           *dn )
 {
- SQLHSTMT sth; 
- BACKSQL_ROW_NTS row;
- /*SQLINTEGER nrows=0;*/
- RETCODE rc;
-
- /* TimesTen */
- char upperdn[BACKSQL_MAX_DN_LEN+1];
- char* toBind;
- int i, j, k;
-
- Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): dn='%s'\n",dn,0,0);
- /* begin TimesTen */
- Debug(LDAP_DEBUG_TRACE, "id_query '%s'\n", bi->id_query, 0, 0);
- rc = backsql_Prepare(dbh,&sth,bi->id_query,0);
- if (rc != SQL_SUCCESS) {
-   Debug(LDAP_DEBUG_TRACE, "backsql_dn2id(): error preparing SQL:\n", 0, 0, 0);
-   Debug(LDAP_DEBUG_TRACE, "%s\n", bi->id_query, 0, 0);
-   backsql_PrintErrors(SQL_NULL_HENV, dbh, sth, rc);
-   SQLFreeStmt(sth, SQL_DROP);
-   return NULL;
- }
-
- if (bi->has_ldapinfo_dn_ru) {
-   /* Prepare an upper cased, byte reversed version that can be
-      searched using indexes */
-
-   for ((i=0, j=strlen(dn)-1); *(dn+i); (i++, j--)) {
-     *(upperdn+i) = toupper(*(dn+j));
-   }   
-   *(upperdn+i) = '\0';
-   Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): upperdn='%s'\n",upperdn,0,0);
-   toBind = upperdn;
- }
- else {
-   if (bi->isTimesTen) {
-     for (i = 0; *(dn+i); i++) {
-       *(upperdn+i) = toupper(*(dn+i)); /* Copy while upper casing */
-     }
-     *(upperdn+i) = '\0';
-     Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): upperdn='%s'\n",upperdn,0,0);
-     toBind = upperdn;
-   }
-   else
-     toBind = dn;
- }
-
- if ((rc=backsql_BindParamStr(sth,1,toBind,
-                  BACKSQL_MAX_DN_LEN)) != SQL_SUCCESS)
- /* end TimesTen*/
- {
-   Debug(LDAP_DEBUG_TRACE,"backsql_dn2id(): error binding dn parameter:\n",0,0,0);
-   backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
-   SQLFreeStmt(sth,SQL_DROP);
-   return NULL;
- }
- if ((rc=SQLExecute(sth)) != SQL_SUCCESS)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_dn2id(): error executing query:\n",0,0,0);
-   backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
-   SQLFreeStmt(sth,SQL_DROP);
-   return NULL;
-  }
- backsql_BindRowAsStrings(sth,&row);
- if ((rc=SQLFetch(sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
-  {
-   if (id==NULL)
-    {
-     id=(backsql_entryID*)ch_calloc(1,sizeof(backsql_entryID));
-    }
-   id->id=atoi(row.cols[0]);
-   id->keyval=atoi(row.cols[1]);
-   id->oc_id=atoi(row.cols[2]);
-   id->dn=ch_strdup(dn);
-   id->next=NULL;
-  }
- else
-  id=NULL;
- backsql_FreeRow(&row);
- SQLFreeStmt(sth, SQL_DROP);
- if (id!=NULL)
-  Debug(LDAP_DEBUG_TRACE,"<==backsql_dn2id(): id=%d\n",(int)id->id,0,0);
- else
-  Debug(LDAP_DEBUG_TRACE,"<==backsql_dn2id(): no match\n",0,0,0);
- return id;
-}
+       SQLHSTMT                sth; 
+       BACKSQL_ROW_NTS         row;
+#if 0
+       SQLINTEGER              nrows = 0;
+#endif
+       RETCODE                 rc;
+       int                     res;
+
+       /* TimesTen */
+       char                    upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
+       char                    *toBind;
+       int                     i, j;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): dn='%s'\n", 
+                       dn->bv_val, 0, 0 );
+
+       assert( id );
+
+       if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
+               Debug( LDAP_DEBUG_TRACE, 
+                       "backsql_dn2id(): DN \"%s\" (%ld bytes) "
+                       "exceeds max DN length (%d):\n",
+                       dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
+               return LDAP_OTHER;
+       }
+       
+       /* begin TimesTen */
+       Debug(LDAP_DEBUG_TRACE, "id_query '%s'\n", bi->id_query, 0, 0);
+       assert( bi->id_query );
+       rc = backsql_Prepare( dbh, &sth, bi->id_query, 0 );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, 
+                       "backsql_dn2id(): error preparing SQL:\n%s", 
+                       bi->id_query, 0, 0);
+               backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               return LDAP_OTHER;
+       }
+
+       if ( bi->has_ldapinfo_dn_ru ) {
+               /*
+                * Prepare an upper cased, byte reversed version 
+                * that can be searched using indexes
+                */
+
+               for ( i = 0, j = dn->bv_len - 1; dn->bv_val[ i ]; i++, j--) {
+                       upperdn[ i ] = dn->bv_val[ j ];
+               }
+               upperdn[ i ] = '\0';
+               ldap_pvt_str2upper( upperdn );
+
+               Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): upperdn='%s'\n",
+                               upperdn, 0, 0 );
+               toBind = upperdn;
+       } else {
+               if ( bi->isTimesTen ) {
+                       AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 );
+                       ldap_pvt_str2upper( upperdn );
+                       Debug( LDAP_DEBUG_TRACE,
+                               "==>backsql_dn2id(): upperdn='%s'\n",
+                               upperdn, 0, 0 );
+                       toBind = upperdn;
+
+               } else {
+                       toBind = dn->bv_val;
+               }
+       }
+
+       rc = backsql_BindParamStr( sth, 1, toBind, BACKSQL_MAX_DN_LEN );
+       if ( rc != SQL_SUCCESS) {
+               /* end TimesTen */ 
+               Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
+                       "error binding dn=\"%s\" parameter:\n", toBind, 0, 0 );
+               backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               return LDAP_OTHER;
+       }
 
+       rc = SQLExecute( sth );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
+                       "error executing query (\"%s\", \"%s\"):\n", 
+                       bi->id_query, toBind, 0 );
+               backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               return LDAP_OTHER;
+       }
 
-int backsql_get_attr_vals(backsql_at_map_rec *at,backsql_srch_info *bsi)
+       backsql_BindRowAsStrings( sth, &row );
+       rc = SQLFetch( sth );
+       if ( BACKSQL_SUCCESS( rc ) ) {
+               id->id = atoi( row.cols[ 0 ] );
+               id->keyval = atoi( row.cols[ 1 ] );
+               id->oc_id = atoi( row.cols[ 2 ] );
+               ber_dupbv( &id->dn, dn );
+               id->next = NULL;
+
+               res = LDAP_SUCCESS;
+
+       } else {
+               res = LDAP_NO_SUCH_OBJECT;
+       }
+       backsql_FreeRow( &row );
+
+       SQLFreeStmt( sth, SQL_DROP );
+       if ( res == LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): id=%ld\n",
+                               id->id, 0, 0 );
+       } else {
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): no match\n",
+                               0, 0, 0 );
+       }
+       return res;
+}
+
+int
+backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
 {
- RETCODE rc;
- SQLHSTMT sth;
- BACKSQL_ROW_NTS row;
- int i;
+       RETCODE         rc;
+       SQLHSTMT        sth;
+       BACKSQL_ROW_NTS row;
+       int             i;
+
+       assert( at );
+       assert( bsi );
  
- Debug(LDAP_DEBUG_TRACE,"==>backsql_get_attr_vals(): oc='%s' attr='%s' keyval=%d\n",
-                       bsi->oc->name,at->name,bsi->c_eid->keyval);
-
- if ((rc=backsql_Prepare(bsi->dbh,&sth,at->query,0)) != SQL_SUCCESS)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error preparing query: %s\n",at->query,0,0);
-   backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
-   return 1;
-  }
-
- if (backsql_BindParamID(sth,1,&(bsi->c_eid->keyval)) != SQL_SUCCESS)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error binding key value parameter\n",0,0,0);
-  return 1;
- }
-
- if ((rc=SQLExecute(sth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error executing attribute query '%s'\n",at->query,0,0);
-   backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
-   SQLFreeStmt(sth,SQL_DROP);
-   return 1;
-  }
-
- backsql_BindRowAsStrings(sth,&row);
- while ((rc=SQLFetch(sth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
-  {
-   for (i=0;i<row.ncols;i++)
-    {
-     if (row.is_null[i]>0)
-      {
-       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);
- SQLFreeStmt(sth,SQL_DROP);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_get_attr_vals()\n",0,0,0);
- return 1;
-}
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
+               "oc='%s' attr='%s' keyval=%ld\n",
+               bsi->oc->name, at->name, bsi->c_eid->keyval );
+
+       rc = backsql_Prepare( bsi->dbh, &sth, at->query, 0 );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+                       "error preparing query: %s\n", at->query, 0, 0 );
+               backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
+               return 1;
+       }
+
+       rc = backsql_BindParamID( sth, 1, &bsi->c_eid->keyval );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+                       "error binding key value parameter\n", 0, 0, 0 );
+               return 1;
+       }
+
+       rc = SQLExecute( sth );
+       if ( ! BACKSQL_SUCCESS( rc ) ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
+                       "error executing attribute query '%s'\n",
+                       at->query, 0, 0 );
+               backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               return 1;
+       }
 
+       backsql_BindRowAsStrings( sth, &row );
 
-Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* eid)
+       rc = SQLFetch( sth );
+       for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
+               for ( i = 0; i < row.ncols; i++ ) {
+                       if ( row.is_null[ i ] > 0 ) {
+                                       backsql_entry_addattr( bsi->e, 
+                                               row.col_names[ i ],
+                                               row.cols[ i ],
+#if 0
+                                               row.col_prec[ i ]
+#else
+                                               /*
+                                                * FIXME: what if a binary 
+                                                * is fetched?
+                                                */
+                                               strlen( row.cols[ i ] )
+#endif
+                                               );
+#if 0
+                               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
+                       }
+               }
+       }
+
+       backsql_FreeRow( &row );
+       SQLFreeStmt( sth, SQL_DROP );
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
+
+       return 1;
+}
+
+Entry *
+backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
 {
- char **c_at_name;
- backsql_at_map_rec *at;
+       char                    **c_at_name;
+       backsql_at_map_rec      *at;
+       int                     rc;
 
Debug(LDAP_DEBUG_TRACE,"==>backsql_id2entry()\n",0,0,0);
      Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
 
- bsi->oc=backsql_oc_with_id(bsi->bi,eid->oc_id);
- bsi->e=e;
- bsi->c_eid=eid;
- e->e_attrs=NULL;
- e->e_private=NULL;
-/* if (bsi->base_dn != NULL)???*/
+       rc = dnPrettyNormal( NULL, &eid->dn, &e->e_name, &e->e_nname );
+       if ( rc != LDAP_SUCCESS ) {
+               return NULL;
+       }
 
- e->e_id=eid->id;
- e->e_dn=ch_strdup(bsi->c_eid->dn);
- e->e_ndn=dn_normalize(ch_strdup(bsi->c_eid->dn));
+       bsi->oc = backsql_oc_with_id( bsi->bi, eid->oc_id );
+       bsi->e = e;
+       bsi->c_eid = eid;
+       e->e_attrs = NULL;
+       e->e_private = NULL;
  
- if (bsi->attrs!=NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_id2entry(): custom attribute list\n",0,0,0);
-  for(c_at_name=bsi->attrs;*c_at_name!=NULL;c_at_name++)
-  {
-   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);
-   if (at!=NULL)
-    backsql_get_attr_vals(at,bsi);
-   else
-       Debug(LDAP_DEBUG_TRACE,"backsql_id2entry(): attribute '%s' is not defined for objectlass '%s'\n",
-                       *c_at_name,bsi->oc->name,0);
-
-  }
- }
- else
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_id2entry(): retrieving all attributes\n",0,0,0);
-  avl_apply(bsi->oc->attrs,(AVL_APPLY)backsql_get_attr_vals,bsi,0,AVL_INORDER);
- }
- backsql_entry_addattr(bsi->e,"objectclass",bsi->oc->name,strlen(bsi->oc->name));
-
- Debug(LDAP_DEBUG_TRACE,"<==backsql_id2entry()\n",0,0,0);
- return e;
+       /* if ( bsi->base_dn != NULL)??? */
+       
+       e->e_id = eid->id;
+       if ( bsi->attrs != NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
+                       "custom attribute list\n", 0, 0, 0 );
+               for ( c_at_name = bsi->attrs; *c_at_name != NULL; c_at_name++ ) {
+                       if ( !strcasecmp( *c_at_name, "objectclass" ) 
+                                       || !strcasecmp( *c_at_name, "0.10" ) ) {
+#if 0
+                               backsql_entry_addattr( bsi->e, "objectclass",
+                                               bsi->oc->name,
+                                               strlen( bsi->oc->name ) );
+#endif
+                               continue;
+                       }
+                       at = backsql_at_with_name( bsi->oc, *c_at_name );
+                       if ( at != NULL ) {
+                               backsql_get_attr_vals( at, bsi );
+                       } else {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
+                                       "attribute '%s' is not defined "
+                                       "for objectlass '%s'\n",
+                                       *c_at_name, bsi->oc->name, 0 );
+                       }
+               }
+       } else {
+               Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
+                       "retrieving all attributes\n", 0, 0, 0 );
+               avl_apply( bsi->oc->attrs, (AVL_APPLY)backsql_get_attr_vals,
+                               bsi, 0, AVL_INORDER );
+       }
+
+       backsql_entry_addattr( bsi->e, "objectclass", bsi->oc->name,
+                       strlen( bsi->oc->name ) );
+
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
+
+       return e;
 }
 
 #endif /* SLAPD_SQL */
+
index 5792d85eea8fb07deb0c9323eaded0f3ebed1fa0..bc52fa8669f15035184f5214513e64e385a5178c 100644 (file)
  */
 
 
-typedef struct __backsql_entryID
-{
- unsigned long id;
- unsigned long keyval;
- unsigned long oc_id;
- char *dn;
- struct __backsql_entryID *next;
-}backsql_entryID;
+typedef struct backsql_entryID {
+       unsigned long           id;
+       unsigned long           keyval;
+       unsigned long           oc_id;
+       struct berval           dn;
+       struct backsql_entryID  *next;
+} 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*/
+int backsql_dn2id( backsql_info *bi, backsql_entryID *id,
+               SQLHDBC dbh, struct berval *dn );
+/* returns next */
+backsql_entryID *backsql_free_entryID( backsql_entryID *id, int freeit );
 
-#endif
+#endif /* __BACKSQL_ENTRYID_H__ */
 
index 92f7b5b90ba562fc2716896fc0a7b740269912f2..ab38e378466b7a4ff66b3ec976b5ed109a26751b 100644 (file)
 
 #ifdef SLAPD_SQL_DYNAMIC
 
-int backsql_LTX_init_module(int argc, char *argv[]) {
-    BackendInfo bi;
+int
+backsql_LTX_init_module(
+       int             argc, 
+       char            *argv[] )
+{
+       BackendInfo bi;
 
-    memset( &bi, '\0', sizeof(bi) );
-    bi.bi_type = "sql";
-    bi.bi_init = backbacksql_initialize;
+       memset( &bi, '\0', sizeof( bi ) );
+       bi.bi_type = "sql";
+       bi.bi_init = backbacksql_initialize;
 
-    backend_add(&bi);
-    return 0;
+       backend_add( &bi );
+       return 0;
 }
 
 #endif /* SLAPD_SHELL_DYNAMIC */
 
-int sql_back_initialize(
-    BackendInfo        *bi
-)
+int
+sql_back_initialize(
+       BackendInfo     *bi )
 { 
- Debug(LDAP_DEBUG_TRACE,"==>backsql_initialize()\n",0,0,0);
+       Debug( LDAP_DEBUG_TRACE,"==>backsql_initialize()\n", 0, 0, 0 );
+       
        bi->bi_open = 0;
        bi->bi_config = 0;
        bi->bi_close = 0;
@@ -72,165 +77,234 @@ int sql_back_initialize(
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = backsql_connection_destroy;
        
-       Debug(LDAP_DEBUG_TRACE,"<==backsql_initialize()\n",0,0,0);
+       Debug( LDAP_DEBUG_TRACE,"<==backsql_initialize()\n", 0, 0, 0 );
        return 0;
 }
 
 
-int backsql_destroy ( BackendInfo *bi )
+int
+backsql_destroy( 
+       BackendInfo     *bi )
 {
Debug(LDAP_DEBUG_TRACE,"==>backsql_destroy()\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_destroy()\n",0,0,0);
- return 0;
      Debug( LDAP_DEBUG_TRACE, "==>backsql_destroy()\n", 0, 0, 0 );
      Debug( LDAP_DEBUG_TRACE, "<==backsql_destroy()\n", 0, 0, 0 );
      return 0;
 }
 
-int backsql_db_init(BackendDB *bd)
+int
+backsql_db_init(
+       BackendDB       *bd )
 {
- backsql_info *si;
- Debug(LDAP_DEBUG_TRACE,"==>backsql_db_init()\n",0,0,0);
- si = (backsql_info *) ch_calloc( 1, sizeof(backsql_info) );
- ldap_pvt_thread_mutex_init(&si->dbconn_mutex);
- ldap_pvt_thread_mutex_init(&si->schema_mutex);
- backsql_init_db_env(si);
+       backsql_info *si;
  
- bd->be_private=si;
- Debug(LDAP_DEBUG_TRACE,"<==backsql_db_init()\n",0,0,0);
- return 0;
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_db_init()\n", 0, 0, 0 );
+       si = (backsql_info *)ch_calloc( 1, sizeof( backsql_info ) );
+       ldap_pvt_thread_mutex_init( &si->dbconn_mutex );
+       ldap_pvt_thread_mutex_init( &si->schema_mutex );
+       backsql_init_db_env( si );
+       si->has_ldapinfo_dn_ru = -1;
+
+       bd->be_private = si;
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_db_init()\n", 0, 0, 0 );
+       return 0;
 }
 
-int backsql_db_destroy(BackendDB *bd)
+int
+backsql_db_destroy(
+       BackendDB       *bd )
 {
backsql_info *si=(backsql_info*)bd->be_private;
      backsql_info *si = (backsql_info*)bd->be_private;
  
- Debug(LDAP_DEBUG_TRACE,"==>backsql_db_destroy()\n",0,0,0);
- ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
- backsql_free_db_env(si);
- ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
- ldap_pvt_thread_mutex_lock(&si->schema_mutex);
- backsql_destroy_schema_map(si);
- ldap_pvt_thread_mutex_unlock(&si->schema_mutex);
- ldap_pvt_thread_mutex_destroy(&si->schema_mutex);
- ldap_pvt_thread_mutex_destroy(&si->dbconn_mutex);
- free(si->dbname);
- free(si->dbuser);
- if (si->dbpasswd)
-  free(si->dbpasswd);
- if (si->dbhost)
-  free(si->dbhost);
- if (si->upper_func)
-  free(si->upper_func);
- free(si->subtree_cond);
- free(si->oc_query);
- free(si->at_query);
- free(si->insentry_query);
- free(si->delentry_query);
- free(si);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_db_destroy()\n",0,0,0);
- return 0;
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_db_destroy()\n", 0, 0, 0 );
+       ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
+       backsql_free_db_env( si );
+       ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
+       ldap_pvt_thread_mutex_lock( &si->schema_mutex );
+       backsql_destroy_schema_map( si );
+       ldap_pvt_thread_mutex_unlock( &si->schema_mutex );
+       ldap_pvt_thread_mutex_destroy( &si->schema_mutex );
+       ldap_pvt_thread_mutex_destroy( &si->dbconn_mutex );
+       free( si->dbname );
+       free( si->dbuser );
+       if ( si->dbpasswd ) {
+               free( si->dbpasswd );
+       }
+       if ( si->dbhost ) {
+               free( si->dbhost );
+       }
+       if ( si->upper_func ) {
+               free( si->upper_func );
+       }
+       
+       free( si->subtree_cond );
+       free( si->oc_query );
+       free( si->at_query );
+       free( si->insentry_query );
+       free( si->delentry_query );
+       free( si );
+       
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_db_destroy()\n", 0, 0, 0 );
+       return 0;
 }
 
-int backsql_db_open (BackendDB *bd)
+int
+backsql_db_open(
+       BackendDB       *bd )
 {
- backsql_info *si=(backsql_info*)bd->be_private;
- Connection tmp;
- SQLHDBC dbh;
- int idq_len;
-
- Debug(LDAP_DEBUG_TRACE,"==>backsql_db_open(): testing RDBMS connection\n",0,0,0);
- if (si->dbname==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): datasource name not specified (use dbname directive in slapd.conf)\n",0,0,0);
-  return 1;
- }
- if (si->dbuser==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): user name not specified (use dbuser directive in slapd.conf)\n",0,0,0);
-  return 1;
- }
- if (si->subtree_cond==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): subtree search SQL condition not specified (use subtree_cond directive in slapd.conf)\n",0,0,0);
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' as default\n",backsql_def_subtree_cond,0,0);
-  si->subtree_cond=ch_strdup(backsql_def_subtree_cond);
- }
- if (si->oc_query==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): objectclass mapping SQL statement not specified (use oc_query directive in slapd.conf)\n",0,0,0);
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_oc_query,0,0);
-  si->oc_query=ch_strdup(backsql_def_oc_query);
- }
- if (si->at_query==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): attribute mapping SQL statement not specified (use at_query directive in slapd.conf)\n",0,0,0);
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_at_query,0,0);
-  si->at_query=ch_strdup(backsql_def_at_query);
- }
- if (si->insentry_query==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): entry insertion SQL statement not specified (use insentry_query directive in slapd.conf)\n",0,0,0);
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_insentry_query,0,0);
-  si->insentry_query=ch_strdup(backsql_def_insentry_query);
- }
- if (si->delentry_query==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): entry deletion SQL statement not specified (use delentry_query directive in slapd.conf)\n",0,0,0);
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_delentry_query,0,0);
-  si->delentry_query=ch_strdup(backsql_def_delentry_query);
- }
- tmp.c_connid=-1;
- dbh=backsql_get_db_conn(bd,&tmp);
- if (!dbh)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): connection failed, exiting\n",0,0,0
-);
-  return 1;
- }
-
- si->id_query=NULL;
- idq_len=0;
- if (si->upper_func==NULL)
- {
-  si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,"dn=?",NULL);
- }
- else
- {
-    if (si->has_ldapinfo_dn_ru) {
-      si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,"dn_ru=?",NULL);
-    }
-    else {
-      if (si->isTimesTen) {
-    si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,si->upper_func,"(dn)=?",NULL);
-      }
-      else {
-               si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,si->upper_func,"(dn)=",si->upper_func,"(?)",NULL);
-         }
+       backsql_info    *si = (backsql_info*)bd->be_private;
+       Connection      tmp;
+       SQLHDBC         dbh;
+       int             idq_len;
+       struct berval   bv;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
+               "testing RDBMS connection\n", 0, 0, 0 );
+       if ( si->dbname == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "datasource name not specified "
+                       "(use dbname directive in slapd.conf)\n", 0, 0, 0 );
+               return 1;
+       }
+       
+       if ( si->dbuser == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "user name not specified "
+                       "(use dbuser directive in slapd.conf)\n", 0, 0, 0 );
+               return 1;
+       }
+       
+       if ( si->subtree_cond == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "subtree search SQL condition not specified "
+                       "(use subtree_cond directive in slapd.conf)\n", 
+                       0, 0, 0);
+               if ( si->upper_func ) {
+                       struct berval   bv = { 0, NULL };
+                       int             len = 0;
+
+                       backsql_strcat( &bv, &len, si->upper_func,
+                                       backsql_def_upper_subtree_cond, NULL );
+                       si->subtree_cond = bv.bv_val;
+               } else {
+                       si->subtree_cond = ch_strdup( backsql_def_subtree_cond );
+               }
+                       
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "setting '%s' as default\n",
+                       si->subtree_cond, 0, 0 );
        }
- }
+
+       if ( si->oc_query == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "objectclass mapping SQL statement not specified "
+                       "(use oc_query directive in slapd.conf)\n", 0, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "setting '%s' by default\n", 
+                       backsql_def_oc_query, 0, 0 );
+               si->oc_query = ch_strdup( backsql_def_oc_query );
+       }
+       
+       if ( si->at_query == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "attribute mapping SQL statement not specified "
+                       "(use at_query directive in slapd.conf)\n",
+                       0, 0, 0 );
+               Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "setting '%s' by default\n",
+                       backsql_def_at_query, 0, 0 );
+               si->at_query = ch_strdup( backsql_def_at_query );
+       }
+       
+       if ( si->insentry_query == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "entry insertion SQL statement not specified "
+                       "(use insentry_query directive in slapd.conf)\n",
+                       0, 0, 0 );
+               Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "setting '%s' by default\n",
+                       backsql_def_insentry_query, 0, 0 );
+               si->insentry_query = ch_strdup( backsql_def_insentry_query );
+       }
+       
+       if ( si->delentry_query == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "entry deletion SQL statement not specified "
+                       "(use delentry_query directive in slapd.conf)\n",
+                       0, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "setting '%s' by default\n",
+                       backsql_def_delentry_query, 0, 0 );
+               si->delentry_query = ch_strdup( backsql_def_delentry_query );
+       }
+       
+       tmp.c_connid =- 1;
+       dbh = backsql_get_db_conn( bd, &tmp );
+       if ( !dbh ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "connection failed, exiting\n", 0, 0, 0 );
+               return 1;
+       }
+
+       si->id_query = NULL;
+       idq_len = 0;
+
+       bv.bv_val = NULL;
+       bv.bv_len = 0;
+       if ( si->upper_func == NULL ) {
+               backsql_strcat( &bv, &idq_len, backsql_id_query, 
+                               "dn=?", NULL );
+       } else {
+               if ( si->has_ldapinfo_dn_ru ) {
+                       backsql_strcat( &bv, &idq_len, backsql_id_query,
+                                       "dn_ru=?", NULL );
+               } else {
+                       if ( si->isTimesTen ) {
+                               backsql_strcat( &bv, &idq_len, 
+                                               backsql_id_query,
+                                               si->upper_func, "(dn)=?",
+                                               NULL );
+                       } else {
+                               backsql_strcat( &bv, &idq_len, 
+                                               backsql_id_query,
+                                               si->upper_func, "(dn)=",
+                                               si->upper_func, "(?)", NULL );
+                       }
+               }
+       }
+       si->id_query = bv.bv_val;
  
-backsql_free_db_conn(bd,&tmp);
- if (!si->schema_loaded)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): test failed, schema map not loaded - exiting\n",0,0,0);
-  return 1;
- }
- Debug(LDAP_DEBUG_TRACE,"<==backsql_db_open(): test succeeded, schema map loaded\n",0,0,0);
- return 0;
+       backsql_free_db_conn( bd, &tmp );
+       if ( !si->schema_loaded ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+                       "test failed, schema map not loaded - exiting\n",
+                       0, 0, 0 );
+               return 1;
+       }
+       
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_db_open(): "
+               "test succeeded, schema map loaded\n", 0, 0, 0 );
+       return 0;
 }
 
-int backsql_db_close(BackendDB *bd)
+int
+backsql_db_close(
+       BackendDB       *bd )
 {
Debug(LDAP_DEBUG_TRACE,"==>backsql_db_close()\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_close()\n",0,0,0);
- return 0;
      Debug( LDAP_DEBUG_TRACE, "==>backsql_db_close()\n", 0, 0, 0 );
      Debug( LDAP_DEBUG_TRACE, "<==backsql_db_close()\n", 0, 0, 0 );
      return 0;
 }
 
-int backsql_connection_destroy(BackendDB *be,Connection *conn)
+int
+backsql_connection_destroy(
+       BackendDB       *be,
+       Connection      *conn )
 {
Debug(LDAP_DEBUG_TRACE,"==>backsql_connection_destroy()\n",0,0,0);
backsql_free_db_conn(be,conn);
Debug(LDAP_DEBUG_TRACE,"<==backsql_connection_destroy()\n",0,0,0);
- return 0;
      Debug( LDAP_DEBUG_TRACE, "==>backsql_connection_destroy()\n", 0, 0, 0 );
      backsql_free_db_conn( be, conn );
      Debug( LDAP_DEBUG_TRACE, "<==backsql_connection_destroy()\n", 0, 0, 0 );
      return 0;
 }
 
 #endif /* SLAPD_SQL */
+
index 9514da01552c760cbb3c5140c9195b495b93d0f7..f1bc54869b8cb7b613bf01a8b604fa1962267529 100644 (file)
 #include "entry-id.h"
 #include "util.h"
 
-int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
-       const char *dn,const char *ndn,Modifications *modlist)
+/*
+ * PostgreSQL doesn't work without :(
+ */
+#define        BACKSQL_REALLOC_STMT
+
+int
+backsql_modify(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       struct berval   *dn,
+       struct berval   *ndn,
+       Modifications   *modlist )
 {
- backsql_info *bi=(backsql_info*)be->be_private;
- SQLHDBC dbh;
- SQLHSTMT sth;
- RETCODE rc;
- backsql_oc_map_rec *oc=NULL;
- backsql_entryID e_id,*res;
- Modification *c_mod;
- Modifications *ml;
- 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);
- if (!dbh)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not get connection handle - exiting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
- if (res==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not lookup entry id\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
-  return 1;
- }
-
- oc=backsql_oc_with_id(bi,e_id.oc_id);
- if (oc==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): cannot determine objectclass of entry -- aborting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
-
- SQLAllocStmt(dbh, &sth);
-
- Debug(LDAP_DEBUG_TRACE,"backsql_modify(): traversing modifications list\n",0,0,0);
- for(ml=modlist;ml!=NULL;ml=ml->sml_next)
- {
-  c_mod=&ml->sml_mod;
-  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute '%s'\n",c_mod->sm_desc->ad_cname.bv_val,0,0);
-  at=backsql_at_with_name(oc,c_mod->sm_desc->ad_cname.bv_val);
-  if (at==NULL)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute provided is not registered in this objectclass ('%s')\n",c_mod->sm_desc->ad_cname.bv_val,0,0);
-   continue;
-  }
+       backsql_info            *bi = (backsql_info*)be->be_private;
+       SQLHDBC                 dbh;
+       SQLHSTMT                sth;
+       RETCODE                 rc;
+       backsql_oc_map_rec      *oc = NULL;
+       backsql_entryID         e_id;
+       int                     res;
+       Modification            *c_mod;
+       Modifications           *ml;
+       backsql_at_map_rec      *at = NULL;
+       struct berval           *at_val;
+       int                     i;
+       /* first parameter no, parameter order */
+       SQLUSMALLINT            pno, po;
+       /* procedure return code */
+       int                     prc;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_modify(): changing entry '%s'\n",
+               ndn->bv_val, 0, 0 );
+       dbh = backsql_get_db_conn( be, conn );
+       if ( !dbh ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                       "could not get connection handle - exiting\n", 
+                       0, 0, 0 );
+               /*
+                * FIXME: we don't want to send back 
+                * excessively detailed messages
+                */
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       res = backsql_dn2id( bi, &e_id, dbh, ndn );
+       if ( res != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                       "could not lookup entry id\n", 0, 0, 0 );
+               send_ldap_result( conn, op, res , "", NULL, NULL, NULL );
+               return 1;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+               "modifying entry '%s' (id=%ld)\n", 
+               e_id.dn.bv_val, e_id.id, 0 );
+
+       oc = backsql_oc_with_id( bi, e_id.oc_id );
+       if ( oc == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                       "cannot determine objectclass of entry -- aborting\n",
+                       0, 0, 0 );
+               /*
+                * FIXME: we don't want to send back 
+                * excessively detailed messages
+                */
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       SQLAllocStmt( dbh, &sth );
+       Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+               "traversing modifications list\n", 0, 0, 0 );
+       for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
+               char *attrname;
+
+               c_mod = &ml->sml_mod;
+
+               attrname = c_mod->sm_desc->ad_cname.bv_val;
+               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): attribute '%s'\n",
+                               attrname, 0, 0 );
+               at = backsql_at_with_name( oc, attrname );
+               if ( at == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                               "attribute provided is not registered "
+                               "in objectclass '%s'\n",
+                               attrname, 0, 0 );
+                       continue;
+               }
   
-  switch(c_mod->sm_op)
-  {
-   case LDAP_MOD_REPLACE:
-                       {
-                        SQLHSTMT asth;
-                        BACKSQL_ROW_NTS row;
+               switch( c_mod->sm_op ) {
+               case LDAP_MOD_REPLACE: {
+                       SQLHSTMT asth;
+                       BACKSQL_ROW_NTS row;
                         
-                        Debug(LDAP_DEBUG_TRACE,"backsql_modify(): replacing values for attribute '%s'\n",at->name,0,0);
-             if (at->add_proc==NULL)
-                        {
-                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add procedure is not defined for this attribute ('%s') - unable to perform replacements\n",at->name,0,0);
-                         break;
-                        }
+                       Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                               "replacing values for attribute '%s'\n",
+                               at->name, 0, 0 );
+
+                       if ( at->add_proc == NULL ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "add procedure is not defined "
+                                       "for attribute '%s' "
+                                       "- unable to perform replacements\n",
+                                       at->name, 0, 0 );
+                               break;
+                       }
+
+                       if ( at->delete_proc == NULL ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "delete procedure is not defined "
+                                       "for attribute '%s' "
+                                       "- adding only\n",
+                                       at->name, 0, 0 );
+                               goto add_only;
+                       }
+                       
 del_all:
+                       rc = backsql_Prepare( dbh, &asth, at->query, 0 );
+                       if ( rc != SQL_SUCCESS ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "error preparing query\n", 0, 0, 0 );
+                               backsql_PrintErrors( bi->db_env, dbh, 
+                                               asth, rc );
+                               break;
+                       }
+
+                       rc = backsql_BindParamID( asth, 1, &e_id.keyval );
+                       if ( rc != SQL_SUCCESS ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "error binding key value parameter\n",
+                                       0, 0, 0 );
+                               backsql_PrintErrors( bi->db_env, dbh, 
+                                               asth, rc );
+                               SQLFreeStmt( asth, SQL_DROP );
+                               break;
+                       }
+                       
+                       rc = SQLExecute( asth );
+                       if ( !BACKSQL_SUCCESS( rc ) ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "error executing attribute query\n",
+                                       0, 0, 0 );
+                               backsql_PrintErrors( bi->db_env, dbh, 
+                                               asth, rc );
+                               SQLFreeStmt( asth, SQL_DROP );
+                               break;
+                       }
+
+                       backsql_BindRowAsStrings( asth, &row );
+                       rc = SQLFetch( asth );
+                       for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( asth ) ) {
+                               for ( i = 0; i < row.ncols; i++ ) {
+                                       if ( at->expect_return & BACKSQL_DEL ) {
+                                               pno = 1;
+                                               SQLBindParameter(sth, 1,
+                                                       SQL_PARAM_OUTPUT,
+                                                       SQL_C_ULONG,
+                                                       SQL_INTEGER,
+                                                       0, 0, &prc, 0, 0 );
+                                       } else {
+                                               pno = 0;
+                                       }
+                                       po = ( at->param_order & BACKSQL_DEL ) > 0;
+                                       SQLBindParameter( sth, 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, pno + 2 - po,
+                                               SQL_PARAM_INPUT,
+                                               SQL_C_CHAR, SQL_CHAR,
+                                               0, 0, row.cols[ i ],
+                                               strlen( row.cols[ i ] ), 0 );
                         
-                        if ((rc=backsql_Prepare(dbh,&asth,at->query,0)) != SQL_SUCCESS)
-                        {
-                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error preparing query\n",0,0,0);
-                         backsql_PrintErrors(bi->db_env,dbh,asth,rc);
-                         break;
-                        }
-
-                        if (backsql_BindParamID(asth,1,&e_id.keyval) != SQL_SUCCESS)
-                        {
-                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error binding key value parameter\n",0,0,0);
-                         backsql_PrintErrors(bi->db_env,dbh,asth,rc);
-                         SQLFreeStmt(asth,SQL_DROP);
-                         break;
-                        }
-
-                        if ((rc=SQLExecute(asth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
-                        {
-                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error executing attribute query\n",0,0,0);
-                         backsql_PrintErrors(bi->db_env,dbh,asth,rc);
-                         SQLFreeStmt(asth,SQL_DROP);
-                         break;
-                        }
-
-                        backsql_BindRowAsStrings(asth,&row);
-                        while ((rc=SQLFetch(asth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
-                        {
-                         for (i=0;i<row.ncols;i++)
-                         {
-                          if (at->expect_return & BACKSQL_DEL)
-                          {
-                           pno=1;
-                           SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
-                          }
-                          else
-                           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);
-                            backsql_PrintErrors(bi->db_env,dbh,sth,rc);
+                                       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 );
+                                               backsql_PrintErrors( bi->db_env,
+                                                               dbh, sth, rc );
+                                       }
                                }
-                         }
-                        }
-                        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)
-                       {
-                        Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add procedure is not defined for this attribute ('%s')\n",at->name,0,0);
-                        break;
+                       backsql_FreeRow( &row );
+                       SQLFreeStmt( asth, SQL_DROP );
+               }
+                                      
+               /*
+                * PASSTHROUGH - to add new attributes -- do NOT add break
+                */
+               case LDAP_MOD_ADD:
+add_only:;
+                       if ( at->add_proc == NULL ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "add procedure is not defined "
+                                       "for attribute '%s'\n",
+                                       at->name, 0, 0 );
+                               break;
                        }
-                       if (c_mod->sm_bvalues==NULL)
-                       {
-                        Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to add for attribute '%s'\n",at->name,0,0);
-                        break;
+                       
+                       if ( c_mod->sm_bvalues == NULL ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "no values given to add "
+                                       "for attribute '%s'\n",
+                                       at->name, 0, 0 );
+                               break;
                        }
-                       Debug(LDAP_DEBUG_TRACE,"backsql_modify(): adding new values for attribute '%s'\n",at->name,0,0);
-                       for(i=0,at_val=c_mod->sm_bvalues[0];at_val!=NULL;i++,at_val=c_mod->sm_bvalues[i])
-                       {
-                        if (at->expect_return & BACKSQL_ADD)
-                        {
-                         pno=1;
-                         SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
-                        }
-                        else
-                         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);
-                         backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-                        }
+                       
+                       Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                               "adding new values for attribute '%s'\n",
+                               at->name, 0, 0 );
+                       for ( i = 0, at_val = &c_mod->sm_bvalues[ 0 ];
+                                       at_val->bv_val != NULL; 
+                                       i++, at_val = &c_mod->sm_bvalues[ i ] ) {
+                               if ( at->expect_return & BACKSQL_ADD ) {
+                                       pno = 1;
+                                       SQLBindParameter( sth, 1,
+                                               SQL_PARAM_OUTPUT,
+                                               SQL_C_ULONG, SQL_INTEGER,
+                                               0, 0, &prc, 0, 0);
+                               } else {
+                                       pno = 0;
+                               }
+                               po = ( at->param_order & BACKSQL_ADD ) > 0;
+                               SQLBindParameter( sth, 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, 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 );
+                                       backsql_PrintErrors( bi->db_env,
+                                                       dbh, sth, rc );
+                               }
                        }
                        break;
-  case LDAP_MOD_DELETE:
-                       if (at->delete_proc==NULL)
-                       {
-                        Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete procedure is not defined for this attribute ('%s')\n",at->name,0,0);
-                        break;
+                       
+               case LDAP_MOD_DELETE:
+                       if ( at->delete_proc == NULL ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "delete procedure is not defined "
+                                       "for attribute '%s'\n",
+                                       at->name, 0, 0 );
+                               break;
                        }
-                       if (c_mod->sm_bvalues==NULL)
-                       {
-                        Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to delete for attribute '%s' -- deleting all values\n",at->name,0,0);
-                        goto del_all;
+
+                       if ( c_mod->sm_bvalues == NULL ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                                       "no values given to delete "
+                                       "for attribute '%s' "
+                                       "-- deleting all values\n",
+                                       at->name, 0, 0 );
+                               goto del_all;
                        }
-            Debug(LDAP_DEBUG_TRACE,"backsql_modify(): deleting values for attribute '%s'\n",at->name,0,0);
-                       for(i=0,at_val=c_mod->sm_bvalues[0];at_val!=NULL;i++,at_val=c_mod->sm_bvalues[i])
-                       {
-                        if (at->expect_return & BACKSQL_DEL)
-                         {
-                          pno=1;
-                          SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
-                         }
-                        else
-                         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);
-                         backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-                        }
+
+                       Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
+                               "deleting values for attribute '%s'\n",
+                               at->name, 0, 0 );
+                       for( i = 0, at_val = &c_mod->sm_bvalues[ 0 ];
+                                       at_val->bv_val != NULL;
+                                       i++, at_val = &c_mod->sm_bvalues[ i ] ) {
+                               if ( at->expect_return & BACKSQL_DEL ) {
+                                       pno = 1;
+                                       SQLBindParameter( sth, 1,
+                                               SQL_PARAM_OUTPUT,
+                                               SQL_C_ULONG, SQL_INTEGER,
+                                               0, 0, &prc, 0, 0 );
+                               } else {
+                                       pno = 0;
+                               }
+                               po = ( at->param_order & BACKSQL_DEL ) > 0;
+                               SQLBindParameter( sth, 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, 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 );
+                                       backsql_PrintErrors( bi->db_env,
+                                                       dbh, sth, rc );
+                               }
                        }
                        break;
-  }
-  SQLFreeStmt(sth,SQL_RESET_PARAMS);
- }
-
- SQLFreeStmt(sth,SQL_DROP);
- send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_modify()\n",0,0,0);
- return 0;
+               }
+               
+               SQLFreeStmt( sth, SQL_RESET_PARAMS );
+       }
+
+       SQLFreeStmt( sth, SQL_DROP );
+       send_ldap_result( conn, op, LDAP_SUCCESS, "", NULL, NULL, NULL );
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
+
+       return 0;
 }
 
-int backsql_modrdn(BackendDB *be,Connection *conn,Operation *op,
-       const char *dn,const char *ndn,const char *newrdn,int deleteoldrdn,const char *newSuperior)
+int
+backsql_modrdn(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       struct berval   *dn,
+       struct berval   *ndn,
+       struct berval   *newrdn,
+       struct berval   *nnewrdn,
+       int             deleteoldrdn,
+       struct berval   *newSuperior,
+       struct berval   *nnewSuperior )
 {
- backsql_info *bi=(backsql_info*)be->be_private;
- SQLHDBC dbh;
- SQLHSTMT sth;
- RETCODE rc;
- backsql_oc_map_rec *oc=NULL;
- backsql_entryID e_id,pe_id,new_pid,*res;
- backsql_at_map_rec *at=NULL;
- char *p_dn=NULL,*new_pdn=NULL, *new_dn;
+       backsql_info            *bi = (backsql_info*)be->be_private;
+       SQLHDBC                 dbh;
+       SQLHSTMT                sth;
+       RETCODE                 rc;
+       backsql_entryID         e_id, pe_id, new_pid;
+       int                     res;
+       struct berval           p_dn, p_ndn,
+                               *new_pdn = NULL, *new_npdn = NULL,
+                               new_dn, new_ndn;
  
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_modrdn() renaming entry '%s', "
+                       "newrdn='%s', newSuperior='%s'\n",
+                       dn->bv_val, newrdn->bv_val, newSuperior->bv_val );
+       dbh = backsql_get_db_conn( be, conn );
+       if ( !dbh ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "could not get connection handle - exiting\n", 
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                       "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       res = backsql_dn2id( bi, &e_id, dbh, ndn );
+       if ( res != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "could not lookup entry id\n", 0, 0, 0 );
+               send_ldap_result( conn, op, res , "", NULL, NULL, NULL );
+               return 1;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): entry id is %ld\n",
+               e_id.id, 0, 0 );
+
+       dnParent( dn, &p_dn );
+       dnParent( ndn, &p_ndn );
+
+       if ( newSuperior ) {
+               new_pdn = newSuperior;
+               new_npdn = nnewSuperior;
+       } else {
+               new_pdn = &p_dn;
+               new_npdn = &p_ndn;
+       }
+
+       SQLAllocStmt( dbh, &sth );
+
+       if ( newSuperior && dn_match( &p_ndn, new_npdn ) ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "newSuperior is equal to old parent - aborting\n",
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", 
+                               NULL, NULL, NULL );
+               goto modrdn_return;
+       }
+
+       if ( newSuperior && dn_match( ndn, new_npdn ) ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "newSuperior is equal to entry being moved "
+                       "- aborting\n", 0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", 
+                               NULL, NULL, NULL );
+               goto modrdn_return;
+       }
+
+       build_new_dn( &new_dn, new_pdn, newrdn ); 
+       if ( dnNormalize2( NULL, &new_dn, &new_ndn ) != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "new dn is invalid ('%s') - aborting\n",
+                       new_dn.bv_val, 0, 0 );
+               send_ldap_result( conn, op, LDAP_INVALID_DN_SYNTAX, "", 
+                               NULL, NULL, NULL );
+               goto modrdn_return;
+       }
+       
+       Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): new entry dn is '%s'\n",
+                       new_dn.bv_val, 0, 0 );
+
+       res = backsql_dn2id( bi, &pe_id, dbh, &p_ndn );
+       if ( res != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "could not lookup old parent entry id\n", 0, 0, 0 );
+               send_ldap_result( conn, op, res, "", NULL, NULL, NULL );
+               goto modrdn_return;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+               "old parent entry id is %ld\n", pe_id.id, 0, 0 );
+
+       res = backsql_dn2id( bi, &new_pid, dbh, new_npdn );
+       if ( res != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+                       "could not lookup new parent entry id\n", 0, 0, 0 );
+               send_ldap_result( conn, op, res, "", NULL, NULL, NULL );
+               goto modrdn_return;
+       }
+       
+       Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+               "new parent entry id is %ld\n", new_pid.id, 0, 0 );
+
  
- Debug(LDAP_DEBUG_TRACE,"==>backsql_modrdn() renaming entry '%s', newrdn='%s', newSuperior='%s'\n",dn,newrdn,newSuperior);
- dbh=backsql_get_db_conn(be,conn);
- if (!dbh)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not get connection handle - exiting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
- if (res==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup entry id\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
-  return 1;
- }
- Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): entry id is %d\n",e_id.id,0,0);
-
- p_dn=dn_parent(be,ndn);
-
- if (newSuperior)
-  new_pdn=dn_validate(ch_strdup(newSuperior));
- else
-   new_pdn=p_dn;
-
- SQLAllocStmt(dbh, &sth);
-
- if (newSuperior && !strcasecmp(p_dn,new_pdn))
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): newSuperior is equal to old parent - aborting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
-  goto modrdn_return;
- }
-
- if (newSuperior && !strcasecmp(ndn,new_pdn))
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): newSuperior is equal to entry being moved - aborting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
-  goto modrdn_return;
- }
-
- build_new_dn( &new_dn, dn, new_pdn, newrdn ); 
- if (!dn_validate(new_dn))
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new dn is invalid ('%s') - aborting\n",new_dn,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
-  goto modrdn_return;
- }
- Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new entry dn is '%s'\n",new_dn,0,0);
-
- res=backsql_dn2id(bi,&pe_id,dbh,(char*)p_dn);
- if (res==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup old parent entry id\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
-  goto modrdn_return;
- }
- Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): old parent entry id is %d\n",pe_id.id,0,0);
-
- res=backsql_dn2id(bi,&new_pid,dbh,(char*)new_pdn);
- if (res==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup new parent entry id\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
-  goto modrdn_return;
- }
- Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new parent entry id is %d\n",new_pid.id,0,0);
-
- 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);
-  backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  goto modrdn_return;
- }
-
- SQLFreeStmt(sth,SQL_RESET_PARAMS);
-
- Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): executing insentry_query\n",0,0,0);
- backsql_BindParamStr(sth,1,new_dn,BACKSQL_MAX_DN_LEN);
- 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);
-  backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  goto modrdn_return;
- }
-
- /*should process deleteoldrdn here...*/
-
- send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
+       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 );
+               backsql_PrintErrors( bi->db_env, dbh, sth, rc );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               goto modrdn_return;
+       }
+
+       SQLFreeStmt( sth, SQL_RESET_PARAMS );
+
+       Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
+               "executing insentry_query\n", 0, 0, 0 );
+       backsql_BindParamStr( sth, 1, new_dn.bv_val, BACKSQL_MAX_DN_LEN );
+       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 );
+               backsql_PrintErrors( bi->db_env, dbh, sth, rc );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               goto modrdn_return;
+       }
+
+       /*
+        * FIXME: should process deleteoldrdn here...
+        */
+
+       send_ldap_result( conn, op, LDAP_SUCCESS, "", NULL, NULL, NULL );
+
 modrdn_return:
- SQLFreeStmt(sth,SQL_DROP);
- if (newSuperior && new_pdn)
-  ch_free(new_pdn);
- if (new_dn)
-  ch_free(new_dn);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_modrdn()\n",0,0,0);
- return 0;
+       SQLFreeStmt( sth, SQL_DROP );
+
+       if ( new_dn.bv_val ) {
+               ch_free( new_dn.bv_val );
+       }
+       
+       if ( new_ndn.bv_val ) {
+               ch_free( new_ndn.bv_val );
+       }
+       
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_modrdn()\n", 0, 0, 0 );
+       return 0;
 }
 
-int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
+int
+backsql_add(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       Entry           *e )
 {
- backsql_info *bi=(backsql_info*)be->be_private;
- SQLHDBC dbh;
- SQLHSTMT sth;
- unsigned long new_keyval;
- long i;
- RETCODE rc;
- backsql_oc_map_rec *oc=NULL;
- backsql_at_map_rec *at_rec=NULL;
- backsql_entryID parent_id,*res;
- 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)
- {
-  Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): invalid dn '%s' -- aborting\n",e->e_dn,0,0);
- }
- 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);
-   break;
-  }
- }
-
- if (oc==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_add(): cannot determine objectclass of entry -- aborting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- if (oc->create_proc == NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_add(): create procedure is not defined for this objectclass - aborting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
-
- dbh=backsql_get_db_conn(be,conn);
- if (!dbh)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not get connection handle - exiting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
-
- SQLAllocStmt(dbh, &sth);
- 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);
-  backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-  SQLFreeStmt(sth,SQL_DROP);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- SQLFreeStmt(sth,SQL_RESET_PARAMS);
- Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc returned keyval=%d\n",new_keyval,0,0);
-
- for(at=e->e_attrs;at!=NULL;at=at->a_next)
- {
-  at_rec=backsql_at_with_name(oc,at->a_desc->ad_cname.bv_val); 
-  
-  if (at_rec==NULL)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_add(): attribute provided is not registered in this objectclass ('%s')\n",at->a_desc->ad_cname.bv_val,0,0);
-   continue;
-  }
-  if (at_rec->add_proc==NULL)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_add(): add procedure is not defined for this attribute ('%s')\n",at->a_desc->ad_cname.bv_val,0,0);
-   continue;
-  }
+       backsql_info            *bi = (backsql_info*)be->be_private;
+       SQLHDBC                 dbh;
+       SQLHSTMT                sth;
+       unsigned long           new_keyval = 0;
+       long                    i;
+       RETCODE                 rc;
+       backsql_oc_map_rec      *oc = NULL;
+       backsql_at_map_rec      *at_rec = NULL;
+       backsql_entryID         parent_id;
+       int                     res;
+       Attribute               *at;
+       struct berval           *at_val;
+       struct berval           pdn;
+       /* first parameter no, parameter order */
+       SQLUSMALLINT            pno, po;
+       /* procedure return code */
+       int                     prc;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_add(): adding entry '%s'\n",
+                       e->e_dn, 0, 0 );
+
+       for ( at = e->e_attrs; at != NULL; at = at->a_next ) {
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "backsql_add(): scanning entry "
+                       "-- %s\n", at->a_type, 0, 0 );
+#endif
+               if ( !strcasecmp( at->a_desc->ad_cname.bv_val, "objectclass" ) ) {
+                       oc = backsql_oc_with_name( bi, at->a_vals[ 0 ].bv_val );
+                       break;
+               }
+       }
+
+       if ( oc == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                       "cannot determine objectclass of entry -- aborting\n",
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       if ( oc->create_proc == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                       "create procedure is not defined for this objectclass "
+                       "- aborting\n", 0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       dbh = backsql_get_db_conn( be, conn );
+       if ( !dbh ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                       "could not get connection handle - exiting\n", 
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+#ifndef BACKSQL_REALLOC_STMT
+       SQLAllocStmt( dbh, &sth );
+#else /* BACKSQL_REALLOC_STMT */
+       rc = backsql_Prepare( dbh, &sth, oc->create_proc, 0 );
+       if ( rc != SQL_SUCCESS ) {
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+#endif /* BACKSQL_REALLOC_STMT */
+
+       if ( oc->expect_return ) {
+               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 );
+#ifndef BACKSQL_REALLOC_STMT
+       rc = SQLExecDirect( sth, oc->create_proc, SQL_NTS );
+#else /* BACKSQL_REALLOC_STMT */
+       rc = SQLExecute( sth );
+#endif /* BACKSQL_REALLOC_STMT */
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                       "create_proc execution failed\n", 0, 0, 0 );
+               backsql_PrintErrors( bi->db_env, dbh, sth, rc);
+               SQLFreeStmt( sth, SQL_DROP );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       if ( !oc->expect_return ) {
+               /*
+                * FIXME: need query to know the id of the inserted entry
+                */
+       }
+
+#ifndef BACKSQL_REALLOC_STMT
+       SQLFreeStmt( sth, SQL_RESET_PARAMS );
+#else /* BACKSQL_REALLOC_STMT */
+       SQLFreeStmt( sth, SQL_DROP );
+#endif /* BACKSQL_REALLOC_STMT */
+       Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+               "create_proc returned keyval=%ld\n", new_keyval, 0, 0 );
+
+       for ( at = e->e_attrs; at != NULL; at = at->a_next ) {
+               SQLUSMALLINT    currpos;
+
+               if ( at->a_vals[ 0 ].bv_val == NULL ) {
+                       continue;
+               }
+
+               at_rec = backsql_at_with_name( oc, 
+                               at->a_desc->ad_cname.bv_val ); 
   
-  for(i=0,at_val=at->a_vals[0];at_val!=NULL;i++,at_val=at->a_vals[i])
-  {
-       if (at_rec->expect_return & BACKSQL_ADD)
-       {
-        pno=1;
-        SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
-       }
-       else
-        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);
-       backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-   }
-  }
- }
- SQLFreeStmt(sth,SQL_RESET_PARAMS); 
- pdn=dn_parent(be,e->e_dn);
- res=backsql_dn2id(bi,&parent_id,dbh,pdn);
- if (res==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not lookup parent entry for new record ('%s')\n",
-                                                                                               pdn,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- backsql_BindParamStr(sth,1,e->e_dn,BACKSQL_MAX_DN_LEN);
- 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;
- }
- SQLFreeStmt(sth,SQL_DROP);
- send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
- return 0;
+               if ( at_rec == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                               "attribute '%s' is not registered "
+                               "in objectclass '%s'\n",
+                               at->a_desc->ad_cname.bv_val, oc->name, 0 );
+                       continue;
+               }
+               
+               if ( at_rec->add_proc == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                               "add procedure is not defined "
+                               "for attribute '%s'\n",
+                               at->a_desc->ad_cname.bv_val, 0, 0 );
+                       continue;
+               }
+
+#ifdef BACKSQL_REALLOC_STMT
+               rc = backsql_Prepare( dbh, &sth, at_rec->add_proc, 0 );
+               if ( rc != SQL_SUCCESS ) {
+                       continue;
+               }
+#endif /* BACKSQL_REALLOC_STMT */
+
+               if ( at_rec->expect_return & BACKSQL_ADD ) {
+                       pno = 1;
+                       SQLBindParameter( sth, 1, SQL_PARAM_OUTPUT,
+                                       SQL_C_ULONG, SQL_INTEGER,
+                                       0, 0, &prc, 0, 0 );
+               } else {
+                       pno = 0;
+               }
+
+               po = ( at_rec->param_order & BACKSQL_ADD ) > 0;
+               currpos = pno + 1 + po;
+               SQLBindParameter( sth, currpos,
+                               SQL_PARAM_INPUT, SQL_C_ULONG,
+                               SQL_INTEGER, 0, 0, &new_keyval, 0, 0 );
+               currpos = pno + 2 - po;
+
+               for ( i = 0, at_val = &at->a_vals[ 0 ];
+                               at_val->bv_val != NULL;
+                               i++, at_val = &at->a_vals[ i ] ) {
+
+                       /*
+                        * check for syntax needed here 
+                        * maybe need binary bind?
+                        */
+
+                       backsql_BindParamStr( sth, currpos,
+                                       at_val->bv_val, at_val->bv_len + 1 );
+
+                       Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                               "executing '%s' with val='%s', id=%ld\n", 
+                               at_rec->add_proc, at_val->bv_val, new_keyval );
+#ifndef BACKSQL_REALLOC_STMT
+                       rc = SQLExecDirect( sth, at_rec->add_proc, SQL_NTS );
+#else /* BACKSQL_REALLOC_STMT */
+                       rc = SQLExecute( sth );
+#endif /* BACKSQL_REALLOC_STMT */
+                       if ( rc != SQL_SUCCESS ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                                       "add_proc execution failed\n", 
+                                       0, 0, 0 );
+                               backsql_PrintErrors( bi->db_env, dbh, sth, rc );
+                       }
+               }
+#ifndef BACKSQL_REALLOC_STMT
+               SQLFreeStmt( sth, SQL_RESET_PARAMS ); 
+#else /* BACKSQL_REALLOC_STMT */
+               SQLFreeStmt( sth, SQL_DROP );
+#endif /* BACKSQL_REALLOC_STMT */
+       }
+
+       dnParent( &e->e_name, &pdn );
+       res = backsql_dn2id( bi, &parent_id, dbh, &pdn );
+       if ( res != LDAP_SUCCESS ) {
+               /*
+                * NO SUCH OBJECT seems more appropriate
+                */
+               Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+                       "could not lookup parent entry for new record '%s'\n",
+                       pdn.bv_val, 0, 0 );
+               send_ldap_result( conn, op, res, "", NULL, NULL, NULL );
+               return 1;
+       }
+#ifdef BACKSQL_REALLOC_STMT
+       rc = backsql_Prepare( dbh, &sth, bi->insentry_query, 0 );
+       if ( rc != SQL_SUCCESS ) {
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+#endif /* BACKSQL_REALLOC_STMT */
+       backsql_BindParamStr( sth, 1, e->e_name.bv_val, BACKSQL_MAX_DN_LEN );
+       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 );
+
+       Debug( LDAP_DEBUG_TRACE, "backsql_add(): executing '%s' for dn '%s'\n",
+                       bi->insentry_query, e->e_name.bv_val, 0 );
+       Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, parent_id=%ld, "
+                       "keyval=%ld\n", oc->id, parent_id.id, new_keyval );
+#ifndef BACKSQL_REALLOC_STMT
+       rc = SQLExecDirect( sth, bi->insentry_query, SQL_NTS );
+#else /* BACKSQL_REALLOC_STMT */
+       rc = SQLExecute( sth );
+#endif /* BACKSQL_REALLOC_STMT */
+       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;
+       }
+       
+       SQLFreeStmt( sth, SQL_DROP );
+       send_ldap_result( conn, op, LDAP_SUCCESS, "",
+                       NULL, NULL, NULL );
+       return 0;
 }
 
-int backsql_delete(BackendDB *be,Connection *conn,Operation *op,
-       const char *dn,const char *ndn)
+int
+backsql_delete(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       struct berval   *dn,
+       struct berval   *ndn )
 {
- backsql_info *bi=(backsql_info*)be->be_private;
- SQLHDBC dbh;
- SQLHSTMT sth;
- 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);
- if (!dbh)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not get connection handle - exiting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
- if (res==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not lookup entry id\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
-  return 1;
- }
-
- oc=backsql_oc_with_id(bi,e_id.oc_id);
- if (oc==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_delete(): cannot determine objectclass of entry -- aborting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- if (oc->delete_proc == NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete procedure is not defined for this objectclass - aborting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
-
- SQLAllocStmt(dbh, &sth);
- if (oc->expect_return)
- {
-  pno=1;
-  SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&rc,0,0);
- }
- 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);
-  backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-  SQLFreeStmt(sth,SQL_DROP);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- 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);
-  backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-  SQLFreeStmt(sth,SQL_DROP);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
- SQLFreeStmt(sth,SQL_DROP);
-
- send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_delete()\n",0,0,0);
- return 0;
+       backsql_info            *bi = (backsql_info*)be->be_private;
+       SQLHDBC                 dbh;
+       SQLHSTMT                sth;
+       RETCODE                 rc;
+       backsql_oc_map_rec      *oc = NULL;
+       backsql_entryID         e_id;
+       int                     res;
+       /* first parameter no */
+       SQLUSMALLINT            pno;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_delete(): deleting entry '%s'\n",
+                       ndn->bv_val, 0, 0 );
+       dbh = backsql_get_db_conn( be, conn );
+       if ( !dbh ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+                       "could not get connection handle - exiting\n", 
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+       
+       res = backsql_dn2id( bi, &e_id, dbh, ndn );
+       if ( res != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+                       "could not lookup entry id\n", 0, 0, 0 );
+               send_ldap_result( conn, op, res, "", NULL, NULL, NULL );
+               return 1;
+       }
+
+       oc = backsql_oc_with_id( bi, e_id.oc_id );
+       if ( oc == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+                       "cannot determine objectclass of entry "
+                       "-- aborting\n", 0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       if ( oc->delete_proc == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+                       "delete procedure is not defined "
+                       "for this objectclass - aborting\n", 0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       SQLAllocStmt( dbh, &sth );
+       if ( oc->expect_return ) {
+               pno = 1;
+               SQLBindParameter( sth, 1, SQL_PARAM_OUTPUT, SQL_C_ULONG,
+                               SQL_INTEGER, 0, 0, &rc, 0, 0 );
+       } else {
+               pno = 0;
+       }
+
+       SQLBindParameter( sth, pno + 1, SQL_PARAM_INPUT, 
+                       SQL_C_ULONG, SQL_INTEGER, 0, 0, &e_id.keyval, 0, 0 );
+#if 0
+       SQLBindParameter( sth, 2, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER,
+                       0, 0, &retcode, 0, 0 );
+#endif
+
+       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 );
+               backsql_PrintErrors( bi->db_env, dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+       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 );
+               backsql_PrintErrors( bi->db_env, dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+       
+       SQLFreeStmt( sth, SQL_DROP );
+       send_ldap_result( conn, op, LDAP_SUCCESS, "", NULL, NULL, NULL );
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_delete()\n", 0, 0, 0 );
+       return 0;
 }
 
 #endif /* SLAPD_SQL */
+
index dc40a0e28d6791f275061f85e49a476a862e401a..62dcbe81509a666c9437b6193058876e23bb3af9 100644 (file)
 #include "back-sql.h"
 #include "sql-wrap.h"
 
-int backsql_dummy()
+int
+backsql_dummy( void )
 {
- return 0;
      return 0;
 }
 
-int    backsql_compare(BackendDB *bd,
-       Connection *conn, Operation *op,
-       const char *dn, const char *ndn,
+int
+backsql_compare(
+       BackendDB       *bd,
+       Connection      *conn,
+       Operation       *op,
+       struct berval   *dn,
+       struct berval   *ndn,
        AttributeAssertion *ava )
 {
- Debug(LDAP_DEBUG_TRACE,"==>backsql_compare() - not implemented\n",0,0,0);
- return 0;
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_compare() - not implemented\n",
+                       0, 0, 0 );
+       return 1;
 }
 
-int backsql_abandon( BackendDB *be,
-       Connection *conn, Operation *op, int msgid )
+int
+backsql_abandon(
+       BackendDB       *be,
+       Connection      *conn, 
+       Operation       *op, 
+       int             msgid )
 {
Debug(LDAP_DEBUG_TRACE,"==>backsql_abandon()\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_abandon()\n",0,0,0);
- return 0;
      Debug( LDAP_DEBUG_TRACE, "==>backsql_abandon()\n", 0, 0, 0 );
      Debug( LDAP_DEBUG_TRACE, "<==backsql_abandon()\n", 0, 0, 0 );
      return 0;
 }
 
 #endif /* SLAPD_SQL */
+
index 5f84573787ff0f4420b6bd72d88aa71eed9d7b26..2598849c481ec4c01562101b016b7532a4f1411a 100644 (file)
 #include "schema-map.h"
 #include "util.h"
 
-int backsql_dummy(void *,void *);
+int backsql_dummy( void *, void * );
 
-int backsql_cmp_oc_name(backsql_oc_map_rec *m1,backsql_oc_map_rec *m2)
+int
+backsql_cmp_oc_name( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
 {
return strcasecmp(m1->name,m2->name);
      return strcasecmp( m1->name, m2->name );
 }
 
-int backsql_cmp_oc_id(backsql_oc_map_rec *m1,backsql_oc_map_rec *m2)
+int
+backsql_cmp_oc_id( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
 {
- if (m1->id < m2->id)
-  return -1;
- if (m1->id > m2->id)
-  return 1;
- return 0;
+       if ( m1->id < m2->id ) {
+               return -1;
+       }
+       if ( m1->id > m2->id ) {
+               return 1;
+       }
+       return 0;
 }
 
-int backsql_cmp_attr(backsql_at_map_rec *m1,backsql_at_map_rec *m2)
+int
+backsql_cmp_attr( 
+       backsql_at_map_rec      *m1, 
+       backsql_at_map_rec      *m2 )
 {
return strcasecmp(m1->name,m2->name);
      return strcasecmp( m1->name, m2->name );
 }
 
-char* backsql_make_attr_query(backsql_oc_map_rec *oc_map,backsql_at_map_rec *at_map)
+char *
+backsql_make_attr_query( 
+       backsql_oc_map_rec      *oc_map,
+       backsql_at_map_rec      *at_map )
 {
- char *tmps;
- int tmpslen;
-
- tmps=NULL;tmpslen=0;
- tmps=backsql_strcat(tmps,&tmpslen,"SELECT ",at_map->sel_expr," AS ",at_map->name,
-                       " FROM ",at_map->from_tbls,
-                       " WHERE ",oc_map->keytbl,".",oc_map->keycol,"=?",NULL);
- if (at_map->join_where!=NULL && at_map->join_where[0]!='\0')
-  tmps=backsql_strcat(tmps,&tmpslen," AND ",at_map->join_where,NULL);
- at_map->query=ch_strdup(tmps);
- ch_free(tmps);
- return at_map->query;
-}
+       struct berval   tmps = { 0, NULL };
+       int             tmpslen = 0;
+
+       backsql_strcat( &tmps, &tmpslen, "SELECT ", at_map->sel_expr, 
+                       " AS ", at_map->name, " FROM ", at_map->from_tbls,
+                       " WHERE ", oc_map->keytbl,".", oc_map->keycol,
+                       "=?", NULL );
+       if ( at_map->join_where != NULL ) {
+               backsql_strcat( &tmps, &tmpslen, " AND ", 
+                               at_map->join_where, NULL );
+       }
 
+       at_map->query = tmps.bv_val;
+       
+       return at_map->query;
+}
 
-int backsql_add_sysmaps(backsql_oc_map_rec *oc_map)
+int
+backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
 {
- backsql_at_map_rec *at_map;
- int len;
- char s[30]; 
-
- sprintf(s,"%d",oc_map->id);
- at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
- at_map->name=ch_strdup("objectClass");
- at_map->sel_expr=ch_strdup("ldap_entry_objclasses.oc_name");
- at_map->from_tbls=ch_strdup("ldap_entry_objclasses,ldap_entries");
- len=strlen(at_map->from_tbls);
- backsql_merge_from_clause(&at_map->from_tbls,&len,oc_map->keytbl);
- at_map->join_where=NULL; len=0;
- at_map->join_where=backsql_strcat(at_map->join_where,&len,
-                       "ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=",
-                       oc_map->keytbl,".",oc_map->keycol," and ldap_entries.oc_map_id=",s,NULL);
- at_map->add_proc=NULL;
- at_map->delete_proc=NULL;
- at_map->param_order=0;
- at_map->expect_return=0;
- backsql_make_attr_query(oc_map,at_map);
- avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
-
- at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
- at_map->name=ch_strdup("ref");
- at_map->sel_expr=ch_strdup("ldap_referrals.url");
- at_map->from_tbls=ch_strdup("ldap_referrals,ldap_entries");
- len=strlen(at_map->from_tbls);
- backsql_merge_from_clause(&at_map->from_tbls,&len,oc_map->keytbl);
- at_map->join_where=NULL; len=0;
- at_map->join_where=backsql_strcat(at_map->join_where,&len,
-                       "ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=",
-                       oc_map->keytbl,".",oc_map->keycol," and ldap_entries.oc_map_id=",s,NULL);
- at_map->add_proc=NULL;
- at_map->delete_proc=NULL;
- at_map->param_order=0;
- at_map->expect_return=0;
- backsql_make_attr_query(oc_map,at_map);
- avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
-
- return 1;
+       backsql_at_map_rec      *at_map;
+       int                     len;
+       char                    s[ 30 ]; 
+       struct berval           bv;
+
+       snprintf( s, sizeof( s ), "%ld", oc_map->id );
+
+       at_map = (backsql_at_map_rec *)ch_calloc(1, 
+                       sizeof( backsql_at_map_rec ) );
+       at_map->name = ch_strdup( "objectClass" );
+       at_map->sel_expr = ch_strdup( "ldap_entry_objclasses.oc_name" );
+       at_map->from_tbls = ch_strdup( "ldap_entry_objclasses,ldap_entries" );
+       len = strlen( at_map->from_tbls );
+       backsql_merge_from_clause( &at_map->from_tbls, &len, oc_map->keytbl );
+       len = 0;
+       bv.bv_val = NULL;
+       bv.bv_len = 0;
+       backsql_strcat( &bv, &len,
+                       "ldap_entries.id=ldap_entry_objclasses.entry_id "
+                       "and ldap_entries.keyval=",
+                       oc_map->keytbl, ".", oc_map->keycol,
+                       " and ldap_entries.oc_map_id=", s, NULL );
+       at_map->join_where = bv.bv_val;
+       at_map->add_proc = NULL;
+       at_map->delete_proc = NULL;
+       at_map->param_order = 0;
+       at_map->expect_return = 0;
+       backsql_make_attr_query( oc_map, at_map );
+       avl_insert( &oc_map->attrs, at_map, 
+                       (AVL_CMP)backsql_cmp_attr, backsql_dummy );
+
+       at_map = (backsql_at_map_rec *)ch_calloc( 1, 
+                       sizeof( backsql_at_map_rec ) );
+       at_map->name = ch_strdup( "ref" );
+       at_map->sel_expr = ch_strdup( "ldap_referrals.url" );
+       at_map->from_tbls = ch_strdup( "ldap_referrals,ldap_entries" );
+       len = strlen( at_map->from_tbls );
+       backsql_merge_from_clause( &at_map->from_tbls, &len,oc_map->keytbl );
+
+       /* FIXME: no free? */
+       at_map->join_where = NULL;
+
+       len = 0;
+       bv.bv_val = NULL;
+       bv.bv_len = 0;
+       backsql_strcat( &bv, &len,
+                       "ldap_entries.id=ldap_referrals.entry_id "
+                       "and ldap_entries.keyval=",
+                       oc_map->keytbl, ".", oc_map->keycol,
+                       " and ldap_entries.oc_map_id=", s, NULL );
+       at_map->join_where = bv.bv_val;
+       at_map->add_proc = NULL;
+       at_map->delete_proc = NULL;
+       at_map->param_order = 0;
+       at_map->expect_return = 0;
+       backsql_make_attr_query( oc_map, at_map );
+       avl_insert( &oc_map->attrs, at_map, 
+                       (AVL_CMP)backsql_cmp_attr, backsql_dummy );
+
+       return 1;
 }
 
-int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh)
+int
+backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
 {
- SQLHSTMT oc_sth,at_sth;
- RETCODE rc;
- BACKSQL_ROW_NTS oc_row,at_row;
- unsigned long oc_id;
- backsql_oc_map_rec *oc_map;
- backsql_at_map_rec *at_map;
- char *tmps;
- int tmpslen;
-
- Debug(LDAP_DEBUG_TRACE,"==>load_schema_map()\n",0,0,0);
-
- /* TimesTen : See if the ldap_entries.dn_ru field exists in the schema. */
-
- rc = backsql_Prepare(dbh, &oc_sth, backsql_check_dn_ru_query, 0);
- if (rc == SQL_SUCCESS) {
-   si->has_ldapinfo_dn_ru = 1;  /* Yes, the field exists */
-   Debug(LDAP_DEBUG_TRACE, "ldapinfo.dn_ru field exists in the schema\n", 0, 0,0);
- }
- else {
-   si->has_ldapinfo_dn_ru = 0;  /* No such field exists */
- }
-
- SQLFreeStmt(oc_sth, SQL_DROP);
-
- rc=backsql_Prepare(dbh,&oc_sth,si->oc_query,0);
- if (rc != SQL_SUCCESS)
-  {
-   Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error preparing oc_query: '%s'\n",si->oc_query,0,0);
-   backsql_PrintErrors(si->db_env,dbh,oc_sth,rc);
-   return -1;
-  }
-  Debug(LDAP_DEBUG_TRACE, "load_schema_map(): at_query '%s'\n", si->at_query,0,0);
-
- rc=backsql_Prepare(dbh,&at_sth,si->at_query,0);
- if (rc != SQL_SUCCESS)
-  {
-   Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error preparing at_query: '%s'\n",si->at_query,0,0);
-   backsql_PrintErrors(si->db_env,dbh,at_sth,rc);
-   return -1;
-  }
- if ((rc=backsql_BindParamID(at_sth,1,&oc_id)) != SQL_SUCCESS)
-  {
-   Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error binding param for at_query: \n",0,0,0);
-   backsql_PrintErrors(si->db_env,dbh,at_sth,rc);
-   return -1;
-  }
- if ((rc=SQLExecute(oc_sth)) != SQL_SUCCESS)
-  {
-   Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing oc_query: \n",0,0,0);
-   backsql_PrintErrors(si->db_env,dbh,oc_sth,rc);
-   return -1;
-  }
- backsql_BindRowAsStrings(oc_sth,&oc_row);
- while ((rc=SQLFetch(oc_sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
-  {
-   oc_map=(backsql_oc_map_rec*)ch_calloc(1,sizeof(backsql_oc_map_rec));
-   oc_map->id=atoi(oc_row.cols[0]);
-   oc_map->name=ch_strdup(oc_row.cols[1]);
-   oc_map->keytbl=ch_strdup(oc_row.cols[2]);
-   oc_map->keycol=ch_strdup(oc_row.cols[3]);
-   oc_map->create_proc=(oc_row.is_null[4]<0)?NULL:ch_strdup(oc_row.cols[4]);
-   oc_map->delete_proc=(oc_row.is_null[5]<0)?NULL:ch_strdup(oc_row.cols[5]);
-   oc_map->expect_return=atoi(oc_row.cols[6]);
-
-   oc_map->attrs=NULL;
-   avl_insert(&si->oc_by_name,oc_map,(AVL_CMP)backsql_cmp_oc_name,backsql_dummy);
-   avl_insert(&si->oc_by_id,oc_map,(AVL_CMP)backsql_cmp_oc_id,backsql_dummy);
-   oc_id=oc_map->id;
-   Debug(LDAP_DEBUG_TRACE,"load_schema_map(): objectclass '%s': keytbl='%s' keycol='%s' ",
-          oc_map->name,oc_map->keytbl,oc_map->keycol);
-   if (oc_map->delete_proc) {
-     Debug(LDAP_DEBUG_TRACE,"delete_proc='%s'\n", oc_map->delete_proc, 0, 0);
-   }
-   if (oc_map->create_proc) {
-     Debug(LDAP_DEBUG_TRACE,"create_proc='%s'\n", oc_map->create_proc, 0, 0);
-   }
-   Debug(LDAP_DEBUG_TRACE,"expect_return=%d; attributes:\n",
-       oc_map->expect_return, 0, 0);
-
-   Debug(LDAP_DEBUG_TRACE,"load_schema_map(): autoadding 'objectClass' and 'ref' mappings\n",0,0,0);
-   backsql_add_sysmaps(oc_map);
-   if ((rc=SQLExecute(at_sth)) != SQL_SUCCESS)
-    {
-     Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing at_query: \n",0,0,0);
-     backsql_PrintErrors(SQL_NULL_HENV,dbh,at_sth,rc);
-     return -1;
-    }
-   backsql_BindRowAsStrings(at_sth,&at_row);
-   while ((rc=SQLFetch(at_sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
-    {
-     Debug(LDAP_DEBUG_TRACE,"********'%s'\n",at_row.cols[0],0,0);
-     Debug(LDAP_DEBUG_TRACE,"name='%s',sel_expr='%s' from='%s' ",at_row.cols[0],
-             at_row.cols[1],at_row.cols[2]);
-        Debug(LDAP_DEBUG_TRACE,"join_where='%s',add_proc='%s' ",at_row.cols[3],
-             at_row.cols[4],0);
-        Debug(LDAP_DEBUG_TRACE,"delete_proc='%s'\n",at_row.cols[5],0,0);
-        Debug(LDAP_DEBUG_TRACE,"sel_expr_u='%s'\n", at_row.cols[8],0,0); /* TimesTen*/
-     at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
-     at_map->name=ch_strdup(at_row.cols[0]);
-     at_map->sel_expr=ch_strdup(at_row.cols[1]);
-        at_map->sel_expr_u = (at_row.is_null[8]<0)?NULL:ch_strdup(at_row.cols[8
-]);
-        tmps=NULL;tmpslen=0;
-        backsql_merge_from_clause(&tmps,&tmpslen,at_row.cols[2]);
-     at_map->from_tbls=ch_strdup(tmps);
-        ch_free(tmps);
-        at_map->join_where=ch_strdup((at_row.is_null[3]<0)?"":at_row.cols[3]);
-        at_map->add_proc=(at_row.is_null[4]<0)?NULL:ch_strdup(at_row.cols[4]);
-        at_map->delete_proc=(at_row.is_null[5]<0)?NULL:ch_strdup(at_row.cols[5]);
-        at_map->param_order=atoi(at_row.cols[6]);
-        at_map->expect_return=atoi(at_row.cols[7]);
-        backsql_make_attr_query(oc_map,at_map);
-        Debug(LDAP_DEBUG_TRACE,"load_schema_map(): preconstructed query '%s'\n",at_map->query,0,0);
-     avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
-    }
-   backsql_FreeRow(&at_row);
-   SQLFreeStmt(at_sth,SQL_CLOSE);
-  }
- backsql_FreeRow(&oc_row);
- SQLFreeStmt(at_sth,SQL_DROP);
- SQLFreeStmt(oc_sth,SQL_DROP);
- si->schema_loaded=1;
- Debug(LDAP_DEBUG_TRACE,"<==load_schema_map()\n",0,0,0);
- return 1;
+       SQLHSTMT                oc_sth, at_sth;
+       RETCODE                 rc;
+       BACKSQL_ROW_NTS         oc_row, at_row;
+       unsigned long           oc_id;
+       backsql_oc_map_rec      *oc_map;
+       backsql_at_map_rec      *at_map;
+       char                    *tmps;
+       int                     tmpslen;
+
+       Debug( LDAP_DEBUG_TRACE, "==>load_schema_map()\n", 0, 0, 0 );
+
+       /* 
+        * TimesTen : See if the ldap_entries.dn_ru field exists in the schema
+        */
+       if ( si->has_ldapinfo_dn_ru == -1 ) {
+               rc = backsql_Prepare( dbh, &oc_sth, 
+                               backsql_check_dn_ru_query, 0 );
+               if ( rc == SQL_SUCCESS ) {
+                       si->has_ldapinfo_dn_ru = 1;  /* Yes, the field exists */
+                       Debug( LDAP_DEBUG_TRACE, "ldapinfo.dn_ru field exists "
+                               "in the schema\n", 0, 0, 0 );
+               } else {
+                       si->has_ldapinfo_dn_ru = 0;  /* No such field exists */
+               }
+
+               SQLFreeStmt( oc_sth, SQL_DROP );
+       }
+
+
+       rc = backsql_Prepare( dbh, &oc_sth, si->oc_query, 0 );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
+                       "error preparing oc_query: '%s'\n", 
+                       si->oc_query, 0, 0 );
+               backsql_PrintErrors( si->db_env, dbh, oc_sth, rc );
+               return -1;
+       }
+       Debug( LDAP_DEBUG_TRACE, "load_schema_map(): at_query '%s'\n", 
+                       si->at_query, 0, 0 );
+
+       rc = backsql_Prepare( dbh, &at_sth, si->at_query, 0 );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
+                       "error preparing at_query: '%s'\n", 
+                       si->at_query, 0, 0 );
+               backsql_PrintErrors( si->db_env, dbh, at_sth, rc );
+               return -1;
+       }
+
+       rc = backsql_BindParamID( at_sth, 1, &oc_id );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
+                       "error binding param for at_query: \n", 0, 0, 0 );
+               backsql_PrintErrors( si->db_env, dbh, at_sth, rc );
+               return -1;
+       }
+
+       rc = SQLExecute( oc_sth );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
+                       "error executing oc_query: \n", 0, 0, 0 );
+               backsql_PrintErrors( si->db_env, dbh, oc_sth, rc );
+               return -1;
+       }
+
+       backsql_BindRowAsStrings( oc_sth, &oc_row );
+       rc = SQLFetch( oc_sth );
+       for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( oc_sth ) ) {
+               oc_map = (backsql_oc_map_rec *)ch_calloc( 1,
+                               sizeof( backsql_oc_map_rec ) );
+               oc_map->id = atoi( oc_row.cols[ 0 ] );
+               oc_map->name = ch_strdup( oc_row.cols[ 1 ] );
+               oc_map->keytbl = ch_strdup( oc_row.cols[ 2 ] );
+               oc_map->keycol = ch_strdup( oc_row.cols[ 3 ] );
+               oc_map->create_proc = ( oc_row.is_null[ 4 ] < 0 ) ? NULL 
+                       : ch_strdup( oc_row.cols[ 4 ] );
+               oc_map->delete_proc = ( oc_row.is_null[ 5 ] < 0 ) ? NULL 
+                       : ch_strdup( oc_row.cols[ 5 ] );
+               oc_map->expect_return = atoi( oc_row.cols[ 6 ] );
+
+               /*
+                * FIXME: first attempt to check for offending
+                * instructions in {create|delete}_proc
+                */
+
+               oc_map->attrs = NULL;
+               avl_insert( &si->oc_by_name, oc_map,
+                               (AVL_CMP)backsql_cmp_oc_name, backsql_dummy );
+               avl_insert( &si->oc_by_id, oc_map,
+                               (AVL_CMP)backsql_cmp_oc_id, backsql_dummy );
+               oc_id = oc_map->id;
+               Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
+                       "objectClass '%s': keytbl='%s' keycol='%s'\n",
+                       oc_map->name, oc_map->keytbl, oc_map->keycol );
+               if ( oc_map->delete_proc ) {
+                       Debug( LDAP_DEBUG_TRACE, "delete_proc='%s'\n", 
+                               oc_map->delete_proc, 0, 0 );
+               }
+               if ( oc_map->create_proc ) {
+                       Debug( LDAP_DEBUG_TRACE, "create_proc='%s'\n",
+                               oc_map->create_proc, 0, 0 );
+               }
+               Debug( LDAP_DEBUG_TRACE, "expect_return=%d; attributes:\n",
+                       oc_map->expect_return, 0, 0 );
+
+               Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
+                       "autoadding 'objectClass' and 'ref' mappings\n",
+                       0, 0, 0 );
+               backsql_add_sysmaps( oc_map );
+               rc = SQLExecute( at_sth );
+               if ( rc != SQL_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
+                               "error executing at_query: \n", 0, 0, 0 );
+                       backsql_PrintErrors( SQL_NULL_HENV, dbh, at_sth, rc );
+                       return -1;
+               }
+
+               backsql_BindRowAsStrings( at_sth, &at_row );
+               rc = SQLFetch( at_sth );
+               for ( ; BACKSQL_SUCCESS(rc); rc = SQLFetch( at_sth ) ) {
+                       Debug( LDAP_DEBUG_TRACE, "********'%s'\n",
+                               at_row.cols[ 0 ], 0, 0 );
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "name='%s',sel_expr='%s' from='%s'",
+                               at_row.cols[ 0 ], at_row.cols[ 1 ],
+                               at_row.cols[ 2 ] );
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "join_where='%s',add_proc='%s'",
+                               at_row.cols[ 3 ], at_row.cols[ 4 ], 0 );
+                       Debug( LDAP_DEBUG_TRACE, "delete_proc='%s'\n",
+                                       at_row.cols[ 5 ], 0, 0 );
+                       /* TimesTen */
+                       Debug( LDAP_DEBUG_TRACE, "sel_expr_u='%s'\n",
+                                       at_row.cols[ 8 ], 0, 0 );
+                       at_map = (backsql_at_map_rec *)ch_calloc( 1,
+                                       sizeof( backsql_at_map_rec ) );
+                       at_map->name = ch_strdup( at_row.cols[ 0 ] );
+                       at_map->sel_expr = ch_strdup( at_row.cols[ 1 ] );
+                       at_map->sel_expr_u = ( at_row.is_null[ 8 ] < 0 ) ? NULL
+                               : ch_strdup( at_row.cols[ 8 ] );
+                       tmps = NULL;
+                       tmpslen = 0;
+                       backsql_merge_from_clause( &tmps, &tmpslen,
+                                       at_row.cols[ 2 ] );
+                       at_map->from_tbls = tmps;
+                       at_map->join_where = ( at_row.is_null[ 3 ] < 0 ) ? NULL 
+                               : ch_strdup( at_row.cols[ 3 ] );
+                       at_map->add_proc = ( at_row.is_null[ 4 ] < 0 ) ? NULL
+                               : ch_strdup( at_row.cols[4] );
+                       at_map->delete_proc = ( at_row.is_null[ 5 ] < 0 ) ? NULL
+                               : ch_strdup( at_row.cols[ 5 ] );
+                       at_map->param_order = atoi( at_row.cols[ 6 ] );
+                       at_map->expect_return = atoi( at_row.cols[ 7 ] );
+                       backsql_make_attr_query( oc_map, at_map );
+                       Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
+                               "preconstructed query '%s'\n",
+                               at_map->query, 0, 0 );
+                       avl_insert( &oc_map->attrs, at_map, 
+                                       (AVL_CMP)backsql_cmp_attr,
+                                       backsql_dummy );
+               }
+               backsql_FreeRow( &at_row );
+               SQLFreeStmt( at_sth, SQL_CLOSE );
+       }
+       backsql_FreeRow( &oc_row );
+       SQLFreeStmt( at_sth, SQL_DROP );
+       SQLFreeStmt( oc_sth, SQL_DROP );
+       si->schema_loaded = 1;
+       Debug( LDAP_DEBUG_TRACE, "<==load_schema_map()\n", 0, 0, 0 );
+       return 1;
 }
 
-backsql_oc_map_rec* backsql_oc_with_name(backsql_info *si,char* objclass)
+backsql_oc_map_rec *
+backsql_oc_with_name( backsql_info *si, char *objclass )
 {
- backsql_oc_map_rec tmp,*res;
+       backsql_oc_map_rec      tmp, *res;
+
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "==>oc_with_name(): "
+               "searching for objectclass with name='%s'\n",
+               objclass, 0, 0 );
+#endif
+       
+       tmp.name = objclass;
+       res = (backsql_oc_map_rec *)avl_find( si->oc_by_name, &tmp,
+                       (AVL_CMP)backsql_cmp_oc_name );
+#if 0
+       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 );
+       }
+#endif
  
-/* 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;
+       return res;
 }
 
-backsql_oc_map_rec* backsql_oc_with_id(backsql_info *si,unsigned long id)
+backsql_oc_map_rec *
+backsql_oc_with_id( backsql_info *si, unsigned long id )
 {
backsql_oc_map_rec tmp,*res;
      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;
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "==>oc_with_id(): "
+               "searching for objectclass with id='%d'\n", id, 0, 0 );
+#endif
+
+       tmp.id = id;
+       res = (backsql_oc_map_rec *)avl_find( si->oc_by_id, &tmp,
+                       (AVL_CMP)backsql_cmp_oc_id );
+
+#if 0
+       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 );
+       }
+#endif
+       
+       return res;
 }
 
-backsql_at_map_rec* backsql_at_with_name(backsql_oc_map_rec* objclass,char* attr)
+backsql_at_map_rec *
+backsql_at_with_name( backsql_oc_map_rec* objclass, char *attr )
 {
backsql_at_map_rec tmp,*res;
      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;
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "==>at_with_name(): "
+               "searching for attribute '%s' for objectclass '%s'\n",
+               attr, objclass->name, 0 );
+#endif
+       tmp.name = attr;
+       res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
+                       (AVL_CMP)backsql_cmp_attr );
+
+#if 0
+       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 );
+       }
+#endif
+
+       return res;
 }
 
-int backsql_free_attr(backsql_at_map_rec *at)
+int
+backsql_free_attr( backsql_at_map_rec *at )
 {
- Debug(LDAP_DEBUG_TRACE,"==>free_attr(): '%s'\n",at->name,0,0);
- ch_free(at->name);
- ch_free(at->sel_expr);
- if (at->from_tbls!=NULL)
-  ch_free(at->from_tbls);
- if (at->join_where!=NULL)
-  ch_free(at->join_where);
- if (at->add_proc!=NULL)
-  ch_free(at->add_proc);
- if (at->delete_proc!=NULL)
-  ch_free(at->delete_proc);
- if (at->query)
-  ch_free(at->query);
- ch_free(at);
- if (at->sel_expr_u)
-   ch_free(at->sel_expr_u); /* TimesTen */
- Debug(LDAP_DEBUG_TRACE,"<==free_attr()\n",0,0,0);
- return 1;
+       Debug( LDAP_DEBUG_TRACE, "==>free_attr(): '%s'\n", at->name, 0, 0 );
+       ch_free( at->name );
+       ch_free( at->sel_expr );
+       if ( at->from_tbls != NULL ) {
+               ch_free( at->from_tbls );
+       }
+       if ( at->join_where != NULL ) {
+               ch_free( at->join_where );
+       }
+       if ( at->add_proc != NULL ) {
+               ch_free( at->add_proc );
+       }
+       if ( at->delete_proc != NULL ) {
+               ch_free( at->delete_proc );
+       }
+       if ( at->query ) {
+               ch_free( at->query );
+       }
+       ch_free( at );
+
+       /* TimesTen */
+       if ( at->sel_expr_u ) {
+               ch_free( at->sel_expr_u );
+       }
+       
+       Debug( LDAP_DEBUG_TRACE, "<==free_attr()\n", 0, 0, 0 );
+
+       return 1;
 }
 
-int backsql_free_oc(backsql_oc_map_rec *oc)
+int
+backsql_free_oc( backsql_oc_map_rec *oc )
 {
- Debug(LDAP_DEBUG_TRACE,"==>free_oc(): '%s'\n",oc->name,0,0);
- avl_free(oc->attrs,(AVL_FREE)backsql_free_attr);
- ch_free(oc->name);
- ch_free(oc->keytbl);
- ch_free(oc->keycol);
- if (oc->create_proc!=NULL)
-  ch_free(oc->create_proc);
- if (oc->delete_proc!=NULL)
-  ch_free(oc->delete_proc);
- ch_free(oc);
- Debug(LDAP_DEBUG_TRACE,"<==free_oc()\n",0,0,0);
- return 1;
+       Debug( LDAP_DEBUG_TRACE, "==>free_oc(): '%s'\n", oc->name, 0, 0 );
+       avl_free( oc->attrs, (AVL_FREE)backsql_free_attr );
+       ch_free( oc->name );
+       ch_free( oc->keytbl );
+       ch_free( oc->keycol );
+       if ( oc->create_proc != NULL ) {
+               ch_free( oc->create_proc );
+       }
+       if ( oc->delete_proc != NULL ) {
+               ch_free( oc->delete_proc );
+       }
+       ch_free( oc );
+
+       Debug( LDAP_DEBUG_TRACE, "<==free_oc()\n", 0, 0, 0 );
+       return 1;
 }
 
-int backsql_destroy_schema_map(backsql_info *si)
+int
+backsql_destroy_schema_map( backsql_info *si )
 {
Debug(LDAP_DEBUG_TRACE,"==>destroy_schema_map()\n",0,0,0);
avl_free(si->oc_by_id,(AVL_FREE)backsql_free_oc);
avl_free(si->oc_by_name,(AVL_FREE)backsql_dummy);
Debug(LDAP_DEBUG_TRACE,"<==destroy_schema_map()\n",0,0,0);
- return 0;
      Debug( LDAP_DEBUG_TRACE, "==>destroy_schema_map()\n", 0, 0, 0 );
      avl_free( si->oc_by_id, (AVL_FREE)backsql_free_oc );
      avl_free( si->oc_by_name, (AVL_FREE)backsql_dummy );
      Debug( LDAP_DEBUG_TRACE, "<==destroy_schema_map()\n", 0, 0, 0 );
      return 0;
 }
 
 #endif /* SLAPD_SQL */
+
index f2fc02bbfa8dcf511008c6ca114613e58687db3f..7747f59b9442a692277179a4d93b72bffb11937d 100644 (file)
  */
 
 
-typedef struct
-{
- 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;
-
-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)*/
- char *sel_expr_u; /* TimesTen */
-}backsql_at_map_rec;
-
-/*defines to support bitmasks above*/
+typedef struct {
+       char            *name;
+       char            *keytbl;
+       char            *keycol;
+       /* expected to return keyval of newly created entry */
+       char            *create_proc;
+       /* supposed to expect keyval as parameter and delete 
+        * all the attributes as well */
+       char            *delete_proc;
+       /* flags whether delete_proc is a function (whether back-sql 
+        * should bind first parameter as output for return code) */
+       int             expect_return;
+       unsigned long   id;
+       Avlnode         *attrs;
+} backsql_oc_map_rec;
+
+typedef struct {
+       /* literal name of corresponding LDAP attribute type */
+       char            *name;
+       char            *from_tbls;
+       char            *join_where;
+       char            *sel_expr;
+       /* supposed to expect 2 binded values: entry keyval 
+        * and attr. value to add, like "add_name(?,?,?)" */
+       char            *add_proc;
+       /* supposed to expect 2 binded values: entry keyval 
+        * and attr. value to delete */
+       char            *delete_proc;
+       /* for optimization purposes attribute load query 
+        * is preconstructed from parts on schemamap load time */
+       char            *query;
+       /* following flags are bitmasks (first bit used for add_proc, 
+        * second - for modify, third - for delete_proc) */
+       /* order of parameters for procedures above; 
+        * 1 means "data then keyval", 0 means "keyval then data" */
+       int             param_order;
+       /* flags whether one or more of procedures is a function 
+        * (whether back-sql should bind first parameter as output 
+        * for return code) */
+       int             expect_return;
+       /* TimesTen */
+       char            *sel_expr_u;
+} backsql_at_map_rec;
+
+/* defines to support bitmasks above */
 #define BACKSQL_ADD    1
 #define BACKSQL_DEL    2
 
-int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh);
-backsql_oc_map_rec* backsql_oc_with_name(backsql_info *si,char* objclass);
-backsql_oc_map_rec* backsql_oc_with_id(backsql_info *si,unsigned long id);
-backsql_at_map_rec* backsql_at_with_name(backsql_oc_map_rec* objclass,char* attr);
-int backsql_destroy_schema_map(backsql_info *si);
+int backsql_load_schema_map( backsql_info *si, SQLHDBC dbh );
+backsql_oc_map_rec *backsql_oc_with_name( backsql_info *si, char *objclass );
+backsql_oc_map_rec *backsql_oc_with_id( backsql_info *si, unsigned long id );
+backsql_at_map_rec *backsql_at_with_name( backsql_oc_map_rec *objclass,
+               char *attr );
+int backsql_destroy_schema_map( backsql_info *si );
 
-#endif
+#endif /* __BACKSQL_SCHEMA_MAP_H__ */
 
index 2dca484832374d894fbdfefd902a7cf738688a0f..dff51d5d28f03530a1597b03cbebefcb688496d0 100644 (file)
 
 #include <stdio.h>
 #include <sys/types.h>
-#include <string.h>
+#include "ac/string.h"
 #include "slap.h"
+#include "lber_pvt.h"
+#include "ldap_pvt.h"
 #include "back-sql.h"
 #include "sql-wrap.h"
 #include "schema-map.h"
 #include "entry-id.h"
 #include "util.h"
 
-int backsql_attrlist_add(backsql_srch_info *bsi,char *at_name)
+static struct berval AllUser = BER_BVC( LDAP_ALL_USER_ATTRIBUTES );
+static struct berval AllOper = BER_BVC( LDAP_ALL_OPERATIONAL_ATTRIBUTES );
+#if 0
+static struct berval NoAttrs = BER_BVC( LDAP_NO_ATTRS );
+#endif
+
+static int
+backsql_attrlist_add( backsql_srch_info *bsi, struct berval *at_name )
 {
- char **p=bsi->attrs;
- int n_attrs=0;
-
- if (bsi->attrs==NULL)
-  return 1;
-
- while(*p)
- {
-  Debug(LDAP_DEBUG_TRACE,"==>backsql_attrlist_add(): attribute '%s' is in list\n",*p,0,0);
-  if (!strcasecmp(*p,at_name))
-   return 1;
-  n_attrs++;
-  p++;
- }
- Debug(LDAP_DEBUG_TRACE,"==>backsql_attrlist_add(): adding '%s' to list\n",at_name,0,0);
- bsi->attrs=(char**)ch_realloc(bsi->attrs,(n_attrs+2)*sizeof(char*));
- bsi->attrs[n_attrs]=ch_strdup(at_name);
- bsi->attrs[n_attrs+1]=NULL;
- return 1;
+       int     n_attrs = 0;
+       char    **tmp;
+
+       if ( bsi->attrs == NULL ) {
+               return 1;
+       }
+
+       for ( ; bsi->attrs[ n_attrs ]; n_attrs++ ) {
+               Debug( LDAP_DEBUG_TRACE, "==>backsql_attrlist_add(): "
+                       "attribute '%s' is in list\n", 
+                       bsi->attrs[ n_attrs ], 0, 0 );
+               /*
+                * We can live with strcmp because the attribute 
+                * list has been normalized before calling be_search
+                */
+               if ( !strcmp( bsi->attrs[ n_attrs ], at_name->bv_val ) ) {
+                       return 1;
+               }
+       }
+       
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_attrlist_add(): "
+               "adding '%s' to list\n", at_name->bv_val, 0, 0 );
+       tmp = (char **)ch_realloc( bsi->attrs, (n_attrs + 2)*sizeof( char * ) );
+       if ( tmp == NULL ) {
+               return -1;
+       }
+       bsi->attrs = tmp;
+       bsi->attrs[ n_attrs ] = ch_strdup( at_name->bv_val );
+       bsi->attrs[ n_attrs + 1 ] = NULL;
+       return 1;
 }
 
-void backsql_init_search(backsql_srch_info *bsi,backsql_info *bi,char *nbase,int scope,
-                                                int slimit,int tlimit,time_t stoptime,Filter *filter,
-                                                SQLHDBC dbh,BackendDB *be,Connection *conn,Operation *op,AttributeName *attrs)
+void
+backsql_init_search(
+       backsql_srch_info       *bsi, 
+       backsql_info            *bi,
+       struct berval           *nbase, 
+       int                     scope, 
+       int                     slimit,
+       int                     tlimit,
+       time_t                  stoptime, 
+       Filter                  *filter, 
+       SQLHDBC                 dbh,
+       BackendDB               *be, 
+       Connection              *conn, 
+       Operation               *op,
+       AttributeName           *attrs )
 {
- AttributeName *p;
- bsi->base_dn=nbase;
- bsi->scope=scope;
- bsi->slimit=slimit;
- bsi->tlimit=tlimit;
- bsi->filter=filter;
- bsi->dbh=dbh;
- bsi->be=be;
- bsi->conn=conn;
- bsi->op=op;
- if (attrs!=NULL)
- {
-  bsi->attrs=(char**)ch_calloc(1,sizeof(char*));
-  bsi->attrs[0]=NULL;
-  for(p=attrs;p->an_name.bv_val;p++)
-   backsql_attrlist_add(bsi,p->an_name.bv_val);
- }
- else
-  bsi->attrs=NULL;
- bsi->abandon=0;
- bsi->id_list=NULL;
- bsi->stoptime=stoptime;
- bsi->bi=bi;
- bsi->sel=NULL; bsi->from=NULL; bsi->join_where=NULL; bsi->flt_where=NULL;
- bsi->sel_len=0; bsi->from_len=0; bsi->jwhere_len=0; bsi->fwhere_len=0;
+       AttributeName           *p;
+       
+       bsi->base_dn = nbase;
+       bsi->scope = scope;
+       bsi->slimit = slimit;
+       bsi->tlimit = tlimit;
+       bsi->filter = filter;
+       bsi->dbh = dbh;
+       bsi->be = be;
+       bsi->conn = conn;
+       bsi->op = op;
+
+       /*
+        * FIXME: need to discover how to deal with 1.1 (NoAttrs)
+        */
+       
+       /*
+        * handle "*"
+        */
+       if ( attrs == NULL || an_find( attrs, &AllUser ) ) {
+               bsi->attrs = NULL;
+
+       } else {
+               bsi->attrs = (char **)ch_calloc( 1, sizeof( char * ) );
+               bsi->attrs[ 0 ] = NULL;
+               
+               for ( p = attrs; p->an_name.bv_val; p++ ) {
+                       /*
+                        * ignore "+"
+                        */
+                       if ( strcmp( p->an_name.bv_val, AllOper.bv_val ) == 0 ) {
+                               continue;
+                       }
+                       backsql_attrlist_add( bsi, &p->an_name );
+               }
+       }
+
+       bsi->abandon = 0;
+       bsi->id_list = NULL;
+       bsi->n_candidates = 0;
+       bsi->stoptime = stoptime;
+       bsi->bi = bi;
+       bsi->sel.bv_val = NULL;
+       bsi->sel.bv_len = 0;
+       bsi->sel_len = 0;
+       bsi->from.bv_val = NULL;
+       bsi->from.bv_len = 0;
+       bsi->from_len = 0;
+       bsi->join_where.bv_val = NULL;
+       bsi->join_where.bv_len = 0;
+       bsi->jwhere_len = 0;
+       bsi->flt_where.bv_val = NULL;
+       bsi->flt_where.bv_len = 0;
+       bsi->fwhere_len = 0;
+
+       bsi->status = LDAP_SUCCESS;
 }
 
-int backsql_process_filter_list(backsql_srch_info *bsi,Filter *f,int op)
+int
+backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
 {
- char *sub_clause=NULL;
- int len=0,res;
-
- if (!f)
-  return 0;
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",NULL);
- while(1)
- {
-  res=backsql_process_filter(bsi,f);
-  if (res < 0)
-    return -1;    /* TimesTen : If the query has no answers,
-                   don't bother to run the query. */
+       int             res;
+
+       if ( !f ) {
+               return 0;
+       }
+       
+       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, "(", NULL );
+
+       while ( 1 ) {
+               res = backsql_process_filter( bsi, f );
+               if ( res < 0 ) {
+                       /*
+                        * TimesTen : If the query has no answers,
+                        * don't bother to run the query.
+                        */
+                       return -1;
+               }
  
-  f=f->f_next;
-  if (f==NULL)
-   break;
-
-  switch (op)
-  {
-   case LDAP_FILTER_AND:
-                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," AND ",NULL);
+               f = f->f_next;
+               if ( f == NULL ) {
+                       break;
+               }
+
+               switch ( op ) {
+               case LDAP_FILTER_AND:
+                       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                                       " AND ", NULL );
                        break;
-   case LDAP_FILTER_OR:
-                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," OR ",NULL);
+
+               case LDAP_FILTER_OR:
+                       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                                       " OR ", NULL );
                        break;
-  }
- }
+               }
      }
 
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,")",NULL);
- return 1;
+       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, /* ( */ ")", NULL );
+
      return 1;
 }
 
-int backsql_process_sub_filter(backsql_srch_info *bsi,Filter *f)
+int
+backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
 {
- int i;
- backsql_at_map_rec *at=backsql_at_with_name(bsi->oc,f->f_sub_desc->ad_cname.bv_val);
+       int                     i;
+       backsql_at_map_rec      *at;
+
+       if ( !f ) {
+               return 0;
+       }
+
+       at = backsql_at_with_name( bsi->oc, f->f_sub_desc->ad_cname.bv_val );
+
+       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, "(" /* ) */ , NULL );
+
+       /* TimesTen */
+       Debug( LDAP_DEBUG_TRACE, "expr: '%s' '%s'\n", at->sel_expr,
+               at->sel_expr_u ? at->sel_expr_u : "<NULL>", 0 );
+       if ( bsi->bi->upper_func ) {
+               /*
+                * If a pre-upper-cased version of the column exists, use it
+                */
+               if ( at->sel_expr_u ) {
+                       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
+                                       at->sel_expr_u, " LIKE '", NULL);
+               } else {
+                       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                                       bsi->bi->upper_func,
+                                       "(", at->sel_expr, ")", 
+                                       " LIKE '", NULL );
+               }
+       } else {
+               backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
+                               at->sel_expr, " LIKE '", NULL );
+       }
  
- if (!f)
-  return 0;
-
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",NULL);
- /* TimesTen*/
- Debug(LDAP_DEBUG_TRACE,"expr: '%s' '%s'\n",at->sel_expr,
-       at->sel_expr_u?at->sel_expr_u:"<NULL>",0);
- if (bsi->bi->upper_func)
- {
-   /* If a pre-upper-cased version of the column exists, use it. */
-   if (at->sel_expr_u) {
-     bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,
-                   at->sel_expr_u," LIKE '",NULL);
-   }
-   else {
-      bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,
-            bsi->bi->upper_func,"(",at->sel_expr,")",
-                " LIKE '",NULL);
-   }
- }
- else
- {
-  bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,at->sel_expr,
-                               " LIKE '",NULL);
- }
- if (f->f_sub_initial!=NULL)
- {
-  if (bsi->bi->upper_func)
-   {
-    bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,ldap_pvt_str2upper(f->f_sub_initial->bv_val),NULL);
-   }
-   else
-    bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_initial->bv_val,NULL);
- }
-
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"%",NULL);
-
- 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);
-   }
-   else
-    bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_any[i]->bv_val,"%",NULL);    
-  }
-
- if (f->f_sub_final!=NULL)
-  if (bsi->bi->upper_func)
-   {
-    bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,ldap_pvt_str2upper(f->f_sub_final->bv_val),NULL);
-   }
-   else
-    bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_final->bv_val,NULL);
-
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"')",NULL);
+       if ( f->f_sub_initial.bv_val != NULL ) {
+               size_t  start;
+
+               start = bsi->flt_where.bv_len;
+               backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
+                               f->f_sub_initial.bv_val, NULL );
+               if ( bsi->bi->upper_func ) {
+                       ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
+               }
+       }
+
+       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, "%", NULL );
+
+       if ( f->f_sub_any != NULL ) {
+               for ( i = 0; f->f_sub_any[ i ].bv_val != NULL; i++ ) {
+                       size_t  start;
+
+#if 0
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "==>backsql_process_sub_filter(): "
+                               "sub_any='%s'\n", f->f_sub_any[ i ].bv_val,
+                               0, 0 );
+#endif
+
+                       start = bsi->flt_where.bv_len;
+                       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                                       f->f_sub_any[ i ].bv_val, "%", NULL );
+                       if ( bsi->bi->upper_func) {
+                               /*
+                                * Note: toupper('%') = '%'
+                                */
+                               ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
+                       }
+               }
+
+               if ( f->f_sub_final.bv_val != NULL ) {
+                       size_t  start;
+
+                       start = bsi->flt_where.bv_len;
+                       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
+                                       f->f_sub_final.bv_val, NULL);
+                       if ( bsi->bi->upper_func ) {
+                               ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
+                       }
+               }
+       }
+
+       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, /* ( */ "')", NULL );
  
- return 1;
      return 1;
 }
 
-int backsql_process_filter(backsql_srch_info *bsi,Filter *f)
+int
+backsql_process_filter( backsql_srch_info *bsi, Filter *f )
 {
- backsql_at_map_rec *at;
- backsql_at_map_rec oc_attr={"objectClass","","",NULL,NULL,NULL,NULL};
- char *at_name=NULL;
- int done=0,len=0;
- int rc=0; /* TimesTen */
-
- Debug(LDAP_DEBUG_TRACE,"==>backsql_process_filter()\n",0,0,0);
- if (f==NULL || f->f_choice==SLAPD_FILTER_COMPUTED)
-  {
-   return 0;
-  }
-  
- switch(f->f_choice)
- {
-  case LDAP_FILTER_OR:
-                       rc = backsql_process_filter_list(bsi,f->f_or,LDAP_FILTER_OR);
-                       done=1;
-                       break;
-  case LDAP_FILTER_AND:
-                       rc = backsql_process_filter_list(bsi,f->f_and,LDAP_FILTER_AND);
-                       done=1;
-                       break;
-  case LDAP_FILTER_NOT:
-                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"NOT (",NULL);
-                       rc = backsql_process_filter(bsi,f->f_not);
-                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,")",NULL);
-                       done=1;
-                       break;
-  case LDAP_FILTER_PRESENT:
-                       at_name=f->f_desc->ad_cname.bv_val;
-                       break;
-  default:
-                        at_name=f->f_av_desc->ad_cname.bv_val;
-                       break;
- }
+       backsql_at_map_rec      *at;
+       backsql_at_map_rec      oc_attr 
+               = { "objectClass", "", "", NULL, NULL, NULL, NULL };
+       AttributeDescription    *ad = NULL;
+       int                     done = 0, len = 0;
+       /* TimesTen */
+       int                     rc = 0;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter()\n", 0, 0, 0 );
+       if ( f == NULL || f->f_choice == SLAPD_FILTER_COMPUTED ) {
+               return 0;
+       }
+
+       switch( f->f_choice ) {
+       case LDAP_FILTER_OR:
+               rc = backsql_process_filter_list( bsi, f->f_or, 
+                               LDAP_FILTER_OR );
+               done = 1;
+               break;
+               
+       case LDAP_FILTER_AND:
+               rc = backsql_process_filter_list( bsi, f->f_and,
+                               LDAP_FILTER_AND);
+               done = 1;
+               break;
+
+       case LDAP_FILTER_NOT:
+               backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                               "NOT (", NULL );
+               rc = backsql_process_filter( bsi, f->f_not );
+               backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, ")", NULL );
+               done = 1;
+               break;
 
- if (rc == -1)
-   goto impossible;     /* TimesTen : Don't run the query */
+       case LDAP_FILTER_PRESENT:
+               ad = f->f_desc;
+               break;
+               
+       default:
+               ad = f->f_av_desc;
+               break;
+       }
+
+       if ( rc == -1 ) {
+               /* TimesTen : Don't run the query */
+               goto impossible;
+       }
  
- if (done)
-  goto done;
-
- if (strcasecmp(at_name,"objectclass"))
-  at=backsql_at_with_name(bsi->oc,at_name);
- else
- {
-  at=&oc_attr;
-  at->sel_expr=backsql_strcat(at->sel_expr,&len,"'",bsi->oc->name,"'",NULL);
- }
- if (at==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_process_filter(): attribute '%s' is not defined for objectclass '%s'\n",
-                      at_name,bsi->oc->name,0);
-  bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," 1=0 ",NULL);
-  goto impossible;
- }
-                       
- 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 ( done ) {
+               goto done;
+       }
+
+       if ( strcasecmp( ad->ad_cname.bv_val, "objectclass" ) ) {
+               at = backsql_at_with_name( bsi->oc, ad->ad_cname.bv_val );
+
+       } else {
+               struct berval   bv;
+               
+               at = &oc_attr;
+
+               /*
+                * FIXME: use berval for at->sel_expr ?
+                */
+               bv.bv_val = at->sel_expr;
+               bv.bv_len = at->sel_expr ? strlen( at->sel_expr ) : 0;
+               backsql_strcat( &bv, &len, "'", bsi->oc->name, "'", NULL );
+               at->sel_expr = bv.bv_val;
+       }
+       if ( at == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
+                       "attribute '%s' is not defined for objectclass '%s'\n",
+                       ad->ad_cname.bv_val, bsi->oc->name, 0 );
+               backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                               " 1=0 ", NULL );
+               goto impossible;
+       }
+
+       backsql_merge_from_clause( &bsi->from.bv_val, &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, &ad->ad_cname );
+
+       if ( at->join_where != NULL && strstr( bsi->join_where.bv_val, at->join_where ) == NULL ) {
+               backsql_strcat( &bsi->join_where, &bsi->jwhere_len, 
+                               " AND ", at->join_where, NULL );
+       }
+
+#if 0  
+       if ( at != &oc_attr ) {
+               backsql_strcat( &bsi->sel, &bsi->sel_len,
+                               ",", at->sel_expr, " AS ", at->name, NULL );
+       }
+#endif
+
+       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 ) {
+                       size_t  start;
+
+                       if ( at->sel_expr_u ) {
+                               backsql_strcat( &bsi->flt_where,
+                                               &bsi->fwhere_len, "(",
+                                               at->sel_expr_u, "='", NULL );
+                       } else {
+                               backsql_strcat( &bsi->flt_where,
+                                               &bsi->fwhere_len, "(",
+                                               bsi->bi->upper_func, "(",
+                                               at->sel_expr, ")='", NULL );
+                       }
 
- 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);
+                       start = bsi->flt_where.bv_len;
 
- /*if (at!=&oc_attr)
-  bsi->sel=backsql_strcat(bsi->sel,&bsi->sel_len,",",at->sel_expr," AS ",at->name,NULL);
- */
+                       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                                       f->f_av_value.bv_val, "')", 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) {
-                               if (at->sel_expr_u)
-                                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",
-                      at->sel_expr_u,"='",
-                      ldap_pvt_str2upper(f->f_av_value->bv_val),"')",
-                      NULL);
-                       else
-                                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",
-                                       bsi->bi->upper_func,"(",at->sel_expr,")='",
-                                       ldap_pvt_str2upper(f->f_av_value->bv_val),"')",NULL);
-                       }
-                       else
-                        bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,"='",
-                                                       f->f_av_value->bv_val,"')",NULL);
+                       ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
 
-                       break;
-  case LDAP_FILTER_GE:
-                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,">=",
-                                                       f->f_av_value->bv_val,")",NULL);
+               } else {
+                       backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                                       "(", at->sel_expr, "='",
+                                       f->f_av_value.bv_val, "')", NULL );
+               }
+               break;
 
-                       break;
-  case LDAP_FILTER_LE:
-                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,"<=",
-                                                       f->f_av_value->bv_val,")",NULL);
-                       break;
-  case LDAP_FILTER_PRESENT:
-                       bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"NOT (",at->sel_expr,
-                                               " IS NULL)",NULL);
-                       break;
-  case LDAP_FILTER_SUBSTRINGS:
-                       backsql_process_sub_filter(bsi,f);
-                       break;
- }
+       case LDAP_FILTER_GE:
+               backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                               "(", at->sel_expr, ">=", 
+                               f->f_av_value.bv_val, ")", NULL );
+               break;
+               
+       case LDAP_FILTER_LE:
+               backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                               "(", at->sel_expr, "<=", 
+                               f->f_av_value.bv_val, ")", NULL );
+               break;
+
+       case LDAP_FILTER_PRESENT:
+               backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, 
+                               "NOT (", at->sel_expr, " IS NULL)", NULL );
+               break;
+
+       case LDAP_FILTER_SUBSTRINGS:
+               backsql_process_sub_filter( bsi, f );
+               break;
+       }
 
 done:
- if (oc_attr.sel_expr!=NULL)
-  free(oc_attr.sel_expr);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_process_filter()\n",0,0,0);
- return 1;
+       if ( oc_attr.sel_expr != NULL ) {
+               free( oc_attr.sel_expr );
+       }
+       
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter()\n", 0, 0, 0 );
+       return 1;
 
 impossible:
- if (oc_attr.sel_expr!=NULL)
-  free(oc_attr.sel_expr);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_process_filter() returns -1\n",0,0,0);
- return -1;
-
+       if ( oc_attr.sel_expr != NULL ) {
+               free( oc_attr.sel_expr );
+       }
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter() returns -1\n",
+                       0, 0, 0 );
+       return -1;
 }
 
-char* backsql_srch_query(backsql_srch_info *bsi)
+static int
+backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
 {
- char *query=NULL;
- int q_len=0;
- int rc;
-
- Debug(LDAP_DEBUG_TRACE,"==>backsql_srch_query()\n",0,0,0);
- bsi->sel=NULL;
- bsi->from=NULL;
- bsi->join_where=NULL;
- bsi->flt_where=NULL;
- bsi->sel_len=bsi->from_len=bsi->jwhere_len=bsi->fwhere_len=0;
-
- bsi->sel=backsql_strcat(bsi->sel,&bsi->sel_len,
-                               "SELECT DISTINCT ldap_entries.id,",bsi->oc->keytbl,".",bsi->oc->keycol,
-                               ", '",bsi->oc->name,"' AS objectClass",
-                               ", ldap_entries.dn AS dn",
-                               NULL);
- bsi->from=backsql_strcat(bsi->from,&bsi->from_len," FROM ldap_entries,",bsi->oc->keytbl,NULL);
- bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len," WHERE ",
-        bsi->oc->keytbl,".",bsi->oc->keycol,"=ldap_entries.keyval AND ",
-        "ldap_entries.oc_map_id=? AND ",NULL);
-
- switch(bsi->scope)
- {
-  case LDAP_SCOPE_BASE:
-        if (bsi->bi->upper_func)
-                {
-                 bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
-                        bsi->bi->upper_func,"(","ldap_entries.dn)=(?)",NULL);
-                }
-               else
-                {
-                 bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
-                               "ldap_entries.dn=?",NULL);
-                }
+       backsql_info    *bi = (backsql_info *)bsi->be->be_private;
+       int             q_len = 0;
+       int             rc;
+
+       assert( query );
+       query->bv_val = NULL;
+       query->bv_len = 0;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_srch_query()\n", 0, 0, 0 );
+       bsi->sel.bv_val = NULL;
+       bsi->sel.bv_len = 0;
+       bsi->sel_len = 0;
+       bsi->from.bv_val = NULL;
+       bsi->from.bv_len = 0;
+       bsi->from_len = 0;
+       bsi->join_where.bv_val = NULL;
+       bsi->join_where.bv_len = 0;
+       bsi->jwhere_len = 0;
+       bsi->flt_where.bv_val = NULL;
+       bsi->flt_where.bv_len = 0;
+       bsi->fwhere_len = 0;
+#if 0
+       backsql_strcat( &bsi->sel, &bsi->sel_len,
+                       "SELECT DISTINCT ldap_entries.id,", 
+                       bsi->oc->keytbl, ".", bsi->oc->keycol,
+                       ",'", bsi->oc->name, "' AS objectClass",
+                       ",ldap_entries.dn AS dn", NULL );
+#endif
+       backsql_strcat( &bsi->sel, &bsi->sel_len,
+                       "SELECT DISTINCT ldap_entries.id,", 
+                       bsi->oc->keytbl, ".", bsi->oc->keycol, ",", NULL );
+       if ( bi->strcast_func ) {
+               backsql_strcat( &bsi->sel, &bsi->sel_len,
+                               bi->strcast_func, 
+                               "('", bsi->oc->name, "')", NULL );
+       } else {
+               backsql_strcat( &bsi->sel, &bsi->sel_len,
+                               "'", bsi->oc->name, "'", NULL );
+       }
+       backsql_strcat( &bsi->sel, &bsi->sel_len,
+                       " AS objectClass,ldap_entries.dn AS dn", NULL );
+
+       backsql_strcat( &bsi->from, &bsi->from_len,
+                       " FROM ldap_entries,", bsi->oc->keytbl, NULL );
+       backsql_strcat( &bsi->join_where, &bsi->jwhere_len,
+                       " WHERE ", bsi->oc->keytbl, ".", bsi->oc->keycol,
+                       "=ldap_entries.keyval AND ",
+                       "ldap_entries.oc_map_id=? AND ", NULL );
+
+       switch ( bsi->scope ) {
+       case LDAP_SCOPE_BASE:
+               if ( bsi->bi->upper_func ) {
+                       backsql_strcat( &bsi->join_where, &bsi->jwhere_len, 
+                                       bsi->bi->upper_func,
+                                       "(","ldap_entries.dn)=",
+                                       bsi->bi->upper_func, "(?)", NULL );
+               } else {
+                       backsql_strcat( &bsi->join_where, &bsi->jwhere_len, 
+                                       "ldap_entries.dn=?", NULL );
+               }
                break;
-  case LDAP_SCOPE_ONELEVEL:
-               bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
-                               "ldap_entries.parent=?",NULL);
+               
+       case LDAP_SCOPE_ONELEVEL:
+               backsql_strcat( &bsi->join_where, &bsi->jwhere_len, 
+                               "ldap_entries.parent=?", NULL );
                break;
-  case LDAP_SCOPE_SUBTREE:
-               bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
-                               bsi->bi->subtree_cond,NULL);
+
+       case LDAP_SCOPE_SUBTREE:
+               backsql_strcat( &bsi->join_where, &bsi->jwhere_len,
+                               bsi->bi->subtree_cond, NULL );
                break;
- }
-
- rc = backsql_process_filter(bsi, bsi->filter);
- if (rc>0) {
-  query=backsql_strcat(query,&q_len,bsi->sel,bsi->from,bsi->join_where," AND ",bsi->flt_where,NULL);
- }
- else if (rc < 0) {
-    /* Indicates that there's no possible way the filter matches
-      anything.  No need to issue the query. */
-
-   Debug(LDAP_DEBUG_TRACE,"<==backsql_srch_query() returns NULL\n",0,0,0);
-   free(query);
-   query = NULL;
- }
+
+       default:
+               assert( 0 );
+       }
+
+       rc = backsql_process_filter( bsi, bsi->filter );
+       if ( rc > 0 ) {
+               backsql_strcat( query, &q_len,
+                               bsi->sel.bv_val, bsi->from.bv_val, 
+                               bsi->join_where.bv_val,
+                               " AND ", bsi->flt_where.bv_val, NULL );
+
+       } else if ( rc < 0 ) {
+               /* 
+                * Indicates that there's no possible way the filter matches
+                * anything.  No need to issue the query
+                */
+               Debug( LDAP_DEBUG_TRACE,
+                       "<==backsql_srch_query() returns NULL\n", 0, 0, 0 );
+               free( query->bv_val );
+               query->bv_val = NULL;
+       }
  
- free(bsi->sel);
- free(bsi->from);
- free(bsi->join_where);
- free(bsi->flt_where);
- bsi->sel_len=bsi->from_len=bsi->jwhere_len=bsi->fwhere_len=0;
- Debug(LDAP_DEBUG_TRACE,"<==backsql_srch_query()\n",0,0,0);
- return query;
+       free( bsi->sel.bv_val );
+       bsi->sel.bv_len = 0;
+       bsi->sel_len = 0;
+       free( bsi->from.bv_val );
+       bsi->from.bv_len = 0;
+       bsi->from_len = 0;
+       free( bsi->join_where.bv_val );
+       bsi->join_where.bv_len = 0;
+       bsi->jwhere_len = 0;
+       free( bsi->flt_where.bv_val );
+       bsi->flt_where.bv_len = 0;
+       bsi->fwhere_len = 0;
+       
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_srch_query()\n", 0, 0, 0 );
+       
+       return ( query->bv_val == NULL ? 1 : 0 );
 }
 
-int backsql_oc_get_candidates(backsql_oc_map_rec *oc,backsql_srch_info *bsi)
+int
+backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
 {
- char *query=NULL;
- SQLHSTMT sth;
- RETCODE rc;
- backsql_entryID base_id,*res,*c_id;
- /*Entry *e;*/
- BACKSQL_ROW_NTS row;
- int i;
- int j;
- char temp_base_dn[BACKSQL_MAX_DN_LEN+1]; /* TimesTen*/
+       struct berval           query;
+       SQLHSTMT                sth;
+       RETCODE                 rc;
+       backsql_entryID         base_id, *c_id;
+       int                     res;
+#if 0
+       Entry                   *e;
+#endif
+       BACKSQL_ROW_NTS         row;
+       int                     i;
+       int                     j;
+       /* TimesTen */
+       char                    temp_base_dn[ BACKSQL_MAX_DN_LEN + 1 ];
  
- Debug(LDAP_DEBUG_TRACE,"==>backsql_oc_get_candidates(): oc='%s'\n",oc->name,0,0);
- bsi->oc=oc;
- query=backsql_srch_query(bsi);
- if (query==NULL)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): could not construct query for objectclass\n",0,0,0);
-  return 1;
- }
-
- Debug(LDAP_DEBUG_TRACE,"Constructed query: %s\n",query,0,0);
-
- if ((rc=backsql_Prepare(bsi->dbh,&sth,query,0)) != SQL_SUCCESS)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error preparing query\n",0,0,0);
-   backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
-   free(query);
-   return 1;
-  }
- free(query);
-
- if (backsql_BindParamID(sth,1,&bsi->oc->id) != SQL_SUCCESS)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error binding objectclass id parameter\n",0,0,0);
-  return 1;
- }
- switch(bsi->scope)
- {
-  case LDAP_SCOPE_BASE:
-               if ((rc=backsql_BindParamStr(sth,2,bsi->base_dn,BACKSQL_MAX_DN_LEN)) != SQL_SUCCESS)
-               {
-         Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error binding base_dn parameter\n",0,0,0);
-                backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
-         return 1;
+       Debug(  LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc='%s'\n",
+                       oc->name, 0, 0 );
+       bsi->oc = oc;
+       if ( backsql_srch_query( bsi, &query ) ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                       "could not construct query for objectclass\n",
+                       0, 0, 0 );
+               return 1;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "Constructed query: %s\n", 
+                       query.bv_val, 0, 0 );
+
+       rc = backsql_Prepare( bsi->dbh, &sth, query.bv_val, 0 );
+       free( query.bv_val );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                       "error preparing query\n", 0, 0, 0 );
+               backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
+               return 1;
+       }
+
+       if ( backsql_BindParamID( sth, 1, &bsi->oc->id ) != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                       "error binding objectclass id parameter\n", 0, 0, 0 );
+               return 1;
+       }
+
+       switch ( bsi->scope ) {
+       case LDAP_SCOPE_BASE:
+               rc = backsql_BindParamStr( sth, 2, bsi->base_dn->bv_val,
+                               BACKSQL_MAX_DN_LEN );
+               if ( rc != SQL_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                               "error binding base_dn parameter\n", 0, 0, 0 );
+                       backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, 
+                                       sth, rc );
+                       return 1;
                }
                break;
 
-  case LDAP_SCOPE_SUBTREE:
-    /* Sets the parameters for the SQL built earlier */
-    /* NOTE that all the databases could actually use the TimesTen version,
-       which would be cleaner and would also eliminate the need for the
-       subtree_cond line in the configuration file.  For now, I'm leaving
-       it the way it is, so non-TimesTen databases use the original code.
-       But at some point this should get cleaned up. */
-     /* If "dn" is being used, do a suffix search.
-     If "dn_ru" is being used, do a prefix search. */
-
-    if (bsi->bi->has_ldapinfo_dn_ru) {
-       temp_base_dn[0] = '\0';
-       for ((i=0, j=strlen(bsi->base_dn)-1); j >= 0; (i++, j--)) {
-         *(temp_base_dn+i) = toupper(*(bsi->base_dn+j));
-       }
-       *(temp_base_dn+i) = '%';
-       *(temp_base_dn+i+1) = '\0';
-    }
-    else {
-        strcpy(temp_base_dn, "%");
-        for (i = 0; *(bsi->base_dn+i); i++) {
-          *(temp_base_dn+i+1) = toupper(*(bsi->base_dn+i));
-        }
-        *(temp_base_dn+i+1) = '\0';
-    }
-    Debug(LDAP_DEBUG_TRACE, "dn '%s'\n", temp_base_dn, 0, 0);
-
-    if ((rc=backsql_BindParamStr(sth,2,temp_base_dn,BACKSQL_MAX_DN_LEN)) !=
-SQL_SUCCESS)
-    {
-         Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error binding base_dn parameter (2)\n",0,0,0);
-         backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
-         return 1;
-    }
-       break;
-
-  case LDAP_SCOPE_ONELEVEL:
-               res=backsql_dn2id(bsi->bi,&base_id,bsi->dbh,bsi->base_dn);
-               if (res==NULL)
-               {
-                Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): could not retrieve base_dn id - no such entry\n",0,0,0);
-                bsi->status=LDAP_NO_SUCH_OBJECT;
-                return 0;
+       case LDAP_SCOPE_SUBTREE:
+               /* 
+                * Sets the parameters for the SQL built earlier
+                * NOTE that all the databases could actually use 
+                * the TimesTen version, which would be cleaner 
+                * and would also eliminate the need for the
+                * subtree_cond line in the configuration file.  
+                * For now, I'm leaving it the way it is, 
+                * so non-TimesTen databases use the original code.
+                * But at some point this should get cleaned up.
+                *
+                * If "dn" is being used, do a suffix search.
+                * If "dn_ru" is being used, do a prefix search.
+                */
+               if ( bsi->bi->has_ldapinfo_dn_ru ) {
+                       temp_base_dn[ 0 ] = '\0';
+                       for ( i = 0, j = bsi->base_dn->bv_len - 1;
+                                       j >= 0; i++, j--) {
+                               temp_base_dn[ i ] = bsi->base_dn->bv_val[ j ];
+                       }
+                       temp_base_dn[ i ] = '%';
+                       temp_base_dn[ i + 1 ] = '\0';
+                       ldap_pvt_str2upper( temp_base_dn );
+
+               } else {
+                       temp_base_dn[ 0 ] = '%';
+                       AC_MEMCPY( &temp_base_dn[ 1 ], bsi->base_dn->bv_val,
+                               bsi->base_dn->bv_len + 1 );
+                       ldap_pvt_str2upper( &temp_base_dn[ 1 ] );
+               }
+
+               Debug( LDAP_DEBUG_TRACE, "dn '%s'\n", temp_base_dn, 0, 0 );
+
+               rc = backsql_BindParamStr( sth, 2, temp_base_dn, 
+                               BACKSQL_MAX_DN_LEN );
+               if ( rc != SQL_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                               "error binding base_dn parameter (2)\n",
+                               0, 0, 0 );
+                       backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, 
+                                       sth, rc );
+                       return 1;
                }
-               if (backsql_BindParamID(sth,2,&base_id.id) != SQL_SUCCESS)
-               {
-                Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error binding base id parameter\n",0,0,0);
-                free(base_id.dn);
-                return 1;
-               }               
-               free(base_id.dn);
                break;
- }
- if ((rc=SQLExecute(sth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error executing query\n",0,0,0);
-   backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
-   SQLFreeStmt(sth,SQL_DROP);
-   return 1;
-  }
-
- 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++)
-    {
-     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]);
-   c_id->keyval=atoi(row.cols[1]);
-   c_id->oc_id=bsi->oc->id;
-   c_id->dn=ch_strdup(row.cols[3]);
-   c_id->next=bsi->id_list;
-   bsi->id_list=c_id;
-   Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): added entry id=%d, keyval=%d dn='%s'\n",
-               c_id->id,c_id->keyval,row.cols[3]);
-  }
- backsql_FreeRow(&row);
- SQLFreeStmt(sth,SQL_DROP);
-
- Debug(LDAP_DEBUG_TRACE,"<==backsql_oc_get_candidates()\n",0,0,0);
- return 1;
+
+       case LDAP_SCOPE_ONELEVEL:
+               res = backsql_dn2id( bsi->bi, &base_id, 
+                               bsi->dbh, bsi->base_dn );
+               if ( res != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                               "could not retrieve base_dn id%s\n",
+                               res == LDAP_NO_SUCH_OBJECT ? ": no such entry"
+                               : "", 0, 0 );
+                       bsi->status = res;
+                       return 0;
+               }
+               
+               rc = backsql_BindParamID( sth, 2, &base_id.id );
+               backsql_free_entryID( &base_id, 0 );
+               if ( rc != SQL_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                               "error binding base id parameter\n", 0, 0, 0 );
+                       return 1;
+               }
+               break;
+       }
+       
+       rc = SQLExecute( sth );
+       if ( !BACKSQL_SUCCESS( rc ) ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                       "error executing query\n", 0, 0, 0 );
+               backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
+               SQLFreeStmt( sth, SQL_DROP );
+               return 1;
+       }
+
+       backsql_BindRowAsStrings( sth, &row );
+       rc = SQLFetch( sth );
+       for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
+#if 0
+               e = (Entry *)ch_calloc( 1, sizeof( Entry ) ); 
+               for ( i = 1; i < row.ncols; i++ ) {
+                       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 ] );
+               c_id->keyval = atoi( row.cols[ 1 ] );
+               c_id->oc_id = bsi->oc->id;
+               ber_str2bv( row.cols[ 3 ], 0, 1, &c_id->dn );
+               c_id->next = bsi->id_list;
+               bsi->id_list = c_id;
+               bsi->n_candidates++;
+               Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
+                       "added entry id=%ld, keyval=%ld dn='%s'\n",
+                       c_id->id, c_id->keyval, row.cols[ 3 ] );
+       }
+       backsql_FreeRow( &row );
+       SQLFreeStmt( sth, SQL_DROP );
+
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_oc_get_candidates()\n", 0, 0, 0 );
+
+       return 1;
 }
 
-int backsql_search(BackendDB *be,Connection *conn,Operation *op,
-       const char *base, const char *nbase, int scope,int deref,int slimit,int tlimit,
-       Filter *filter, const char *filterstr,AttributeName *attrs,int attrsonly)
+int
+backsql_search(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       struct berval   *base,
+       struct berval   *nbase,
+       int             scope,
+       int             deref,
+       int             slimit,
+       int             tlimit,
+       Filter          *filter,
+       struct berval   *filterstr,
+       AttributeName   *attrs,
+       int             attrsonly )
 {
- backsql_info *bi=(backsql_info*)be->be_private;
- SQLHDBC dbh;
- int sres;
- int nentries;
- Entry *entry,*res;
- int manageDSAit = get_manageDSAit( op );
- struct berval **v2refs = NULL;
- time_t        stoptime;
- backsql_srch_info srch_info;
- backsql_entryID *eid=NULL;
-
- Debug(LDAP_DEBUG_TRACE,"==>backsql_search(): base='%s', filter='%s', scope=%d,",
-                     nbase,filterstr,scope);
- Debug(LDAP_DEBUG_TRACE," deref=%d, attrsonly=%d, attributes to load: %s\n",
-        deref,attrsonly,attrs==NULL?"all":"custom list");
- dbh=backsql_get_db_conn(be,conn);
-
- if (!dbh)
- {
-  Debug(LDAP_DEBUG_TRACE,"backsql_search(): could not get connection handle - exiting\n",0,0,0);
-  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
-  return 1;
- }
-
- /* TimesTen : Pass it along to the lower level routines */ 
- srch_info.isTimesTen = bi->isTimesTen; 
+       backsql_info            *bi = (backsql_info *)be->be_private;
+       SQLHDBC                 dbh;
+       int                     sres;
+       int                     nentries;
+       Entry                   *entry, *res;
+       int                     manageDSAit = get_manageDSAit( op );
+       BerVarray               v2refs = NULL;
+       time_t                  stoptime = 0;
+       backsql_srch_info       srch_info;
+       backsql_entryID         *eid = NULL;
+       struct slap_limits_set  *limit = NULL;
+       int                     isroot = 0;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): "
+               "base='%s', filter='%s', scope=%d,", 
+               nbase->bv_val, filterstr->bv_val, scope );
+       Debug( LDAP_DEBUG_TRACE, " deref=%d, attrsonly=%d, "
+               "attributes to load: %s\n",
+               deref, attrsonly, attrs == NULL ? "all" : "custom list" );
+       dbh = backsql_get_db_conn( be, conn );
+
+       if ( !dbh ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
+                       "could not get connection handle - exiting\n", 
+                       0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER, "",
+                               "SQL-backend error", NULL, NULL );
+               return 1;
+       }
+
+       /* TimesTen : Pass it along to the lower level routines */ 
+       srch_info.isTimesTen = bi->isTimesTen; 
  
- if (tlimit == 0 && be_isroot(be,&op->o_ndn))
-  {
-   tlimit = -1;        /* allow root to set no limit */
-  } 
- else
-  {
-   tlimit = (tlimit > be->be_timelimit || tlimit < 1) ?
-                   be->be_timelimit : tlimit;
-   stoptime = op->o_time + tlimit;
-  }
-  
- if (slimit == 0 && be_isroot(be,&op->o_ndn))
-  {
-   slimit = -1;        /* allow root to set no limit */
-  }
- else
-  {
-   slimit = (slimit > be->be_sizelimit || slimit < 1) ?
-                   be->be_sizelimit : slimit;
-  }
-
- 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 */
-   if (op->o_abandon)
-    {
-     break;
-    }
-
-   /* check time limit */
-   if ( tlimit != -1 && slap_get_time() > stoptime)
-    {
-        send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
+       /* if not root, get appropriate limits */
+       if ( be_isroot( be, &op->o_ndn ) ) {
+               isroot = 1;
+       } else {
+               ( void ) get_limits( be, &op->o_ndn, &limit );
+       }
+
+       /* The time/size limits come first because they require very little
+        * effort, so there's no chance the candidates are selected and then 
+        * the request is not honored only because of time/size constraints */
+
+       /* if no time limit requested, use soft limit (unless root!) */
+       if ( isroot ) {
+               if ( tlimit == 0 ) {
+                       tlimit = -1;    /* allow root to set no limit */
+               }
+
+               if ( slimit == 0 ) {
+                       slimit = -1;
+               }
+
+       } else {
+               /* if no limit is required, use soft limit */
+               if ( tlimit <= 0 ) {
+                       tlimit = limit->lms_t_soft;
+
+               /* if requested limit higher than hard limit, abort */
+               } else if ( tlimit > limit->lms_t_hard ) {
+                       /* no hard limit means use soft instead */
+                       if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) {
+                               tlimit = limit->lms_t_soft;
+
+                       /* positive hard limit means abort */
+                       } else if ( limit->lms_t_hard > 0 ) {
+                               send_search_result( conn, op, 
+                                               LDAP_UNWILLING_TO_PERFORM,
+                                               NULL, NULL, NULL, NULL, 0 );
+                               return 0;
+                       }
+               
+                       /* negative hard limit means no limit */
+               }
+               
+               /* if no limit is required, use soft limit */
+               if ( slimit <= 0 ) {
+                       slimit = limit->lms_s_soft;
+
+               /* if requested limit higher than hard limit, abort */
+               } else if ( slimit > limit->lms_s_hard ) {
+                       /* no hard limit means use soft instead */
+                       if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) {
+                               slimit = limit->lms_s_soft;
+
+                       /* positive hard limit means abort */
+                       } else if ( limit->lms_s_hard > 0 ) {
+                               send_search_result( conn, op, 
+                                               LDAP_UNWILLING_TO_PERFORM,
+                                               NULL, NULL, NULL, NULL, 0 );
+                               return 0;
+                       }
+                       
+                       /* negative hard limit means no limit */
+               }
+       }
+
+       /* compute it anyway; root does not use it */
+       stoptime = op->o_time + tlimit;
+
+       backsql_init_search( &srch_info, bi, 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 );
+
+       if ( !isroot && limit->lms_s_unchecked != -1 ) {
+               if ( srch_info.n_candidates > limit->lms_s_unchecked ) {
+                       send_search_result( conn, op,
+                                       LDAP_ADMINLIMIT_EXCEEDED,
+                                       NULL, NULL, NULL, NULL, 0 );
+                       goto done;
+               }
+       }
+       
+       nentries = 0;
+       /*
+        * now we load candidate entries (only those attributes 
+        * 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 */
+               if ( op->o_abandon ) {
+                       break;
+               }
+
+               /* check time limit */
+               if ( tlimit != -1 && slap_get_time() > stoptime ) {
+                       send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
                                NULL, NULL, v2refs, NULL, nentries );
+                       break;
+               }
+
+               Debug(LDAP_DEBUG_TRACE, "backsql_search(): loading data "
+                       "for entry id=%ld, oc_id=%ld, keyval=%ld\n",
+                       eid->id, eid->oc_id, eid->keyval );
+
+               entry = (Entry *)ch_calloc( sizeof( Entry ), 1 );
+               res = backsql_id2entry( &srch_info, entry, eid );
+               if ( res == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
+                               "error in backsql_id2entry() "
+                               "- skipping entry\n", 0, 0, 0 );
+                       continue;
+               }
+
+               if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
+                       is_entry_referral( entry ) ) {
+                       BerVarray refs = get_entry_referrals( be, conn,
+                                       op, entry );
+
+                       send_search_reference( be, conn, op, entry, refs, 
+                                       NULL, &v2refs );
+                       ber_bvarray_free( refs );
+                       continue;
+               }
+
+               if ( test_filter( be, conn, op, entry, filter ) 
+                               == LDAP_COMPARE_TRUE ) {
+                       sres = send_search_entry( be, conn, op, entry,
+                                       attrs, attrsonly, NULL );
+                       if ( sres == -1 ) {
+                               Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
+                                       "connection lost\n", 0, 0, 0 );
+                               break;
+                       }
+                       nentries += !sres;                                      
+               }
+               entry_free( entry );
+
+               if ( slimit != -1 && nentries > slimit ) {
+                       send_search_result( conn, op, LDAP_SIZELIMIT_EXCEEDED,
+                               NULL, NULL, v2refs, NULL, nentries );
+                       break;
+               }
      
-     break;
-    }
-     
-   Debug(LDAP_DEBUG_TRACE,"backsql_search(): loading data for entry id=%d, oc_id=%d, keyval=%d\n",
-               eid->id,eid->oc_id,eid->keyval);
-   
-   entry=(Entry *)ch_calloc(sizeof(Entry),1);
-   res=backsql_id2entry(&srch_info,entry,eid);
-   if (res==NULL)
-    {
-     Debug(LDAP_DEBUG_TRACE,"backsql_search(): error in backsql_id2entry() - skipping entry\n",0,0,0);
-     continue;
-    }
-
-   if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
-                       is_entry_referral( entry ) )
-    {
-     struct berval **refs = get_entry_referrals(be,conn,op,entry);
-
-     send_search_reference( be, conn, op, entry, refs, scope, NULL, &v2refs );
-     ber_bvecfree( refs );
-     continue;
-    }
-
-   if (test_filter(be,conn,op,entry,filter)==LDAP_COMPARE_TRUE)
-    {
-     if ((sres=send_search_entry(be,conn,op,entry,attrs,attrsonly,NULL))==-1)
-      {
-       Debug(LDAP_DEBUG_TRACE,"backsql_search(): connection lost\n",0,0,0);
-       break;
-      }
-     nentries+=!sres;                                  
-    }
-   entry_free(entry);
-  }
-
- for(eid=srch_info.id_list;eid!=NULL;eid=backsql_free_entryID(eid));
-
- charray_free(srch_info.attrs);
-
- if (nentries>0)
-  send_search_result( conn, op,
-               v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
-               NULL, NULL, v2refs, NULL, nentries );
- else
-  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,NULL,NULL,NULL,0);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_search()\n",0,0,0);
- return 0;
+       }
+
+       if ( nentries > 0 ) {
+               send_search_result( conn, op,
+                       v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
+                       NULL, NULL, v2refs, NULL, nentries );
+       } else {
+               send_ldap_result( conn, op, srch_info.status,
+                               NULL, NULL, NULL, 0 );
+       }
+       
+done:;
+       for ( eid = srch_info.id_list; eid != NULL; 
+                       eid = backsql_free_entryID( eid, 1 ) );
+
+       charray_free( srch_info.attrs );
+
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_search()\n", 0, 0, 0 );
+       return 0;
 }
 
 #endif /* SLAPD_SQL */
+
index 36bb21c4b25f108fcc781c7254105feec6879137..d20a363dad05af5418cfb8eb3b59c03abf50bd77 100644 (file)
 #include <sql.h>
 #include <sqlext.h>
 
-typedef struct
-{
- SWORD ncols;
- char** col_names;
- UDWORD *col_prec;
- char** cols;
- SQLINTEGER* is_null;
-}BACKSQL_ROW_NTS;
+typedef struct {
+       SWORD           ncols;
+       char            **col_names;
+       UDWORD          *col_prec;
+       char            **cols;
+       SQLINTEGER      *is_null;
+} BACKSQL_ROW_NTS;
 
-#endif
+#endif /* __BACKSQL_SQL_TYPES_H__ */
 
index 8251b5a0c96403cd691b9c69ba990cb9a607ecc6..c549c99b7b47c8034fb9128ce3d6f0b2edd4c1f6 100644 (file)
@@ -12,8 +12,9 @@
 #ifdef SLAPD_SQL
 
 #include <stdio.h>
-#include <string.h>
+#include "ac/string.h"
 #include <sys/types.h>
+#include "ldap_pvt.h"
 #include "slap.h"
 #include "back-sql.h"
 #include "sql-types.h"
 
 #define MAX_ATTR_LEN 16384
 
-typedef struct backsql_conn
-{
- int ldap_cid;
- SQLHDBC dbh;
-}backsql_db_conn;
+typedef struct backsql_conn {
+       int             ldap_cid;
+       SQLHDBC         dbh;
+} backsql_db_conn;
 
-int backsql_dummy(void *,void *);
+int backsql_dummy( void *, void * );
 
-void backsql_PrintErrors(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth,int rc)
+void
+backsql_PrintErrors( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth, int rc )
 {
SQLCHAR           msg[SQL_MAX_MESSAGE_LENGTH];    /* msg. buffer    */
SQLCHAR           state[SQL_SQLSTATE_SIZE];       /* statement buf. */
SDWORD        iSqlCode;                              /* return code    */
- SWORD       len=SQL_MAX_MESSAGE_LENGTH-1;                               /* return length  */
      SQLCHAR msg[SQL_MAX_MESSAGE_LENGTH];            /* msg. buffer    */
      SQLCHAR state[SQL_SQLSTATE_SIZE];               /* statement buf. */
      SDWORD  iSqlCode;                               /* return code    */
+       SWORD   len = SQL_MAX_MESSAGE_LENGTH - 1;       /* return length  */ 
 
- Debug(LDAP_DEBUG_TRACE,"Return code: %d\n", rc,0,0);
-  
- while((rc=SQLError(henv,hdbc,sth,state,&iSqlCode,msg,
-             SQL_MAX_MESSAGE_LENGTH - 1, &len)) == SQL_SUCCESS
-       || rc == SQL_SUCCESS_WITH_INFO
-       )
- {
-  Debug(LDAP_DEBUG_TRACE,"Native error code: %d\n",(int) iSqlCode,0,0);
-  Debug(LDAP_DEBUG_TRACE,"SQL engine state: %s\n", state,0,0);
-  Debug(LDAP_DEBUG_TRACE,"Message: %s\n",msg,0,0);
- }
+       Debug( LDAP_DEBUG_TRACE, "Return code: %d\n", rc, 0, 0 );
+
+
+       rc = SQLError( henv, hdbc, sth, state, &iSqlCode, msg,
+                       SQL_MAX_MESSAGE_LENGTH - 1, &len );
+       for ( ; BACKSQL_SUCCESS( rc ); ) {
+               Debug( LDAP_DEBUG_TRACE, "Native error code: %d\n", 
+                               (int)iSqlCode, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "SQL engine state: %s\n", 
+                               state, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "Message: %s\n", msg, 0, 0 );
+               rc = SQLError( henv, hdbc, sth, state, &iSqlCode, msg,
+                               SQL_MAX_MESSAGE_LENGTH - 1, &len );
+       }
 }
 
-RETCODE backsql_Prepare(SQLHDBC dbh,SQLHSTMT *sth,char* query,int timeout)
+RETCODE
+backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char *query, int timeout )
 {
- RETCODE rc;
- char drv_name[30];
- SWORD len;
- int i;
- rc=SQLAllocStmt(dbh,sth);
- 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)
-   {
-    Debug(LDAP_DEBUG_TRACE,"_SQLPrepare(): SQLSetStmtOption(SQL_CONCURRENCY,SQL_CONCUR_ROWVER) failed:\n", 0,0,0);
-    backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
-   }
-  }
- if (timeout>0)
-  {
-   Debug(LDAP_DEBUG_TRACE,"_SQLprepare(): setting query timeout to %d sec.\n", timeout,0,0);
-   if ((rc=SQLSetStmtOption(*sth,SQL_QUERY_TIMEOUT,timeout)) != SQL_SUCCESS)
-    {
-     backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
-    }
-  }
- /*Debug(LDAP_DEBUG_TRACE,"<==_SQLPrepare() calling SQLPrepare()\n", 0,0,0);*/
- return SQLPrepare(*sth,query,SQL_NTS);
+       RETCODE         rc;
+       char            drv_name[ 30 ];
+       SWORD           len;
+
+       rc = SQLAllocStmt( dbh, sth );
+       if ( rc != SQL_SUCCESS ) {
+               return rc;
+       }
+
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "==>_SQLPrepare()\n", 0, 0, 0 );
+#endif
+
+       SQLGetInfo( dbh, SQL_DRIVER_NAME, drv_name, 30, &len );
+
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "_SQLPrepare(): driver name='%s'\n",
+                       drv_name, 0, 0 );
+#endif
+       
+       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 ) {
+                       Debug( LDAP_DEBUG_TRACE, "_SQLPrepare(): "
+                               "SQLSetStmtOption(SQL_CONCURRENCY,SQL_CONCUR_ROWVER) failed:\n", 
+                               0, 0, 0 );
+                       backsql_PrintErrors( SQL_NULL_HENV, dbh, *sth, rc );
+               }
+       }
+
+       if ( timeout > 0 ) {
+               Debug( LDAP_DEBUG_TRACE, "_SQLprepare(): "
+                       "setting query timeout to %d sec.\n", 
+                       timeout, 0, 0 );
+               rc = SQLSetStmtOption( *sth, SQL_QUERY_TIMEOUT, timeout );
+               if ( rc != SQL_SUCCESS ) {
+                       backsql_PrintErrors( SQL_NULL_HENV, dbh, *sth, rc );
+               }
+       }
+
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "<==_SQLPrepare() calling SQLPrepare()\n",
+                       0, 0, 0 );
+#endif
+
+       return SQLPrepare( *sth, query, SQL_NTS );
 }
 
-RETCODE backsql_BindParamStr(SQLHSTMT sth,int par_ind,char *str,int maxlen)
+#if 0
+RETCODE
+backsql_BindParamStr( SQLHSTMT sth, int par_ind, char *str, int maxlen )
 {
- RETCODE rc;
- SQLINTEGER len=SQL_NTS;
- rc=SQLBindParameter(sth,(SQLUSMALLINT)par_ind,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR,
-         (SQLUINTEGER)maxlen,0,(SQLPOINTER)str,(SQLUINTEGER)maxlen,NULL);
- return rc;
+       RETCODE         rc;
+
+       rc = SQLBindParameter( sth, (SQLUSMALLINT)par_ind, SQL_PARAM_INPUT,
+                       SQL_C_CHAR, SQL_VARCHAR,
+                       (SQLUINTEGER)maxlen, 0, (SQLPOINTER)str,
+                       (SQLUINTEGER)maxlen, NULL );
+       return rc;
 }
 
-RETCODE backsql_BindParamID(SQLHSTMT sth,int par_ind,unsigned long *id)
+RETCODE
+backsql_BindParamID( SQLHSTMT sth, int par_ind, unsigned long *id )
 {
return SQLBindParameter(sth,(SQLUSMALLINT)par_ind,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,
-         0,0,(SQLPOINTER)id,0,(SQLINTEGER*)NULL);
+       return SQLBindParameter( sth, (SQLUSMALLINT)par_ind,
                      SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER,
+                       0, 0, (SQLPOINTER)id, 0, (SQLINTEGER*)NULL );
 }
+#endif
 
-RETCODE backsql_BindRowAsStrings(SQLHSTMT sth,BACKSQL_ROW_NTS *row)
+RETCODE
+backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row )
 {
- RETCODE rc;
- SQLCHAR colname[64];
- SQLSMALLINT name_len,col_type,col_scale,col_null;
- UDWORD col_prec;
- int i;
- 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));
-  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;
-       rc=SQLBindCol(sth,(SQLUSMALLINT)i,SQL_C_CHAR,(SQLPOINTER)row->cols[i-1],col_prec+1,
-                                                      &row->is_null[i-1]);
-   }
-   else
-   {
-    row->cols[i-1]=(char*)ch_calloc((col_prec+1),sizeof(char));
-    row->col_prec[i-1]=col_prec;
-       rc=SQLBindCol(sth,(SQLUSMALLINT)i,SQL_C_CHAR,(SQLPOINTER)row->cols[i-1],col_prec+1,
-                                                      &row->is_null[i-1]);
-   }
-  }
- }
- /*Debug(LDAP_DEBUG_TRACE,"<== backsql_BindRowAsStrings()\n",0,0,0);*/
- return rc;
+       RETCODE         rc;
+       SQLCHAR         colname[ 64 ];
+       SQLSMALLINT     name_len, col_type, col_scale, col_null;
+       UDWORD          col_prec;
+       int             i;
+
+       if ( row == NULL ) {
+               return SQL_ERROR;
+       }
+
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "==> backsql_BindRowAsStrings()\n", 0, 0, 0 );
+#endif
+       
+       rc = SQLNumResultCols( sth, &row->ncols );
+       if ( rc != SQL_SUCCESS ) {
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "_SQLBindRowAsStrings(): "
+                       "SQLNumResultCols() failed:\n", 0, 0, 0 );
+#endif
+               
+               backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, sth, rc );
+       } else {
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
+                       "ncols=%d\n", (int)row->ncols, 0, 0 );
+#endif
+
+               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 ) );
+               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,
+                                       &col_prec, &col_scale, &col_null );
+                       row->col_names[ i - 1 ] = ch_strdup( colname );
+#if 0
+                       Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
+                               "col_name=%s, col_prec[%d]=%d\n",
+                               colname, (int)i, (int)col_prec );
+#endif
+                       if ( col_type == SQL_LONGVARCHAR 
+                                       || col_type == SQL_LONGVARBINARY) {
+#if 0
+                               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()
+                                */
+#endif
+                               col_prec = MAX_ATTR_LEN;
+                               row->cols[ i - 1 ] = (char *)ch_calloc( col_prec + 1, sizeof( char ) );
+                               row->col_prec[ i - 1 ] = col_prec;
+                               rc = SQLBindCol( sth, (SQLUSMALLINT)i,
+                                               SQL_C_CHAR,
+                                               (SQLPOINTER)row->cols[ i - 1 ],
+                                               col_prec + 1,
+                                               &row->is_null[ i - 1 ] );
+                       } else {
+                               row->cols[ i - 1 ] = (char *)ch_calloc( col_prec + 1, sizeof( char ) );
+                               row->col_prec[ i - 1 ] = col_prec;
+                               rc = SQLBindCol( sth, (SQLUSMALLINT)i,
+                                               SQL_C_CHAR,
+                                               (SQLPOINTER)row->cols[ i - 1 ],
+                                               col_prec + 1,
+                                               &row->is_null[ i - 1 ] );
+                       }
+               }
+       }
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "<== backsql_BindRowAsStrings()\n", 0, 0, 0 );
+#endif
+
+       return rc;
 }
 
-RETCODE backsql_FreeRow(BACKSQL_ROW_NTS *row)
+RETCODE
+backsql_FreeRow( BACKSQL_ROW_NTS *row )
 {
- int i;
- if (row->cols == NULL)
-  return SQL_ERROR;
- for(i=0;i<row->ncols;i++)
-  {
-   free(row->cols[i]);
-  }
- free(row->col_names);
- free(row->col_prec);
- free(row->cols);
- free(row->is_null);
- return SQL_SUCCESS;
+       int     i;
+
+       if ( row->cols == NULL ) {
+               return SQL_ERROR;
+       }
+
+       for ( i = 0; i < row->ncols; i++ ) {
+               /*
+                * FIXME: we need to free the col_names as well, don't we?
+                */
+               free( row->cols[ i ] );
+       }
+
+       free( row->col_names );
+       free( row->col_prec );
+       free( row->cols );
+       free( row->is_null );
+
+       return SQL_SUCCESS;
 }
 
-int backsql_cmp_connid(backsql_db_conn *c1,backsql_db_conn *c2)
+int
+backsql_cmp_connid( backsql_db_conn *c1, backsql_db_conn *c2 )
 {
- if (c1->ldap_cid > c2->ldap_cid)
-  return 1; 
- if (c1->ldap_cid < c2->ldap_cid)
-  return -1; 
- return 0;
+       if ( c1->ldap_cid > c2->ldap_cid ) {
+               return 1;
+       }
+       
+       if ( c1->ldap_cid < c2->ldap_cid ) {
+               return -1;
+       }
+       
+       return 0;
 }
 
-
-int backsql_close_db_conn(backsql_db_conn *conn)
+int
+backsql_close_db_conn( backsql_db_conn *conn )
 {
- Debug(LDAP_DEBUG_TRACE,"==>backsql_close_db_conn()\n",0,0,0);
- SQLTransact(NULL, conn->dbh, SQL_COMMIT);  /* TimesTen */
- SQLDisconnect(conn->dbh);
- SQLFreeConnect(conn->dbh);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_close_db_conn()\n",0,0,0);
- return 1;
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_close_db_conn()\n", 0, 0, 0 );
+
+       /* TimesTen */
+       SQLTransact( SQL_NULL_HENV, conn->dbh, SQL_COMMIT );
+       SQLDisconnect( conn->dbh );
+       SQLFreeConnect( conn->dbh );
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_close_db_conn()\n", 0, 0, 0 );
+       return 1;
 }
 
-int backsql_init_db_env(backsql_info *si)
+int
+backsql_init_db_env( backsql_info *si )
 {
- RETCODE rc;
- Debug(LDAP_DEBUG_TRACE,"==>backsql_init_db_env()\n",0,0,0);
- if ((rc=SQLAllocEnv(&si->db_env)) != SQL_SUCCESS)
-  {
-   Debug(LDAP_DEBUG_TRACE,"init_db_env: SQLAllocEnv failed:\n",0,0,0);
-   backsql_PrintErrors(SQL_NULL_HENV,SQL_NULL_HDBC,SQL_NULL_HENV,rc);
-  }
- Debug(LDAP_DEBUG_TRACE,"<==backsql_init_db_env()\n",0,0,0);
- return SQL_SUCCESS;
+       RETCODE         rc;
+       
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_init_db_env()\n", 0, 0, 0 );
+       rc = SQLAllocEnv( &si->db_env );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "init_db_env: SQLAllocEnv failed:\n",
+                               0, 0, 0 );
+               backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC,
+                               SQL_NULL_HENV, rc );
+       }
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_init_db_env()\n", 0, 0, 0 );
+       return SQL_SUCCESS;
 }
 
-int backsql_free_db_env(backsql_info *si)
+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;
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_env()\n", 0, 0, 0 );
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "free_db_env(): delete AVL tree here!!!\n",
+                       0, 0, 0 );
+#endif
+
+       /*
+        * stop, if frontend waits for all threads to shutdown 
+        * before calling this -- then what are we going to delete?? 
+        * everything is already deleted...
+        */
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_free_db_env()\n", 0, 0, 0 );
+       return SQL_SUCCESS;
 }
 
-backsql_db_conn* backsql_open_db_conn(backsql_info *si,int ldap_cid)
+backsql_db_conn *
+backsql_open_db_conn( backsql_info *si, int ldap_cid )
 {
- char DBMSName[32]; /* TimesTen*/
-
- backsql_db_conn *dbc=(backsql_db_conn*)ch_calloc(1,sizeof(backsql_db_conn));
- int rc;
- Debug(LDAP_DEBUG_TRACE,"==>backsql_open_db_conn()\n",0,0,0);
- dbc->ldap_cid=ldap_cid;
- if ((rc=SQLAllocConnect(si->db_env,&dbc->dbh)) != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLAllocConnect() failed:\n",0,0,0);
-   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);
-   else
-       Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLConnect() succeeded with info:\n",0,0,0);
-   backsql_PrintErrors(si->db_env,dbc->dbh,SQL_NULL_HENV,rc);
-   if (rc != SQL_SUCCESS_WITH_INFO)
-    return NULL;
-  }
-
- /* TimesTen : Turn off autocommit.  We must explicitly commit any transactions. */
-
- SQLSetConnectOption(dbc->dbh, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF);
-
- /* See if this connection is to TimesTen.  If it is,
-    remember that fact for later use. */
-
- si->isTimesTen = 0;        /* Assume until proven otherwise */
-
- DBMSName[0] = '\0';
- rc = SQLGetInfo(dbc->dbh, SQL_DBMS_NAME, (PTR) &DBMSName,
-         sizeof(DBMSName), NULL);
- if (rc == SQL_SUCCESS) {
-   if (strcmp(DBMSName, "TimesTen") == 0 ||
-       strcmp(DBMSName, "Front-Tier") == 0) {
-     Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: TimesTen database!\n",0,0,0);
-     si->isTimesTen = 1;
-   }
- }
- else {
-   Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLGetInfo() failed:\n",0,0,0);
-   backsql_PrintErrors(si->db_env,dbc->dbh,SQL_NULL_HENV,rc);
- }  
- /* end TimesTen */
+       /* TimesTen */
+       char                    DBMSName[ 32 ];
+       backsql_db_conn         *dbc;
+       int                     rc;
  
- Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn(): connected, adding to tree\n",0,0,0);
- ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
- avl_insert(&si->db_conns,dbc,(AVL_CMP)backsql_cmp_connid,backsql_dummy);
- ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
- Debug(LDAP_DEBUG_TRACE,"<==backsql_open_db_conn()\n",0,0,0);
- return dbc;
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_open_db_conn()\n", 0, 0, 0 );
+       dbc = (backsql_db_conn *)ch_calloc( 1, sizeof( backsql_db_conn ) );
+       dbc->ldap_cid = ldap_cid;
+       rc = SQLAllocConnect( si->db_env, &dbc->dbh );
+       if (!BACKSQL_SUCCESS( rc ) ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
+                       "SQLAllocConnect() failed:\n", 0, 0, 0 );
+               backsql_PrintErrors( si->db_env, SQL_NULL_HDBC,
+                               SQL_NULL_HENV, rc );
+               return NULL;
+       }
+
+       rc = SQLConnect( dbc->dbh, si->dbname, SQL_NTS, si->dbuser, 
+                       SQL_NTS, si->dbpasswd, SQL_NTS );
+       if ( rc != SQL_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
+                       "SQLConnect() to database '%s' as user '%s' "
+                       "%s:\n", si->dbname, si->dbuser,
+                       rc == SQL_SUCCESS_WITH_INFO ?
+                       "succeeded with info" : "failed" );
+               backsql_PrintErrors( si->db_env, dbc->dbh, SQL_NULL_HENV, rc );
+               if ( rc != SQL_SUCCESS_WITH_INFO ) {
+                       return NULL;
+               }
+       }
+
+       /* 
+        * TimesTen : Turn off autocommit.  We must explicitly
+        * commit any transactions. 
+        */
+       SQLSetConnectOption( dbc->dbh, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF );
+
+       /* 
+        * See if this connection is to TimesTen.  If it is,
+        * remember that fact for later use.
+        */
+       si->isTimesTen = 0;     /* Assume until proven otherwise */
+       DBMSName[ 0 ] = '\0';
+       rc = SQLGetInfo( dbc->dbh, SQL_DBMS_NAME, (PTR)&DBMSName,
+                       sizeof( DBMSName ), NULL );
+       if ( rc == SQL_SUCCESS ) {
+               if ( strcmp( DBMSName, "TimesTen" ) == 0 ||
+                               strcmp( DBMSName, "Front-Tier" ) == 0 ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
+                               "TimesTen database!\n", 0, 0, 0 );
+                       si->isTimesTen = 1;
+               }
+       } else {
+               Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
+                       "SQLGetInfo() failed:\n", 0, 0, 0 );
+               backsql_PrintErrors( si->db_env, dbc->dbh, SQL_NULL_HENV, rc );
+       }
+       /* end TimesTen */
+
+       Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(): "
+               "connected, adding to tree\n", 0, 0, 0 );
+       ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
+       avl_insert( &si->db_conns, dbc, (AVL_CMP)backsql_cmp_connid,
+                       backsql_dummy );
+       ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_open_db_conn()\n", 0, 0, 0 );
+
+       return dbc;
 }
 
-int backsql_free_db_conn(Backend *be,Connection *ldapc)
+int
+backsql_free_db_conn( Backend *be, Connection *ldapc )
 {
- backsql_info *si=(backsql_info*)be->be_private;
- backsql_db_conn tmp,*conn;
- Debug(LDAP_DEBUG_TRACE,"==>backsql_free_db_conn()\n",0,0,0);
- tmp.ldap_cid=ldapc->c_connid;
- 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);
-   backsql_close_db_conn(conn);
-  }
- Debug(LDAP_DEBUG_TRACE,"<==backsql_free_db_conn()\n",0,0,0);
- return SQL_SUCCESS;
+       backsql_info            *si = (backsql_info *)be->be_private;
+       backsql_db_conn         tmp, *conn;
+
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_conn()\n", 0, 0, 0 );
+       tmp.ldap_cid = ldapc->c_connid;
+       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 );
+               backsql_close_db_conn( conn );
+       }
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_free_db_conn()\n", 0, 0, 0 );
+       return SQL_SUCCESS;
 }
 
-SQLHDBC backsql_get_db_conn(Backend *be,Connection *ldapc)
+SQLHDBC
+backsql_get_db_conn( Backend *be, Connection *ldapc )
 {
- backsql_info *si=(backsql_info*)be->be_private;
- backsql_db_conn *dbc;
- backsql_db_conn tmp;
- 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);
- if (!dbc)
- {
-   Debug(LDAP_DEBUG_TRACE,"backsql_get_db_conn(): could not get connection handle -- returning NULL\n",0,0,0);
-   return NULL;
- }
- ldap_pvt_thread_mutex_lock(&si->schema_mutex);
- if (!si->schema_loaded)
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_get_db_conn(): first call -- reading schema map\n",0,0,0);
-   backsql_load_schema_map(si,dbc->dbh);
-  }
- ldap_pvt_thread_mutex_unlock(&si->schema_mutex);
+       backsql_info            *si = (backsql_info *)be->be_private;
+       backsql_db_conn         *dbc;
+       backsql_db_conn         tmp;
+
+       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 );
+       }
  
- Debug(LDAP_DEBUG_TRACE,"<==backsql_get_db_conn()\n",0,0,0);
- return dbc->dbh;
+       if ( !dbc ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
+                       "could not get connection handle -- returning NULL\n",
+                       0, 0, 0 );
+               return SQL_NULL_HDBC;
+       }
+       ldap_pvt_thread_mutex_lock( &si->schema_mutex );
+       if ( !si->schema_loaded ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
+                       "first call -- reading schema map\n", 0, 0, 0 );
+               backsql_load_schema_map( si, dbc->dbh );
+       }
+       ldap_pvt_thread_mutex_unlock( &si->schema_mutex );
+
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_get_db_conn()\n", 0, 0, 0 );
+       return dbc->dbh;
 }
 
 #endif /* SLAPD_SQL */
index 6bf738ce09652871d170550b7dc7d427d3d220c8..00edc26b6ef472b4d366f1ae61a2d194139bf345 100644 (file)
 #include "back-sql.h"
 #include "sql-types.h"
 
-RETCODE backsql_Prepare(SQLHDBC dbh,SQLHSTMT *sth,char* query,int timeout);
-RETCODE backsql_BindParamStr(SQLHSTMT sth,int par_ind,char *str,int maxlen);
-RETCODE backsql_BindParamID(SQLHSTMT sth,int par_ind,unsigned long *id);
-RETCODE backsql_BindRowAsStrings(SQLHSTMT sth,BACKSQL_ROW_NTS *row);
-RETCODE backsql_FreeRow(BACKSQL_ROW_NTS *row);
-void backsql_PrintErrors(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth,int rc);
-
-int backsql_init_db_env(backsql_info *si);
-int backsql_free_db_env(backsql_info *si);
-SQLHDBC backsql_get_db_conn(Backend *be,Connection *ldapc);
-int backsql_free_db_conn(Backend *be,Connection *ldapc);
-
-#endif
+RETCODE backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char* query, int timeout );
+
+#define backsql_BindParamStr( sth, par_ind, str, maxlen )              \
+       SQLBindParameter( (sth), (SQLUSMALLINT)(par_ind),               \
+                       SQL_PARAM_INPUT,                                \
+                       SQL_C_CHAR, SQL_VARCHAR,                        \
+                       (SQLUINTEGER)(maxlen), 0, (SQLPOINTER)(str),    \
+                       (SQLUINTEGER)(maxlen), NULL )
+
+#define backsql_BindParamID( sth, par_ind, id )                                \
+       SQLBindParameter( (sth), (SQLUSMALLINT)(par_ind),               \
+                       SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER,      \
+                       0, 0, (SQLPOINTER)(id), 0, (SQLINTEGER*)NULL )
+
+RETCODE backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row );
+RETCODE backsql_FreeRow( BACKSQL_ROW_NTS *row );
+void backsql_PrintErrors( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth, int rc );
+
+int backsql_init_db_env( backsql_info *si );
+int backsql_free_db_env( backsql_info *si );
+SQLHDBC backsql_get_db_conn( Backend *be, Connection *ldapc );
+int backsql_free_db_conn( Backend *be, Connection *ldapc );
+
+#endif /* __BACKSQL_SQL_WRAP_H__ */
 
index 00e1d33889e6ffce2c509c180d20e50216abfcba..e7458b7296ad244e648cd4ae92cb053863e6d21b 100644 (file)
 
 #include <stdio.h>
 #include <sys/types.h>
-#include <string.h>
-#include <stdarg.h>
+#include "ac/string.h"
+#include "ac/ctype.h"
+#include "ac/stdarg.h"
 #include "slap.h"
 #include "back-sql.h"
 #include "schema-map.h"
 #include "util.h"
 
 
-char backsql_def_oc_query[]="SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return FROM ldap_oc_mappings";
-char backsql_def_at_query[]="SELECT name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return,sel_expr_u FROM ldap_attr_mappings WHERE oc_map_id=?";
-char backsql_def_delentry_query[]="DELETE FROM ldap_entries WHERE id=?";
-char backsql_def_insentry_query[]="INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)";
-char backsql_def_subtree_cond[]="ldap_entries.dn LIKE CONCAT('%',?)";
-char backsql_id_query[]="SELECT id,keyval,oc_map_id FROM ldap_entries WHERE ";
-
-/* TimesTen*/
+char backsql_def_oc_query[] = 
+       "SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return "
+       "FROM ldap_oc_mappings";
+char backsql_def_at_query[] = 
+       "SELECT name,sel_expr,from_tbls,join_where,add_proc,delete_proc,"
+       "param_order,expect_return,sel_expr_u FROM ldap_attr_mappings "
+       "WHERE oc_map_id=?";
+char backsql_def_delentry_query[] = "DELETE FROM ldap_entries WHERE id=?";
+char backsql_def_insentry_query[] = 
+       "INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) "
+       "VALUES (?,?,?,?)";
+char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)";
+char backsql_def_upper_subtree_cond[] = "(ldap_entries.dn) LIKE CONCAT('%',?)";
+char backsql_id_query[] = "SELECT id,keyval,oc_map_id FROM ldap_entries WHERE ";
+
+/* TimesTen */
 char backsql_check_dn_ru_query[] = "SELECT dn_ru from ldap_entries";
 
-char* backsql_strcat(char* dest,int *buflen, ...)
+struct berval *
+backsql_strcat( struct berval *dest, int *buflen, ... )
 {
- va_list strs;
- int cdlen,cslen,grow;
- char *cstr;
+       va_list         strs;
+       int             cdlen, cslen, grow;
+       char            *cstr;
+
+       assert( dest );
+       assert( dest->bv_val == NULL 
+                       || dest->bv_len == strlen( dest->bv_val ) );
  
- /*Debug(LDAP_DEBUG_TRACE,"==>my_strcat()\n");*/
- va_start(strs,buflen);
- if (dest==NULL || *buflen<=0)
-  {
-   dest=(char*)ch_calloc(BACKSQL_STR_GROW,sizeof(char));
-   *buflen=BACKSQL_STR_GROW;
-  }
- cdlen=strlen(dest)+1;
- while ((cstr=va_arg(strs,char*)) != NULL)
-  {
-   cslen=strlen(cstr);
-   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)
-      {
-       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;
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n" );
+#endif
+
+       va_start( strs, buflen );
+       if ( dest->bv_val == NULL || *buflen <= 0 ) {
+               dest->bv_val = (char *)ch_calloc( BACKSQL_STR_GROW, 
+                               sizeof( char ) );
+               dest->bv_len = 0;
+               *buflen = BACKSQL_STR_GROW;
+       }
+       cdlen = dest->bv_len;
+       while ( ( cstr = va_arg( strs, char * ) ) != NULL ) {
+               cslen = strlen( cstr );
+               grow = BACKSQL_MAX( BACKSQL_STR_GROW, cslen );
+               if ( *buflen - cdlen <= cslen ) {
+                       char    *tmp_dest;
+
+#if 0
+                       Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
+                               "buflen=%d, cdlen=%d, cslen=%d "
+                               "-- reallocating dest\n",
+                               *buflen, cdlen + 1, cslen );
+#endif
+                       tmp_dest = (char *)ch_realloc( dest->bv_val,
+                                       ( *buflen ) + grow * sizeof( char ) );
+                       if ( tmp_dest == NULL ) {
+                               Debug( LDAP_DEBUG_ANY, "backsql_strcat(): "
+                                       "could not reallocate string buffer.\n",
+                                       0, 0, 0 );
+                               return NULL;
+                       }
+                       dest->bv_val = tmp_dest;
+                       *buflen += grow;
+#if 0
+                       Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
+                               "new buflen=%d, dest=%p\n", *buflen, dest, 0 );
+#endif
+               }
+               AC_MEMCPY( dest->bv_val + cdlen, cstr, cslen + 1 );
+               cdlen += cslen;
+       }
+       va_end( strs );
+
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_strcat() (dest='%s')\n", 
+                       dest, 0, 0 );
+#endif
+
+       dest->bv_len = cdlen;
+
+       return dest;
 } 
 
-int backsql_entry_addattr(Entry *e,char *at_name,char *at_val,unsigned int at_val_len)
+int
+backsql_entry_addattr(
+       Entry           *e,
+       char            *at_name,
+       char            *at_val, 
+       unsigned int    at_val_len )
 {
- Attribute *c_at=e->e_attrs;
- struct berval* add_val[2];
- struct berval cval;
- AttributeDescription *ad;
- int rc;
- const char *text;
- Debug(LDAP_DEBUG_TRACE,"backsql_entry_addattr(): at_name='%s', at_val='%s'\n",at_name,at_val,0);
- cval.bv_val=at_val;
- cval.bv_len=at_val_len;
- add_val[0]=&cval;
- add_val[1]=NULL;
- ad=NULL;
- rc = slap_str2ad( at_name, &ad, &text );
- if( rc != LDAP_SUCCESS ) 
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_entry_addattr(): failed to find AttributeDescription for '%s'\n",at_name,0,0);
-   return 0;
-  }
-  
- rc = attr_merge(e,ad,add_val);
-
- if( rc != 0 )
-  {
-   Debug(LDAP_DEBUG_TRACE,"backsql_entry_addattr(): failed to merge value '%s' for attribute '%s'\n",at_val,at_name,0);
-   return 0;
-  }
- Debug(LDAP_DEBUG_TRACE,"<==backsql_query_addattr()\n",0,0,0);
- return 1;
+       struct berval           add_val[ 2 ];
+       AttributeDescription    *ad;
+       int                     rc;
+       const char              *text;
+
+       Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
+               "at_name='%s', at_val='%s'\n", at_name, at_val, 0 );
+       add_val[ 0 ].bv_val = at_val;
+       add_val[ 0 ].bv_len = at_val_len;
+       add_val[ 1 ].bv_val = NULL;
+       add_val[ 1 ].bv_len = 0;
+
+       ad = NULL;
+       rc = slap_str2ad( at_name, &ad, &text );
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
+                       "failed to find AttributeDescription for '%s'\n",
+                       at_name, 0, 0 );
+               return 0;
+       }
+
+       rc = attr_merge( e, ad, add_val );
+
+       if ( rc != 0 ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
+                       "failed to merge value '%s' for attribute '%s'\n",
+                       at_val, at_name, 0 );
+               return 0;
+       }
+       
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_query_addattr()\n", 0, 0, 0 );
+       return 1;
 }
 
-char* backsql_get_table_spec(char **p)
+char *
+backsql_get_table_spec( char **p )
 {
- char *s,*q;
- char *res=NULL;
- int res_len=0;
-
- s=*p;
- while(**p && **p!=',') (*p)++;
- if (**p)
-  *(*p)++='\0';
-
+       char            *s, *q;
+       struct berval   res = { 0, NULL };
+       int             res_len = 0;
+
+       s = *p;
+       while ( **p && **p != ',' ) {
+               (*p)++;
+       }
+
+       if ( **p ) {
+               *(*p)++ = '\0';
+       }
+       
 #define BACKSQL_NEXT_WORD { \
-  while (*s && isspace((unsigned char)*s)) s++; \
-  if (!*s) return res; \
-  q=s; \
-  while (*q && !isspace((unsigned char)*q)) q++; \
-  if (*q) *q++='\0'; \
- }
-
- BACKSQL_NEXT_WORD;
- res=backsql_strcat(res,&res_len,s,NULL);/*table name*/
- s=q;
-
- BACKSQL_NEXT_WORD;
- if (!strcasecmp(s,"as"))
- {
-  s=q;
-  BACKSQL_NEXT_WORD;
- }
- /*res=backsql_strcat(res,&res_len," AS ",s,NULL);
-  *oracle doesn't understand AS :(
-  */
- res=backsql_strcat(res,&res_len," ",s,NULL);/*table alias*/
- return res;
+               while ( *s && isspace( (unsigned char)*s ) ) s++; \
+               if ( !*s ) return res.bv_val; \
+               q = s; \
+               while ( *q && !isspace( (unsigned char)*q ) ) q++; \
+               if ( *q ) *q++='\0'; \
+       }
+
+       BACKSQL_NEXT_WORD;
+       /* table name */
+       backsql_strcat( &res, &res_len, s, NULL );
+       s = q;
+
+       BACKSQL_NEXT_WORD;
+       if ( !strcasecmp( s, "as" ) ) {
+               s = q;
+               BACKSQL_NEXT_WORD;
+       }
+#if 0
+       backsql_strcat( &res, &res_len, " AS ", s, NULL );
+       /* oracle doesn't understand AS :( */
+#endif
+       /* table alias */
+       backsql_strcat( &res, &res_len, " ", s, NULL);
+       return res.bv_val;
 }
 
-int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from)
+int
+backsql_merge_from_clause( char **dest_from, int *dest_len, char *src_from )
 {
- 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
-       if((pos=strstr(*dest_from,s))==NULL)
-     *dest_from=backsql_strcat(*dest_from,dest_len,",",s,NULL);
-    else if((e=pos[strlen(s)])!='\0' && e!=',')
-      *dest_from=backsql_strcat(*dest_from,dest_len,",",s,NULL);
-  if (s)
-       ch_free(s);
- }
-/* Debug(LDAP_DEBUG_TRACE,"<==backsql_merge_from_clause()\n",0,0,0);*/
- free(srcc);
- return 1;
+       char            *s, *p, *srcc, *pos, e;
+       struct berval   res = { 0 , NULL };
+
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "==>backsql_merge_from_clause(): "
+               "dest_from='%s',src_from='%s'\n",
+               dest_from, src_from, 0 );
+#endif
+       srcc = ch_strdup( src_from );
+       p = srcc;
+
+       if ( *dest_from != NULL ) {
+               res.bv_val = *dest_from;
+               res.bv_len = strlen( *dest_from );
+       }
+       
+       while ( *p ) {
+               s = backsql_get_table_spec( &p );
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "backsql_merge_from_clause(): "
+                       "p='%s' s='%s'\n", p, s, 0 );
+#endif
+               if ( res.bv_val == NULL ) {
+                       backsql_strcat( &res, dest_len, s, NULL );
+
+               } else {
+                       pos = strstr( res.bv_val, s );
+                       if ( pos == NULL ) {
+                               backsql_strcat( &res, dest_len, ",", s, NULL );
+                       } else if ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) {
+                               backsql_strcat( &res, dest_len, ",", s, NULL );
+                       }
+               }
+               
+               if ( s ) {
+                       ch_free( s );
+               }
+       }
+#if 0
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_merge_from_clause()\n", 0, 0, 0 );
+#endif
+       free( srcc );
+       *dest_from = res.bv_val;
+
+       return 1;
 }
 
 #endif /* SLAPD_SQL */
+
index d75eba3799ef2f7f5dcca833680515ae7c43a5e2..baa600af3283dd2bcfa1dfdc16ab645f1884ff93 100644 (file)
 
 #define BACKSQL_STR_GROW 64
 
-char* backsql_strcat(char* dest,int *buflen, ...);
+struct berval *backsql_strcat( struct berval *dest, int *buflen, ... );
 
-int backsql_entry_addattr(Entry *e,char *at_name,char *at_val,unsigned int at_val_len);
+int backsql_entry_addattr( Entry *e, char *at_name, char *at_val,
+               unsigned int at_val_len );
 
-typedef struct __backsql_srch_info
-{
- char *base_dn;
- int scope;
- Filter *filter;
- int slimit,tlimit;
- time_t        stoptime;
- backsql_entryID *id_list,*c_eid;
- int abandon;
- backsql_info *bi;
- backsql_oc_map_rec *oc;
- char *sel,*from,*join_where,*flt_where;
- int sel_len,from_len,jwhere_len,fwhere_len;
- SQLHDBC dbh;
- int status;
- Backend *be;
- Connection *conn;
- Operation *op;
- char **attrs;
- Entry *e;
- int isTimesTen; /* 1 if the db is TimesTen; 0 if it's not */
-}backsql_srch_info;
+typedef struct __backsql_srch_info {
+       struct berval           *base_dn;
+       int                     scope;
+       Filter                  *filter;
+       int                     slimit, tlimit;
+       time_t                  stoptime;
+       backsql_entryID         *id_list, *c_eid;
+       int                     n_candidates;
+       int                     abandon;
+       backsql_info            *bi;
+       backsql_oc_map_rec      *oc;
+       struct berval           sel, from, join_where, flt_where;
+       int                     sel_len, from_len, jwhere_len, fwhere_len;
+       SQLHDBC                 dbh;
+       int                     status;
+       Backend                 *be;
+       Connection              *conn;
+       Operation               *op;
+       char                    **attrs;
+       Entry                   *e;
+       /* 1 if the db is TimesTen; 0 if it's not */
+       int                     isTimesTen; 
+} backsql_srch_info;
 
-int backsql_process_filter(backsql_srch_info *bsi,Filter *f);
-void backsql_init_search(backsql_srch_info *bsi,backsql_info *bi,char *nbase,int scope,
-                                                int slimit,int tlimit,time_t stoptime,Filter *filter,
-                                                SQLHDBC dbh,Backend *be,Connection *conn,Operation *op,struct berval **attrs);
-Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* id);
+int backsql_process_filter( backsql_srch_info *bsi, Filter *f );
+void backsql_init_search( backsql_srch_info *bsi, backsql_info *bi,
+               struct berval *nbase, int scope, int slimit, int tlimit,
+               time_t stoptime, Filter *filter, SQLHDBC dbh,
+               BackendDB *be, Connection *conn, Operation *op,
+               AttributeName *attrs );
+Entry *backsql_id2entry( backsql_srch_info *bsi, Entry *e, 
+               backsql_entryID *id );
 
-extern char backsql_def_oc_query[],backsql_def_at_query[],
-                       backsql_def_delentry_query[],backsql_def_insentry_query[],
-                       backsql_def_subtree_cond[],backsql_id_query[];
-extern char backsql_check_dn_ru_query[];
+extern char 
+       backsql_def_oc_query[],
+       backsql_def_at_query[],
+       backsql_def_delentry_query[],
+       backsql_def_insentry_query[],
+       backsql_def_subtree_cond[],
+       backsql_def_upper_subtree_cond[],
+       backsql_id_query[];
+extern char 
+       backsql_check_dn_ru_query[];
 
-int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from);
+int backsql_merge_from_clause( char **dest_from, int *dest_len, 
+               char *src_from );
 
 
-#endif
+#endif /* __BACKSQL_UTIL_H__ */