101
101
#define DNA_HOSTNAME "dnaHostname"
102
102
#define DNA_PORTNUM "dnaPortNum"
103
103
#define DNA_SECURE_PORTNUM "dnaSecurePortNum"
104
#define DNA_REMOTE_BUFSIZ 15 /* max size for bind method & protocol */
104
105
#define DNA_REMOTE_BIND_METHOD "dnaRemoteBindMethod"
105
106
#define DNA_REMOTE_CONN_PROT "dnaRemoteConnProtocol"
191
192
static PRCList *dna_global_config = NULL;
192
193
static Slapi_RWLock *g_dna_cache_lock;
195
static struct dnaServer *dna_global_servers = NULL;
196
static Slapi_RWLock *g_dna_cache_server_lock;
194
198
static void *_PluginID = NULL;
195
199
static const char *_PluginDN = NULL;
244
250
static int dna_load_plugin_config(Slapi_PBlock *pb, int use_eventq);
245
251
static int dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply);
246
static void dna_delete_config();
252
static void dna_delete_config(PRCList *list);
247
253
static void dna_free_config_entry(struct configEntry ** entry);
248
254
static int dna_load_host_port();
264
270
PRUint64 new, PRUint64 last);
265
271
static int dna_update_shared_config(struct configEntry * config_entry);
266
272
static void dna_update_config_event(time_t event_time, void *arg);
267
static int dna_get_shared_servers(struct configEntry *config_entry, PRCList **servers);
273
static int dna_get_shared_servers(struct configEntry *config_entry, PRCList **servers, int get_all);
268
274
static void dna_free_shared_server(struct dnaServer **server);
269
275
static void dna_delete_shared_servers(PRCList **servers);
270
276
static int dna_release_range(char *range_dn, PRUint64 *lower, PRUint64 *upper);
287
293
static int dna_isrepl(Slapi_PBlock *pb);
288
294
static int dna_get_remote_config_info( struct dnaServer *server, char **bind_dn, char **bind_passwd,
289
295
char **bind_method, int *is_ssl, int *port);
296
static int dna_load_shared_servers();
297
static void dna_delete_global_servers();
298
static int dna_get_shared_config_attr_val(struct configEntry *config_entry, char *attr, char *value);
299
static PRCList *dna_config_copy();
293
302
* the ops (where the real work is done)
333
* During the plugin startup we delay the creation of the shared config entries
334
* so all the other betxn plugins have time to start. During the "delayed"
335
* update config event we will need a copy of the global config, as we can not
336
* hold the read lock while starting a transaction(potential deadlock).
341
PRCList *copy = (PRCList *)slapi_ch_calloc(1, sizeof(struct configEntry));
342
PRCList *config_list;
347
if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
348
config_list = PR_LIST_HEAD(dna_global_config);
349
while (config_list != dna_global_config) {
350
struct configEntry *new_entry = (struct configEntry *)slapi_ch_calloc(1, sizeof(struct configEntry));
351
struct configEntry *config_entry = (struct configEntry *) config_list;
353
new_entry->dn = slapi_ch_strdup(config_entry->dn);
354
new_entry->types = slapi_ch_array_dup(config_entry->types);
355
new_entry->prefix = slapi_ch_strdup(config_entry->prefix);
356
new_entry->filter = slapi_ch_strdup(config_entry->filter);
357
new_entry->slapi_filter = slapi_filter_dup(config_entry->slapi_filter);
358
new_entry->generate = slapi_ch_strdup(config_entry->generate);
359
new_entry->scope = slapi_ch_strdup(config_entry->scope);
360
new_entry->shared_cfg_base = slapi_ch_strdup(config_entry->shared_cfg_base);
361
new_entry->shared_cfg_dn = slapi_ch_strdup(config_entry->shared_cfg_dn);
362
new_entry->remote_binddn = slapi_ch_strdup(config_entry->remote_binddn);
363
new_entry->remote_bindpw = slapi_ch_strdup(config_entry->remote_bindpw);
364
new_entry->timeout = config_entry->timeout;
365
new_entry->interval = config_entry->interval;
366
new_entry->threshold = config_entry->threshold;
367
new_entry->nextval = config_entry->nextval;
368
new_entry->maxval = config_entry->maxval;
369
new_entry->remaining = config_entry->remaining;
370
new_entry->extend_in_progress = config_entry->extend_in_progress;
371
new_entry->next_range_lower = config_entry->next_range_lower;
372
new_entry->next_range_upper = config_entry->next_range_upper;
373
new_entry->lock = NULL;
374
new_entry->extend_lock = NULL;
377
PR_INSERT_LINK(&(new_entry->list), copy);
380
PR_INSERT_BEFORE(&(new_entry->list), copy);
382
config_list = PR_NEXT_LINK(config_list);
325
391
* Deal with cache locking
340
406
slapi_rwlock_unlock(g_dna_cache_lock);
409
void dna_server_read_lock()
411
slapi_rwlock_rdlock(g_dna_cache_server_lock);
414
void dna_server_write_lock()
416
slapi_rwlock_wrlock(g_dna_cache_server_lock);
419
void dna_server_unlock()
421
slapi_rwlock_unlock(g_dna_cache_server_lock);
345
426
* Get the dna plug-in version
555
636
g_dna_cache_lock = slapi_new_rwlock();
557
637
if (!g_dna_cache_lock) {
558
638
slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
559
"dna_start: lock creation failed\n");
639
"dna_start: global config lock creation failed\n");
643
g_dna_cache_server_lock = slapi_new_rwlock();
644
if (!g_dna_cache_server_lock) {
645
slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
646
"dna_start: global server lock creation failed\n");
561
647
return DNA_FAILURE;
604
690
g_plugin_started = 1;
693
* Load all shared server configs
695
if (dna_load_shared_servers() ) {
696
slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
697
"dna_start: shared config server initialization failed.\n");
605
701
slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
606
702
"dna: ready for service\n");
607
703
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
629
725
dna_write_lock();
630
726
g_plugin_started = 0;
727
dna_delete_config(NULL);
634
728
slapi_ch_free((void **)&dna_global_config);
731
dna_delete_global_servers();
732
slapi_destroy_rwlock(g_dna_cache_server_lock);
733
g_dna_cache_server_lock = NULL;
636
735
slapi_ch_free_string(&hostname);
637
736
slapi_ch_free_string(&portnum);
755
* Free the global linkedl ist of shared servers
758
dna_delete_global_servers()
760
struct dnaServer *server, *next;
762
if(dna_global_servers){
763
server = dna_global_servers;
766
dna_free_shared_server(&server);
769
dna_global_servers = NULL;
774
* Look through the global config entries, and build a global
775
* shared server config list.
778
dna_load_shared_servers()
780
struct configEntry *config_entry = NULL;
781
struct dnaServer *server = NULL, *global_servers = NULL;
782
PRCList *server_list = NULL;
783
PRCList *config_list = NULL;
784
int freed_servers = 0;
787
/* Now build the new list. */
789
if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
790
config_list = PR_LIST_HEAD(dna_global_config);
791
while (config_list != dna_global_config) {
792
PRCList *shared_list = NULL;
793
config_entry = (struct configEntry *) config_list;
795
if(dna_get_shared_servers(config_entry,
797
1 /* get all the servers */))
803
dna_server_write_lock();
805
dna_delete_global_servers();
809
server_list = PR_LIST_HEAD(shared_list);
810
while (server_list != shared_list) {
811
server = (struct dnaServer *)server_list;
812
if(global_servers == NULL){
813
dna_global_servers = global_servers = server;
815
global_servers->next = server;
816
global_servers = server;
818
server_list = PR_NEXT_LINK(server_list);
820
slapi_ch_free((void **)&shared_list);
824
config_list = PR_NEXT_LINK(config_list);
656
833
* config looks like this
1416
dna_delete_config(PRCList *list)
1418
PRCList *list_entry, *delete_list;
1243
while (!PR_CLIST_IS_EMPTY(dna_global_config)) {
1244
list = PR_LIST_HEAD(dna_global_config);
1245
dna_delete_configEntry(list);
1423
delete_list = dna_global_config;
1425
while (!PR_CLIST_IS_EMPTY(delete_list)) {
1426
list_entry = PR_LIST_HEAD(delete_list);
1427
dna_delete_configEntry(list_entry);
1324
1507
* Event queue callback that we use to do the initial
1325
1508
* update of the shared config entries shortly after
1511
* Since we need to start a backend transaction, a copy/snapshot of the global
1512
* config is used, and then freed.
1329
1515
dna_update_config_event(time_t event_time, void *arg)
1331
1517
Slapi_PBlock *pb = NULL;
1332
1518
struct configEntry *config_entry = NULL;
1333
PRCList *list = NULL;
1519
PRCList *copy = NULL, *list = NULL;
1335
/* Get read lock to prevent config changes */
1521
/* Get the read lock so we can copy the config */
1336
1522
dna_read_lock();
1338
1524
/* Bail out if the plug-in close function was just called. */
1343
/* Loop through all config entries and update the shared
1344
* config entries. */
1529
/* Loop through all config entries and update the shared config entries. */
1345
1530
if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
1346
list = PR_LIST_HEAD(dna_global_config);
1532
* We need to use a copy of the config because we can not hold
1533
* the read lock and start a backend transaction.
1535
copy = dna_config_copy();
1348
/* Create the pblock. We'll reuse this for all
1349
* shared config updates. */
1538
/* Create the pblock. We'll reuse it for all shared config updates. */
1350
1539
if ((pb = slapi_pblock_new()) == NULL)
1353
while (list != dna_global_config) {
1542
list = PR_LIST_HEAD(copy);
1543
while (list != copy) {
1354
1544
config_entry = (struct configEntry *) list;
1356
1546
/* If a shared config dn is set, update the shared config. */
1445
1636
} else if (!skip_range_request && config_entry->shared_cfg_base) {
1446
1637
/* Find out if there are any other servers to request
1447
1638
* range from. */
1448
dna_get_shared_servers(config_entry, &servers);
1639
dna_get_shared_servers(config_entry, &servers, 0 );
1451
1642
/* We have other servers we can try to extend
1585
1776
/* We found some entries. Go through them and
1586
1777
* order them based off of remaining values. */
1587
1778
for (i = 0; entries[i]; i++) {
1588
/* skip our own shared config entry */
1589
if (slapi_sdn_compare(cfg_sdn, slapi_entry_get_sdn(entries[i]))) {
1779
/* skip our own shared config entry, unless we want all the servers */
1780
if (get_all || slapi_sdn_compare(cfg_sdn, slapi_entry_get_sdn(entries[i]))) {
1590
1781
struct dnaServer *server = NULL;
1592
1783
/* set up the server list entry */
1593
1784
server = (struct dnaServer *) slapi_ch_calloc(1,
1594
1785
sizeof(struct dnaServer));
1786
server->sdn = slapi_sdn_new_dn_byval(slapi_entry_get_ndn(entries[i]));
1595
1787
server->host = slapi_entry_attr_get_charptr(entries[i],
1597
1789
server->port = slapi_entry_attr_get_uint(entries[i], DNA_PORTNUM);
1661
1853
/* Find the right slot for this entry. We
1662
1854
* want to order the entries based off of
1663
* the remaining number of values, higest
1855
* the remaining number of values, highest
1664
1856
* to lowest. */
1665
1857
struct dnaServer *sitem;
1666
1858
PRCList* item = PR_LIST_HEAD(*servers);
2133
dna_dn_is_shared_config(Slapi_PBlock *pb, char *dn)
2135
struct configEntry *config_entry = NULL;
2136
Slapi_Entry *entry = NULL;
2137
Slapi_Attr *attr = NULL;
2138
PRCList *list = NULL;
2142
if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
2143
list = PR_LIST_HEAD(dna_global_config);
2144
while (list != dna_global_config) {
2145
config_entry = (struct configEntry *) list;
2146
if (slapi_dn_issuffix(dn, config_entry->shared_cfg_base)) {
2147
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &entry);
2148
/* If the entry has the dnaHost attribute, it is a shared entry */
2149
if (slapi_entry_attr_find(entry, DNA_HOSTNAME, &attr) == 0) {
2154
list = PR_NEXT_LINK(list);
1940
2162
#define DNA_LDAP_TAG_SK_REVERSE 0x81L
1942
2164
static LDAPControl *dna_build_sort_control(const char *attr)
2490
* Get a value from the global server list. The dna_server_read_lock()
2491
* should be held prior to calling this function.
2494
dna_get_shared_config_attr_val(struct configEntry *config_entry, char *attr, char *value)
2496
struct dnaServer *server = NULL;
2497
Slapi_DN *server_sdn = NULL;
2500
server_sdn = slapi_sdn_new_dn_byref(config_entry->shared_cfg_dn);
2501
if (dna_global_servers) {
2502
server = dna_global_servers;
2504
if(slapi_sdn_compare(server->sdn, server_sdn) == 0){
2505
if(strcmp(attr, DNA_REMOTE_BIND_METHOD) == 0){
2506
PR_snprintf(value, DNA_REMOTE_BUFSIZ, "%s", server->remote_bind_method);
2509
} else if(strcmp(attr, DNA_REMOTE_CONN_PROT) == 0){
2510
PR_snprintf(value, DNA_REMOTE_BUFSIZ, "%s", server->remote_conn_prot);
2515
server = server->next;
2518
slapi_sdn_free(&server_sdn);
2268
2523
* dna_update_shared_config()
2270
2525
* Updates the shared config entry if one is
2316
2571
* already exist, we add it. */
2317
2572
if (ret == LDAP_NO_SUCH_OBJECT) {
2318
2573
Slapi_Entry *e = NULL;
2320
slapi_sdn_new_normdn_byref(config_entry->shared_cfg_dn);
2574
Slapi_DN *sdn = slapi_sdn_new_normdn_byref(config_entry->shared_cfg_dn);
2575
char bind_meth[DNA_REMOTE_BUFSIZ];
2576
char conn_prot[DNA_REMOTE_BUFSIZ];
2322
2578
/* Set up the new shared config entry */
2323
2579
e = slapi_entry_alloc();
2334
2590
slapi_entry_add_string(e, DNA_REMAINING, remaining_vals);
2592
/* Grab the remote server settings */
2593
dna_server_read_lock();
2594
if(dna_get_shared_config_attr_val(config_entry, DNA_REMOTE_BIND_METHOD, bind_meth)) {
2595
slapi_entry_add_string(e, DNA_REMOTE_BIND_METHOD, bind_meth);
2597
if(dna_get_shared_config_attr_val(config_entry, DNA_REMOTE_CONN_PROT, conn_prot)){
2598
slapi_entry_add_string(e, DNA_REMOTE_CONN_PROT,conn_prot);
2600
dna_server_unlock();
2336
2602
/* clear pb for re-use */
2337
2603
slapi_pblock_init(pb);
3932
4198
if (dna_dn_is_config(dn)) {
3933
4199
dna_load_plugin_config(pb, 0);
4201
if(dna_dn_is_shared_config(pb, dn) == 0){
4202
dna_load_shared_servers();