/* config.cpp - ndb backend configuration file routine */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software .
*
* Copyright 2008-2022 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* .
*/
/* ACKNOWLEDGEMENTS:
* This work was initially developed by Howard Chu for inclusion
* in OpenLDAP Software. This work was sponsored by MySQL.
*/
#include "portable.h"
#include "lutil.h"
#include "back-ndb.h"
#include "slap-config.h"
extern "C" {
static ConfigDriver ndb_cf_gen;
};
enum {
NDB_ATLEN = 1,
NDB_ATSET,
NDB_INDEX,
NDB_ATBLOB
};
static ConfigTable ndbcfg[] = {
{ "dbhost", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_hostname),
"( OLcfgDbAt:6.1 NAME 'olcDbHost' "
"DESC 'Hostname of SQL server' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "dbname", "name", 2, 2, 0, ARG_STRING|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_dbname),
"( OLcfgDbAt:6.2 NAME 'olcDbName' "
"DESC 'Name of SQL database' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "dbuser", "username", 2, 2, 0, ARG_STRING|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_username),
"( OLcfgDbAt:6.3 NAME 'olcDbUser' "
"DESC 'Username for SQL session' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "dbpass", "password", 2, 2, 0, ARG_STRING|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_password),
"( OLcfgDbAt:6.4 NAME 'olcDbPass' "
"DESC 'Password for SQL session' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "dbport", "port", 2, 2, 0, ARG_UINT|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_port),
"( OLcfgDbAt:6.5 NAME 'olcDbPort' "
"DESC 'Port number of SQL server' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "dbsocket", "path", 2, 2, 0, ARG_STRING|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_socket),
"( OLcfgDbAt:6.6 NAME 'olcDbSocket' "
"DESC 'Local socket path of SQL server' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "dbflag", "flag", 2, 2, 0, ARG_LONG|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_clflag),
"( OLcfgDbAt:6.7 NAME 'olcDbFlag' "
"DESC 'Flags for SQL session' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "dbconnect", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_connectstr),
"( OLcfgDbAt:6.8 NAME 'olcDbConnect' "
"DESC 'Hostname of NDB server' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "dbconnections", "number", 2, 2, 0, ARG_INT|ARG_OFFSET,
(void *)offsetof(struct ndb_info, ni_nconns),
"( OLcfgDbAt:6.9 NAME 'olcDbConnections' "
"DESC 'Number of cluster connections to open' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "attrlen", "attr> be->be_private;
int i, rc;
NdbAttrInfo *ai;
NdbOcInfo *oci;
ListNode *ln, **l2;
struct berval bv, *bva;
if ( c->op == SLAP_CONFIG_EMIT ) {
char buf[BUFSIZ];
rc = 0;
bv.bv_val = buf;
switch( c->type ) {
case NDB_ATLEN:
if ( ni->ni_attrlens ) {
for ( ln = ni->ni_attrlens; ln; ln=ln->ln_next ) {
ai = (NdbAttrInfo *)ln->ln_data;
bv.bv_len = snprintf( buf, sizeof(buf),
"%s %d", ai->na_name.bv_val,
ai->na_len );
value_add_one( &c->rvalue_vals, &bv );
}
} else {
rc = 1;
}
break;
case NDB_ATSET:
if ( ni->ni_attrsets ) {
char *ptr, *end = buf+sizeof(buf);
for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) {
oci = (NdbOcInfo *)ln->ln_data;
ptr = lutil_strcopy( buf, oci->no_name.bv_val );
*ptr++ = ' ';
for ( i=0; ino_nattrs; i++ ) {
if ( end - ptr < oci->no_attrs[i]->na_name.bv_len+1 )
break;
if ( i )
*ptr++ = ',';
ptr = lutil_strcopy(ptr,
oci->no_attrs[i]->na_name.bv_val );
}
bv.bv_len = ptr - buf;
value_add_one( &c->rvalue_vals, &bv );
}
} else {
rc = 1;
}
break;
case NDB_INDEX:
if ( ni->ni_attridxs ) {
for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
ai = (NdbAttrInfo *)ln->ln_data;
value_add_one( &c->rvalue_vals, &ai->na_name );
}
} else {
rc = 1;
}
break;
case NDB_ATBLOB:
if ( ni->ni_attrblobs ) {
for ( ln = ni->ni_attrblobs; ln; ln=ln->ln_next ) {
ai = (NdbAttrInfo *)ln->ln_data;
value_add_one( &c->rvalue_vals, &ai->na_name );
}
} else {
rc = 1;
}
break;
}
return rc;
} else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */
rc = 0;
switch( c->type ) {
case NDB_INDEX:
if ( c->valx == -1 ) {
/* delete all */
} else {
}
break;
}
return rc;
}
switch( c->type ) {
case NDB_ATLEN:
ber_str2bv( c->argv[1], 0, 0, &bv );
ai = ndb_ai_get( ni, &bv );
if ( !ai ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
c->log, c->argv[1] );
Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
return -1;
}
for ( ln = ni->ni_attrlens; ln; ln = ln->ln_next ) {
if ( ln->ln_data == (void *)ai ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr len already set for %s",
c->log, c->argv[1] );
Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
return -1;
}
}
ai->na_len = atoi( c->argv[2] );
ai->na_flag |= NDB_INFO_ATLEN;
ln = (ListNode *)ch_malloc( sizeof(ListNode));
ln->ln_data = ai;
ln->ln_next = NULL;
for ( l2 = &ni->ni_attrlens; *l2; l2 = &(*l2)->ln_next );
*l2 = ln;
break;
case NDB_INDEX:
ber_str2bv( c->argv[1], 0, 0, &bv );
ai = ndb_ai_get( ni, &bv );
if ( !ai ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
c->log, c->argv[1] );
Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
return -1;
}
for ( ln = ni->ni_attridxs; ln; ln = ln->ln_next ) {
if ( ln->ln_data == (void *)ai ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr index already set for %s",
c->log, c->argv[1] );
Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
return -1;
}
}
ai->na_flag |= NDB_INFO_INDEX;
ln = (ListNode *)ch_malloc( sizeof(ListNode));
ln->ln_data = ai;
ln->ln_next = NULL;
for ( l2 = &ni->ni_attridxs; *l2; l2 = &(*l2)->ln_next );
*l2 = ln;
break;
case NDB_ATSET:
ber_str2bv( c->argv[1], 0, 0, &bv );
bva = ndb_str2bvarray( c->argv[2], strlen( c->argv[2] ), ',', NULL );
rc = ndb_aset_get( ni, &bv, bva, &oci );
ber_bvarray_free( bva );
if ( rc ) {
if ( rc == LDAP_ALREADY_EXISTS ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"%s: attrset %s already defined",
c->log, c->argv[1] );
} else {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"%s: invalid attrset %s (%d)",
c->log, c->argv[1], rc );
}
Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
return -1;
}
ln = (ListNode *)ch_malloc( sizeof(ListNode));
ln->ln_data = oci;
ln->ln_next = NULL;
for ( l2 = &ni->ni_attrsets; *l2; l2 = &(*l2)->ln_next );
*l2 = ln;
break;
case NDB_ATBLOB:
ber_str2bv( c->argv[1], 0, 0, &bv );
ai = ndb_ai_get( ni, &bv );
if ( !ai ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
c->log, c->argv[1] );
Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
return -1;
}
for ( ln = ni->ni_attrblobs; ln; ln = ln->ln_next ) {
if ( ln->ln_data == (void *)ai ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr blob already set for %s",
c->log, c->argv[1] );
Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
return -1;
}
}
ai->na_flag |= NDB_INFO_ATBLOB;
ln = (ListNode *)ch_malloc( sizeof(ListNode));
ln->ln_data = ai;
ln->ln_next = NULL;
for ( l2 = &ni->ni_attrblobs; *l2; l2 = &(*l2)->ln_next );
*l2 = ln;
break;
}
return 0;
}
extern "C"
int ndb_back_init_cf( BackendInfo *bi )
{
bi->bi_cf_ocs = ndbocs;
return config_register_schema( ndbcfg, ndbocs );
}