]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ndb/config.cpp
Happy New Year
[openldap] / servers / slapd / back-ndb / config.cpp
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-2018 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 }