1 /* config.cpp - ndb backend configuration file routine */ 2 /* OpenLDAP: pkg/ldap/servers/slapd/back-ndb/config.cpp,v 1.3.2.3 2010/04/13 20:23:34 kurt Exp */ 3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 2008-2010 The OpenLDAP Foundation. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted only as authorized by the OpenLDAP 10 * Public License. 11 * 12 * A copy of this license is available in the file LICENSE in the 13 * top-level directory of the distribution or, alternatively, at 14 * <http://www.OpenLDAP.org/license.html>. 15 */ 16 /* ACKNOWLEDGEMENTS: 17 * This work was initially developed by Howard Chu for inclusion 18 * in OpenLDAP Software. This work was sponsored by MySQL. 19 */ 20 21 #include "portable.h" 22 #include "lutil.h" 23 24 #include "back-ndb.h" 25 26 #include "config.h" 27 28 extern "C" { 29 static ConfigDriver ndb_cf_gen; 30 }; 31 32 enum { 33 NDB_ATLEN = 1, 34 NDB_ATSET, 35 NDB_INDEX, 36 NDB_ATBLOB 37 }; 38 39 static ConfigTable ndbcfg[] = { 40 { "dbhost", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET, 41 (void *)offsetof(struct ndb_info, ni_hostname), 42 "( OLcfgDbAt:6.1 NAME 'olcDbHost' " 43 "DESC 'Hostname of SQL server' " 44 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, 45 { "dbname", "name", 2, 2, 0, ARG_STRING|ARG_OFFSET, 46 (void *)offsetof(struct ndb_info, ni_dbname), 47 "( OLcfgDbAt:6.2 NAME 'olcDbName' " 48 "DESC 'Name of SQL database' " 49 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, 50 { "dbuser", "username", 2, 2, 0, ARG_STRING|ARG_OFFSET, 51 (void *)offsetof(struct ndb_info, ni_username), 52 "( OLcfgDbAt:6.3 NAME 'olcDbUser' " 53 "DESC 'Username for SQL session' " 54 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, 55 { "dbpass", "password", 2, 2, 0, ARG_STRING|ARG_OFFSET, 56 (void *)offsetof(struct ndb_info, ni_password), 57 "( OLcfgDbAt:6.4 NAME 'olcDbPass' " 58 "DESC 'Password for SQL session' " 59 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, 60 { "dbport", "port", 2, 2, 0, ARG_UINT|ARG_OFFSET, 61 (void *)offsetof(struct ndb_info, ni_port), 62 "( OLcfgDbAt:6.5 NAME 'olcDbPort' " 63 "DESC 'Port number of SQL server' " 64 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, 65 { "dbsocket", "path", 2, 2, 0, ARG_STRING|ARG_OFFSET, 66 (void *)offsetof(struct ndb_info, ni_socket), 67 "( OLcfgDbAt:6.6 NAME 'olcDbSocket' " 68 "DESC 'Local socket path of SQL server' " 69 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, 70 { "dbflag", "flag", 2, 2, 0, ARG_LONG|ARG_OFFSET, 71 (void *)offsetof(struct ndb_info, ni_clflag), 72 "( OLcfgDbAt:6.7 NAME 'olcDbFlag' " 73 "DESC 'Flags for SQL session' " 74 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, 75 { "dbconnect", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET, 76 (void *)offsetof(struct ndb_info, ni_connectstr), 77 "( OLcfgDbAt:6.8 NAME 'olcDbConnect' " 78 "DESC 'Hostname of NDB server' " 79 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, 80 { "dbconnections", "number", 2, 2, 0, ARG_INT|ARG_OFFSET, 81 (void *)offsetof(struct ndb_info, ni_nconns), 82 "( OLcfgDbAt:6.9 NAME 'olcDbConnections' " 83 "DESC 'Number of cluster connections to open' " 84 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, 85 { "attrlen", "attr> <len", 3, 3, 0, ARG_MAGIC|NDB_ATLEN, 86 (void *)ndb_cf_gen, 87 "( OLcfgDbAt:6.10 NAME 'olcNdbAttrLen' " 88 "DESC 'Column length of a specific attribute' " 89 "EQUALITY caseIgnoreMatch " 90 "SYNTAX OMsDirectoryString )", NULL, NULL }, 91 { "attrset", "set> <attrs", 3, 3, 0, ARG_MAGIC|NDB_ATSET, 92 (void *)ndb_cf_gen, 93 "( OLcfgDbAt:6.11 NAME 'olcNdbAttrSet' " 94 "DESC 'Set of common attributes' " 95 "EQUALITY caseIgnoreMatch " 96 "SYNTAX OMsDirectoryString )", NULL, NULL }, 97 { "index", "attr", 2, 2, 0, ARG_MAGIC|NDB_INDEX, 98 (void *)ndb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' " 99 "DESC 'Attribute to index' " 100 "EQUALITY caseIgnoreMatch " 101 "SYNTAX OMsDirectoryString )", NULL, NULL }, 102 { "attrblob", "attr", 2, 2, 0, ARG_MAGIC|NDB_ATBLOB, 103 (void *)ndb_cf_gen, "( OLcfgDbAt:6.12 NAME 'olcNdbAttrBlob' " 104 "DESC 'Attribute to treat as a BLOB' " 105 "EQUALITY caseIgnoreMatch " 106 "SYNTAX OMsDirectoryString )", NULL, NULL }, 107 { "directory", "dir", 2, 2, 0, ARG_IGNORED, 108 NULL, "( OLcfgDbAt:0.1 NAME 'olcDbDirectory' " 109 "DESC 'Dummy keyword' " 110 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, 111 { NULL, NULL, 0, 0, 0, ARG_IGNORED, 112 NULL, NULL, NULL, NULL } 113 }; 114 115 static ConfigOCs ndbocs[] = { 116 { 117 "( OLcfgDbOc:6.2 " 118 "NAME 'olcNdbConfig' " 119 "DESC 'NDB backend configuration' " 120 "SUP olcDatabaseConfig " 121 "MUST ( olcDbHost $ olcDbName $ olcDbConnect ) " 122 "MAY ( olcDbUser $ olcDbPass $ olcDbPort $ olcDbSocket $ " 123 "olcDbFlag $ olcDbConnections $ olcNdbAttrLen $ " 124 "olcDbIndex $ olcNdbAttrSet $ olcNdbAttrBlob ) )", 125 Cft_Database, ndbcfg }, 126 { NULL, Cft_Abstract, NULL } 127 }; 128 129 static int 130 ndb_cf_gen( ConfigArgs *c ) 131 { 132 struct ndb_info *ni = (struct ndb_info *)c->be->be_private; 133 int i, rc; 134 NdbAttrInfo *ai; 135 NdbOcInfo *oci; 136 ListNode *ln, **l2; 137 struct berval bv, *bva; 138 139 if ( c->op == SLAP_CONFIG_EMIT ) { 140 char buf[BUFSIZ]; 141 rc = 0; 142 bv.bv_val = buf; 143 switch( c->type ) { 144 case NDB_ATLEN: 145 if ( ni->ni_attrlens ) { 146 for ( ln = ni->ni_attrlens; ln; ln=ln->ln_next ) { 147 ai = (NdbAttrInfo *)ln->ln_data; 148 bv.bv_len = snprintf( buf, sizeof(buf), 149 "%s %d", ai->na_name.bv_val, 150 ai->na_len ); 151 value_add_one( &c->rvalue_vals, &bv ); 152 } 153 } else { 154 rc = 1; 155 } 156 break; 157 158 case NDB_ATSET: 159 if ( ni->ni_attrsets ) { 160 char *ptr, *end = buf+sizeof(buf); 161 for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) { 162 oci = (NdbOcInfo *)ln->ln_data; 163 ptr = lutil_strcopy( buf, oci->no_name.bv_val ); 164 *ptr++ = ' '; 165 for ( i=0; i<oci->no_nattrs; i++ ) { 166 if ( end - ptr < oci->no_attrs[i]->na_name.bv_len+1 ) 167 break; 168 if ( i ) 169 *ptr++ = ','; 170 ptr = lutil_strcopy(ptr, 171 oci->no_attrs[i]->na_name.bv_val ); 172 } 173 bv.bv_len = ptr - buf; 174 value_add_one( &c->rvalue_vals, &bv ); 175 } 176 } else { 177 rc = 1; 178 } 179 break; 180 181 case NDB_INDEX: 182 if ( ni->ni_attridxs ) { 183 for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) { 184 ai = (NdbAttrInfo *)ln->ln_data; 185 value_add_one( &c->rvalue_vals, &ai->na_name ); 186 } 187 } else { 188 rc = 1; 189 } 190 break; 191 192 case NDB_ATBLOB: 193 if ( ni->ni_attrblobs ) { 194 for ( ln = ni->ni_attrblobs; ln; ln=ln->ln_next ) { 195 ai = (NdbAttrInfo *)ln->ln_data; 196 value_add_one( &c->rvalue_vals, &ai->na_name ); 197 } 198 } else { 199 rc = 1; 200 } 201 break; 202 203 } 204 return rc; 205 } else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */ 206 rc = 0; 207 switch( c->type ) { 208 case NDB_INDEX: 209 if ( c->valx == -1 ) { 210 211 /* delete all */ 212 213 } else { 214 215 } 216 break; 217 } 218 return rc; 219 } 220 221 switch( c->type ) { 222 case NDB_ATLEN: 223 ber_str2bv( c->argv[1], 0, 0, &bv ); 224 ai = ndb_ai_get( ni, &bv ); 225 if ( !ai ) { 226 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", 227 c->log, c->argv[1] ); 228 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); 229 return -1; 230 } 231 for ( ln = ni->ni_attrlens; ln; ln = ln->ln_next ) { 232 if ( ln->ln_data == (void *)ai ) { 233 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr len already set for %s", 234 c->log, c->argv[1] ); 235 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); 236 return -1; 237 } 238 } 239 ai->na_len = atoi( c->argv[2] ); 240 ai->na_flag |= NDB_INFO_ATLEN; 241 ln = (ListNode *)ch_malloc( sizeof(ListNode)); 242 ln->ln_data = ai; 243 ln->ln_next = NULL; 244 for ( l2 = &ni->ni_attrlens; *l2; l2 = &(*l2)->ln_next ); 245 *l2 = ln; 246 break; 247 248 case NDB_INDEX: 249 ber_str2bv( c->argv[1], 0, 0, &bv ); 250 ai = ndb_ai_get( ni, &bv ); 251 if ( !ai ) { 252 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", 253 c->log, c->argv[1] ); 254 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); 255 return -1; 256 } 257 for ( ln = ni->ni_attridxs; ln; ln = ln->ln_next ) { 258 if ( ln->ln_data == (void *)ai ) { 259 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr index already set for %s", 260 c->log, c->argv[1] ); 261 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); 262 return -1; 263 } 264 } 265 ai->na_flag |= NDB_INFO_INDEX; 266 ln = (ListNode *)ch_malloc( sizeof(ListNode)); 267 ln->ln_data = ai; 268 ln->ln_next = NULL; 269 for ( l2 = &ni->ni_attridxs; *l2; l2 = &(*l2)->ln_next ); 270 *l2 = ln; 271 break; 272 273 case NDB_ATSET: 274 ber_str2bv( c->argv[1], 0, 0, &bv ); 275 bva = ndb_str2bvarray( c->argv[2], strlen( c->argv[2] ), ',', NULL ); 276 rc = ndb_aset_get( ni, &bv, bva, &oci ); 277 ber_bvarray_free( bva ); 278 if ( rc ) { 279 if ( rc == LDAP_ALREADY_EXISTS ) { 280 snprintf( c->cr_msg, sizeof( c->cr_msg ), 281 "%s: attrset %s already defined", 282 c->log, c->argv[1] ); 283 } else { 284 snprintf( c->cr_msg, sizeof( c->cr_msg ), 285 "%s: invalid attrset %s (%d)", 286 c->log, c->argv[1], rc ); 287 } 288 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); 289 return -1; 290 } 291 ln = (ListNode *)ch_malloc( sizeof(ListNode)); 292 ln->ln_data = oci; 293 ln->ln_next = NULL; 294 for ( l2 = &ni->ni_attrsets; *l2; l2 = &(*l2)->ln_next ); 295 *l2 = ln; 296 break; 297 298 case NDB_ATBLOB: 299 ber_str2bv( c->argv[1], 0, 0, &bv ); 300 ai = ndb_ai_get( ni, &bv ); 301 if ( !ai ) { 302 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", 303 c->log, c->argv[1] ); 304 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); 305 return -1; 306 } 307 for ( ln = ni->ni_attrblobs; ln; ln = ln->ln_next ) { 308 if ( ln->ln_data == (void *)ai ) { 309 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr blob already set for %s", 310 c->log, c->argv[1] ); 311 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); 312 return -1; 313 } 314 } 315 ai->na_flag |= NDB_INFO_ATBLOB; 316 ln = (ListNode *)ch_malloc( sizeof(ListNode)); 317 ln->ln_data = ai; 318 ln->ln_next = NULL; 319 for ( l2 = &ni->ni_attrblobs; *l2; l2 = &(*l2)->ln_next ); 320 *l2 = ln; 321 break; 322 323 } 324 return 0; 325 } 326 327 extern "C" 328 int ndb_back_init_cf( BackendInfo *bi ) 329 { 330 bi->bi_cf_ocs = ndbocs; 331 332 return config_register_schema( ndbcfg, ndbocs ); 333 } 334