config.cpp revision 1.1.1.5
1/* config.cpp - ndb backend configuration file routine */
2/* $OpenLDAP$ */
3/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 *
5 * Copyright 2008-2017 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
28extern "C" {
29	static ConfigDriver ndb_cf_gen;
30};
31
32enum {
33	NDB_ATLEN = 1,
34	NDB_ATSET,
35	NDB_INDEX,
36	NDB_ATBLOB
37};
38
39static 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
115static 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
129static int
130ndb_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
327extern "C"
328int ndb_back_init_cf( BackendInfo *bi )
329{
330	bi->bi_cf_ocs = ndbocs;
331
332	return config_register_schema( ndbcfg, ndbocs );
333}
334