예제 #1
0
static int
ndb_cf_gen( ConfigArgs *c )
{
	struct ndb_info *ni = (struct ndb_info *)c->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; i<oci->no_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;
}
예제 #2
0
static int
ndb_db_open( BackendDB *be, ConfigReply *cr )
{
	struct ndb_info *ni = (struct ndb_info *) be->be_private;
	char sqlbuf[BUFSIZ], *ptr;
	int rc, i;

	if ( be->be_suffix == NULL ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: need suffix" );
		Debug( LDAP_DEBUG_ANY, "%s\n",
			cr->msg, 0, 0 );
		return -1;
	}

	Debug( LDAP_DEBUG_ARGS,
		LDAP_XSTRING(ndb_db_open) ": \"%s\"\n",
		be->be_suffix[0].bv_val, 0, 0 );

	if ( ni->ni_nconns < 1 )
		ni->ni_nconns = 1;

	ni->ni_cluster = (Ndb_cluster_connection **)ch_calloc( ni->ni_nconns, sizeof( Ndb_cluster_connection *));
	for ( i=0; i<ni->ni_nconns; i++ ) {
		ni->ni_cluster[i] = new Ndb_cluster_connection( ni->ni_connectstr );
		rc = ni->ni_cluster[i]->connect( 20, 5, 1 );
		if ( rc ) {
			snprintf( cr->msg, sizeof( cr->msg ),
				"ndb_db_open: ni_cluster[%d]->connect failed (%d)",
				i, rc );
			goto fail;
		}
	}
	for ( i=0; i<ni->ni_nconns; i++ ) {
		rc = ni->ni_cluster[i]->wait_until_ready( 30, 30 );
		if ( rc ) {
			snprintf( cr->msg, sizeof( cr->msg ),
				"ndb_db_open: ni_cluster[%d]->wait failed (%d)",
				i, rc );
			goto fail;
		}
	}

	mysql_init( &ni->ni_sql );
	if ( !mysql_real_connect( &ni->ni_sql, ni->ni_hostname, ni->ni_username, ni->ni_password,
		"", ni->ni_port, ni->ni_socket, ni->ni_clflag )) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: mysql_real_connect failed, %s (%d)",
			mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		rc = -1;
		goto fail;
	}

	sprintf( sqlbuf, "CREATE DATABASE IF NOT EXISTS %s", ni->ni_dbname );
	rc = mysql_query( &ni->ni_sql, sqlbuf );
	if ( rc ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: CREATE DATABASE %s failed, %s (%d)",
			ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		goto fail;
	}

	sprintf( sqlbuf, "USE %s", ni->ni_dbname );
	rc = mysql_query( &ni->ni_sql, sqlbuf );
	if ( rc ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: USE DATABASE %s failed, %s (%d)",
			ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		goto fail;
	}

	ptr = sqlbuf;
	ptr += sprintf( ptr, "CREATE TABLE IF NOT EXISTS " DN2ID_TABLE " ("
		"eid bigint unsigned NOT NULL, "
		"object_classes VARCHAR(1024) NOT NULL, "
		"a0 VARCHAR(128) NOT NULL DEFAULT '', "
		"a1 VARCHAR(128) NOT NULL DEFAULT '', "
		"a2 VARCHAR(128) NOT NULL DEFAULT '', "
		"a3 VARCHAR(128) NOT NULL DEFAULT '', "
		"a4 VARCHAR(128) NOT NULL DEFAULT '', "
		"a5 VARCHAR(128) NOT NULL DEFAULT '', "
		"a6 VARCHAR(128) NOT NULL DEFAULT '', "
		"a7 VARCHAR(128) NOT NULL DEFAULT '', "
		"a8 VARCHAR(128) NOT NULL DEFAULT '', "
		"a9 VARCHAR(128) NOT NULL DEFAULT '', "
		"a10 VARCHAR(128) NOT NULL DEFAULT '', "
		"a11 VARCHAR(128) NOT NULL DEFAULT '', "
		"a12 VARCHAR(128) NOT NULL DEFAULT '', "
		"a13 VARCHAR(128) NOT NULL DEFAULT '', "
		"a14 VARCHAR(128) NOT NULL DEFAULT '', "
		"a15 VARCHAR(128) NOT NULL DEFAULT '', "
		"PRIMARY KEY (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15), "
		"UNIQUE KEY eid (eid) USING HASH" );
	/* Create index columns */
	if ( ni->ni_attridxs ) {
		ListNode *ln;
		int newcol = 0;

		*ptr++ = ',';
		*ptr++ = ' ';
		for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
			NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data;
			ptr += sprintf( ptr, "`%s` VARCHAR(%d), ",
				ai->na_name.bv_val, ai->na_len );
		}
		ptr = lutil_strcopy(ptr, "KEY " INDEX_NAME " (" );

		for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
			NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data;
			if ( newcol ) *ptr++ = ',';
			*ptr++ = '`';
			ptr = lutil_strcopy( ptr, ai->na_name.bv_val );
			*ptr++ = '`';
			ai->na_ixcol = newcol + 18;
			newcol++;
		}
		*ptr++ = ')';
	}
	strcpy( ptr, ") ENGINE=ndb" );
	rc = mysql_query( &ni->ni_sql, sqlbuf );
	if ( rc ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: CREATE TABLE " DN2ID_TABLE " failed, %s (%d)",
			mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		goto fail;
	}

	rc = mysql_query( &ni->ni_sql, "CREATE TABLE IF NOT EXISTS " NEXTID_TABLE " ("
		"a bigint unsigned AUTO_INCREMENT PRIMARY KEY ) ENGINE=ndb" );
	if ( rc ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: CREATE TABLE " NEXTID_TABLE " failed, %s (%d)",
			mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		goto fail;
	}

	{
		NdbOcInfo *oci;

		rc = ndb_aset_get( ni, &ndb_optable, ndb_opattrs, &oci );
		if ( rc ) {
			snprintf( cr->msg, sizeof( cr->msg ),
				"ndb_db_open: ndb_aset_get( %s ) failed (%d)",
				ndb_optable.bv_val, rc );
			goto fail;
		}
		for ( i=0; ndb_oplens[i] >= 0; i++ ) {
			if ( ndb_oplens[i] )
				oci->no_attrs[i]->na_len = ndb_oplens[i];
		}
		rc = ndb_aset_create( ni, oci );
		if ( rc ) {
			snprintf( cr->msg, sizeof( cr->msg ),
				"ndb_db_open: ndb_aset_create( %s ) failed (%d)",
				ndb_optable.bv_val, rc );
			goto fail;
		}
		ni->ni_opattrs = oci;
	}
	/* Create attribute sets */
	{
		ListNode *ln;

		for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) {
			NdbOcInfo *oci = (NdbOcInfo *)ln->ln_data;
			rc = ndb_aset_create( ni, oci );
			if ( rc ) {
				snprintf( cr->msg, sizeof( cr->msg ),
					"ndb_db_open: ndb_aset_create( %s ) failed (%d)",
					oci->no_name.bv_val, rc );
				goto fail;
			}
		}
	}
	/* Initialize any currently used objectClasses */
	{
		Ndb *ndb;
		const NdbDictionary::Dictionary *myDict;

		ndb = new Ndb( ni->ni_cluster[0], ni->ni_dbname );
		ndb->init(1024);

		myDict = ndb->getDictionary();
		ndb_oc_read( ni, myDict );
		delete ndb;
	}

#ifdef DO_MONITORING
	/* monitor setup */
	rc = ndb_monitor_db_open( be );
	if ( rc != 0 ) {
		goto fail;
	}
#endif

	return 0;

fail:
	Debug( LDAP_DEBUG_ANY, "%s\n",
		cr->msg, 0, 0 );
	ndb_db_close( be, NULL );
	return rc;
}