Back to index

openldap  2.4.31
operational.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1999-2012 The OpenLDAP Foundation.
00005  * Portions Copyright 1999 Dmitry Kovalev.
00006  * Portions Copyright 2002 Pierangelo Masarati.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted only as authorized by the OpenLDAP
00011  * Public License.
00012  *
00013  * A copy of this license is available in the file LICENSE in the
00014  * top-level directory of the distribution or, alternatively, at
00015  * <http://www.OpenLDAP.org/license.html>.
00016  */
00017 /* ACKNOWLEDGEMENTS:
00018  * This work was initially developed by Dmitry Kovalev for inclusion
00019  * by OpenLDAP Software.  Additional significant contributors include
00020  * Pierangelo Masarati.
00021  */
00022 
00023 #include "portable.h"
00024 
00025 #include <stdio.h>
00026 #include <sys/types.h>
00027 
00028 #include "slap.h"
00029 #include "proto-sql.h"
00030 #include "lutil.h"
00031 
00032 /*
00033  * sets the supported operational attributes (if required)
00034  */
00035 
00036 Attribute *
00037 backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id )
00038 {
00039        int                  rc;
00040        struct berval        val, nval;
00041        AttributeDescription *desc = slap_schema.si_ad_entryUUID;
00042        Attribute            *a;
00043 
00044        backsql_entryUUID( bi, id, &val, NULL );
00045 
00046        rc = (*desc->ad_type->sat_equality->smr_normalize)(
00047                      SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
00048                      desc->ad_type->sat_syntax,
00049                      desc->ad_type->sat_equality,
00050                      &val, &nval, NULL );
00051        if ( rc != LDAP_SUCCESS ) {
00052               ber_memfree( val.bv_val );
00053               return NULL;
00054        }
00055 
00056        a = attr_alloc( desc );
00057 
00058        a->a_numvals = 1;
00059        a->a_vals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
00060        a->a_vals[ 0 ] = val;
00061        BER_BVZERO( &a->a_vals[ 1 ] );
00062 
00063        a->a_nvals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
00064        a->a_nvals[ 0 ] = nval;
00065        BER_BVZERO( &a->a_nvals[ 1 ] );
00066 
00067        return a;
00068 }
00069 
00070 Attribute *
00071 backsql_operational_entryCSN( Operation *op )
00072 {
00073        char          csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];
00074        struct berval entryCSN;
00075        Attribute     *a;
00076 
00077        a = attr_alloc( slap_schema.si_ad_entryCSN );
00078        a->a_numvals = 1;
00079        a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
00080        BER_BVZERO( &a->a_vals[ 1 ] );
00081 
00082 #ifdef BACKSQL_SYNCPROV
00083        if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH && op->o_private != NULL ) {
00084               assert( op->o_private != NULL );
00085 
00086               entryCSN = *((struct berval *)op->o_private);
00087 
00088        } else
00089 #endif /* BACKSQL_SYNCPROV */
00090        {
00091               entryCSN.bv_val = csnbuf;
00092               entryCSN.bv_len = sizeof( csnbuf );
00093               slap_get_csn( op, &entryCSN, 0 );
00094        }
00095 
00096        ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
00097 
00098        a->a_nvals = a->a_vals;
00099 
00100        return a;
00101 }
00102 
00103 int
00104 backsql_operational(
00105        Operation     *op,
00106        SlapReply     *rs )
00107 {
00108 
00109        backsql_info  *bi = (backsql_info*)op->o_bd->be_private;
00110        SQLHDBC       dbh = SQL_NULL_HDBC;
00111        int           rc = 0;
00112        Attribute     **ap;
00113        enum {
00114               BACKSQL_OP_HASSUBORDINATES = 0,
00115               BACKSQL_OP_ENTRYUUID,
00116               BACKSQL_OP_ENTRYCSN,
00117 
00118               BACKSQL_OP_LAST
00119        };
00120        int           get_conn = BACKSQL_OP_LAST,
00121                      got[ BACKSQL_OP_LAST ] = { 0 };
00122 
00123        Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry \"%s\"\n",
00124                      rs->sr_entry->e_nname.bv_val, 0, 0 );
00125 
00126        for ( ap = &rs->sr_entry->e_attrs; *ap; ap = &(*ap)->a_next ) {
00127               if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) {
00128                      get_conn--;
00129                      got[ BACKSQL_OP_HASSUBORDINATES ] = 1;
00130 
00131               } else if ( (*ap)->a_desc == slap_schema.si_ad_entryUUID ) {
00132                      get_conn--;
00133                      got[ BACKSQL_OP_ENTRYUUID ] = 1;
00134 
00135               } else if ( (*ap)->a_desc == slap_schema.si_ad_entryCSN ) {
00136                      get_conn--;
00137                      got[ BACKSQL_OP_ENTRYCSN ] = 1;
00138               }
00139        }
00140 
00141        for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
00142               if ( !got[ BACKSQL_OP_HASSUBORDINATES ] &&
00143                      (*ap)->a_desc == slap_schema.si_ad_hasSubordinates )
00144               {
00145                      get_conn--;
00146                      got[ BACKSQL_OP_HASSUBORDINATES ] = 1;
00147 
00148               } else if ( !got[ BACKSQL_OP_ENTRYUUID ] && 
00149                      (*ap)->a_desc == slap_schema.si_ad_entryUUID )
00150               {
00151                      get_conn--;
00152                      got[ BACKSQL_OP_ENTRYUUID ] = 1;
00153 
00154               } else if ( !got[ BACKSQL_OP_ENTRYCSN ] &&
00155                      (*ap)->a_desc == slap_schema.si_ad_entryCSN )
00156               {
00157                      get_conn--;
00158                      got[ BACKSQL_OP_ENTRYCSN ] = 1;
00159               }
00160        }
00161 
00162        if ( !get_conn ) {
00163               return 0;
00164        }
00165 
00166        rc = backsql_get_db_conn( op, &dbh );
00167        if ( rc != LDAP_SUCCESS ) {
00168               Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
00169                      "could not get connection handle - exiting\n", 
00170                      0, 0, 0 );
00171               return 1;
00172        }
00173 
00174        if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) 
00175                      && !got[ BACKSQL_OP_HASSUBORDINATES ]
00176                      && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL )
00177        {
00178               rc = backsql_has_children( op, dbh, &rs->sr_entry->e_nname );
00179 
00180               switch( rc ) {
00181               case LDAP_COMPARE_TRUE:
00182               case LDAP_COMPARE_FALSE:
00183                      *ap = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
00184                      assert( *ap != NULL );
00185                      ap = &(*ap)->a_next;
00186                      rc = 0;
00187                      break;
00188 
00189               default:
00190                      Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
00191                             "has_children failed( %d)\n", rc, 0, 0 );
00192                      return 1;
00193               }
00194        }
00195 
00196        if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryUUID, rs->sr_attrs ) ) 
00197                      && !got[ BACKSQL_OP_ENTRYUUID ]
00198                      && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL )
00199        {
00200               backsql_srch_info    bsi = { 0 };
00201 
00202               rc = backsql_init_search( &bsi, &rs->sr_entry->e_nname,
00203                             LDAP_SCOPE_BASE,
00204                             (time_t)(-1), NULL, dbh, op, rs, NULL,
00205                             BACKSQL_ISF_GET_ID );
00206               if ( rc != LDAP_SUCCESS ) {
00207                      Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
00208                             "could not retrieve entry ID - no such entry\n", 
00209                             0, 0, 0 );
00210                      return 1;
00211               }
00212 
00213               *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
00214 
00215               (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
00216 
00217               if ( bsi.bsi_attrs != NULL ) {
00218                      op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
00219               }
00220 
00221               if ( *ap == NULL ) {
00222                      Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
00223                             "could not retrieve entryUUID\n", 
00224                             0, 0, 0 );
00225                      return 1;
00226               }
00227 
00228               ap = &(*ap)->a_next;
00229        }
00230 
00231        if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryCSN, rs->sr_attrs ) ) 
00232                      && !got[ BACKSQL_OP_ENTRYCSN ]
00233                      && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN ) == NULL )
00234        {
00235               *ap = backsql_operational_entryCSN( op );
00236               if ( *ap == NULL ) {
00237                      Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
00238                             "could not retrieve entryCSN\n", 
00239                             0, 0, 0 );
00240                      return 1;
00241               }
00242 
00243               ap = &(*ap)->a_next;
00244        }
00245 
00246        Debug( LDAP_DEBUG_TRACE, "<==backsql_operational(%d)\n", rc, 0, 0);
00247 
00248        return rc;
00249 }
00250