From 702807607636ef3eae63c716c3e3f174b81776c3 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Feb 29 2012 18:23:28 +0000 Subject: Ticket #302 - use thread local storage for internalModifiersName & internalCreatorsName Bug Description: use thread local storage for internalModifiersName & internalCreatorsName Fix description: Created new thread local storage slapi functions for initializing, setting/getting thread local storage data in a new file thread_data.c. This was built on top of some of the changes for ticket 111. We create the index in main.c right before we start the plugins and worker threads. Then we set the bind dn in bind_credentials_set_nolock(), nad we also set the thread data when we copy the operation in op_copy_indentity so can maintian the bind dn through different threads from the same connection. For plugins that create new threads we need to pass the new thread the bind dn(char *), and then set the thread data(slapi_td_set_dn()). https://fedorahosted.org/389/ticket/302 --- diff --git a/Makefile.am b/Makefile.am index 787161d..521f4f4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -685,6 +685,7 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \ ldap/servers/slapd/subentry.c \ ldap/servers/slapd/task.c \ ldap/servers/slapd/time.c \ + ldap/servers/slapd/thread_data.c \ ldap/servers/slapd/uniqueid.c \ ldap/servers/slapd/uniqueidgen.c \ ldap/servers/slapd/utf8.c \ diff --git a/Makefile.in b/Makefile.in index fc638dc..3aaf49f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -644,12 +644,12 @@ am__libslapd_la_SOURCES_DIST = ldap/servers/slapd/add.c \ ldap/servers/slapd/snmp_collator.c ldap/servers/slapd/sort.c \ ldap/servers/slapd/ssl.c ldap/servers/slapd/str2filter.c \ ldap/servers/slapd/subentry.c ldap/servers/slapd/task.c \ - ldap/servers/slapd/time.c ldap/servers/slapd/uniqueid.c \ - ldap/servers/slapd/uniqueidgen.c ldap/servers/slapd/utf8.c \ - ldap/servers/slapd/utf8compare.c ldap/servers/slapd/util.c \ - ldap/servers/slapd/uuid.c ldap/servers/slapd/value.c \ - ldap/servers/slapd/valueset.c ldap/servers/slapd/vattr.c \ - ldap/libraries/libavl/avl.c \ + ldap/servers/slapd/time.c ldap/servers/slapd/thread_data.c \ + ldap/servers/slapd/uniqueid.c ldap/servers/slapd/uniqueidgen.c \ + ldap/servers/slapd/utf8.c ldap/servers/slapd/utf8compare.c \ + ldap/servers/slapd/util.c ldap/servers/slapd/uuid.c \ + ldap/servers/slapd/value.c ldap/servers/slapd/valueset.c \ + ldap/servers/slapd/vattr.c ldap/libraries/libavl/avl.c \ ldap/servers/slapd/slapi_counter_sunos_sparcv9.S am__objects_2 = ldap/libraries/libavl/libslapd_la-avl.lo @SOLARIS_TRUE@am__objects_3 = ldap/servers/slapd/libslapd_la-slapi_counter_sunos_sparcv9.lo @@ -737,6 +737,7 @@ am_libslapd_la_OBJECTS = ldap/servers/slapd/libslapd_la-add.lo \ ldap/servers/slapd/libslapd_la-subentry.lo \ ldap/servers/slapd/libslapd_la-task.lo \ ldap/servers/slapd/libslapd_la-time.lo \ + ldap/servers/slapd/libslapd_la-thread_data.lo \ ldap/servers/slapd/libslapd_la-uniqueid.lo \ ldap/servers/slapd/libslapd_la-uniqueidgen.lo \ ldap/servers/slapd/libslapd_la-utf8.lo \ @@ -1842,12 +1843,12 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \ ldap/servers/slapd/snmp_collator.c ldap/servers/slapd/sort.c \ ldap/servers/slapd/ssl.c ldap/servers/slapd/str2filter.c \ ldap/servers/slapd/subentry.c ldap/servers/slapd/task.c \ - ldap/servers/slapd/time.c ldap/servers/slapd/uniqueid.c \ - ldap/servers/slapd/uniqueidgen.c ldap/servers/slapd/utf8.c \ - ldap/servers/slapd/utf8compare.c ldap/servers/slapd/util.c \ - ldap/servers/slapd/uuid.c ldap/servers/slapd/value.c \ - ldap/servers/slapd/valueset.c ldap/servers/slapd/vattr.c \ - $(libavl_a_SOURCES) $(am__append_1) + ldap/servers/slapd/time.c ldap/servers/slapd/thread_data.c \ + ldap/servers/slapd/uniqueid.c ldap/servers/slapd/uniqueidgen.c \ + ldap/servers/slapd/utf8.c ldap/servers/slapd/utf8compare.c \ + ldap/servers/slapd/util.c ldap/servers/slapd/uuid.c \ + ldap/servers/slapd/value.c ldap/servers/slapd/valueset.c \ + ldap/servers/slapd/vattr.c $(libavl_a_SOURCES) $(am__append_1) libslapd_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) @sasl_inc@ @db_inc@ @svrcore_inc@ @kerberos_inc@ @pcre_inc@ libslapd_la_LIBADD = $(LDAPSDK_LINK) $(SASL_LINK) $(SVRCORE_LINK) $(NSS_LINK) $(NSPR_LINK) $(KERBEROS_LINK) $(PCRE_LINK) $(THREADLIB) @@ -4050,6 +4051,9 @@ ldap/servers/slapd/libslapd_la-task.lo: \ ldap/servers/slapd/libslapd_la-time.lo: \ ldap/servers/slapd/$(am__dirstamp) \ ldap/servers/slapd/$(DEPDIR)/$(am__dirstamp) +ldap/servers/slapd/libslapd_la-thread_data.lo: \ + ldap/servers/slapd/$(am__dirstamp) \ + ldap/servers/slapd/$(DEPDIR)/$(am__dirstamp) ldap/servers/slapd/libslapd_la-uniqueid.lo: \ ldap/servers/slapd/$(am__dirstamp) \ ldap/servers/slapd/$(DEPDIR)/$(am__dirstamp) @@ -5360,6 +5364,8 @@ mostlyclean-compile: -rm -f ldap/servers/slapd/libslapd_la-subentry.lo -rm -f ldap/servers/slapd/libslapd_la-task.$(OBJEXT) -rm -f ldap/servers/slapd/libslapd_la-task.lo + -rm -f ldap/servers/slapd/libslapd_la-thread_data.$(OBJEXT) + -rm -f ldap/servers/slapd/libslapd_la-thread_data.lo -rm -f ldap/servers/slapd/libslapd_la-time.$(OBJEXT) -rm -f ldap/servers/slapd/libslapd_la-time.lo -rm -f ldap/servers/slapd/libslapd_la-uniqueid.$(OBJEXT) @@ -5821,6 +5827,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-str2filter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-subentry.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-task.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-thread_data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-time.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-uniqueid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-uniqueidgen.Plo@am__quote@ @@ -8344,6 +8351,13 @@ ldap/servers/slapd/libslapd_la-time.lo: ldap/servers/slapd/time.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libslapd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/slapd/libslapd_la-time.lo `test -f 'ldap/servers/slapd/time.c' || echo '$(srcdir)/'`ldap/servers/slapd/time.c +ldap/servers/slapd/libslapd_la-thread_data.lo: ldap/servers/slapd/thread_data.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libslapd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/slapd/libslapd_la-thread_data.lo -MD -MP -MF ldap/servers/slapd/$(DEPDIR)/libslapd_la-thread_data.Tpo -c -o ldap/servers/slapd/libslapd_la-thread_data.lo `test -f 'ldap/servers/slapd/thread_data.c' || echo '$(srcdir)/'`ldap/servers/slapd/thread_data.c +@am__fastdepCC_TRUE@ $(am__mv) ldap/servers/slapd/$(DEPDIR)/libslapd_la-thread_data.Tpo ldap/servers/slapd/$(DEPDIR)/libslapd_la-thread_data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ldap/servers/slapd/thread_data.c' object='ldap/servers/slapd/libslapd_la-thread_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libslapd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/slapd/libslapd_la-thread_data.lo `test -f 'ldap/servers/slapd/thread_data.c' || echo '$(srcdir)/'`ldap/servers/slapd/thread_data.c + ldap/servers/slapd/libslapd_la-uniqueid.lo: ldap/servers/slapd/uniqueid.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libslapd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/slapd/libslapd_la-uniqueid.lo -MD -MP -MF ldap/servers/slapd/$(DEPDIR)/libslapd_la-uniqueid.Tpo -c -o ldap/servers/slapd/libslapd_la-uniqueid.lo `test -f 'ldap/servers/slapd/uniqueid.c' || echo '$(srcdir)/'`ldap/servers/slapd/uniqueid.c @am__fastdepCC_TRUE@ $(am__mv) ldap/servers/slapd/$(DEPDIR)/libslapd_la-uniqueid.Tpo ldap/servers/slapd/$(DEPDIR)/libslapd_la-uniqueid.Plo diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c b/ldap/servers/plugins/linkedattrs/fixup_task.c index 10c821b..b19d3ab 100644 --- a/ldap/servers/plugins/linkedattrs/fixup_task.c +++ b/ldap/servers/plugins/linkedattrs/fixup_task.c @@ -67,6 +67,7 @@ linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e, task_data *mytaskdata = NULL; Slapi_Task *task = NULL; const char *linkdn = NULL; + char *bind_dn; *returncode = LDAP_SUCCESS; @@ -81,6 +82,7 @@ linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e, linkdn = fetch_attr(e, "linkdn", 0); /* setup our task data */ + slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn); mytaskdata = (task_data*)slapi_ch_calloc(1, sizeof(task_data)); if (mytaskdata == NULL) { *returncode = LDAP_OPERATIONS_ERROR; @@ -91,6 +93,7 @@ linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e, if (linkdn) { mytaskdata->linkdn = slapi_dn_normalize(slapi_ch_strdup(linkdn)); } + mytaskdata->bind_dn = slapi_ch_strdup(bind_dn); /* allocate new task now */ task = slapi_new_task(slapi_entry_get_ndn(e)); @@ -126,6 +129,7 @@ linked_attrs_fixup_task_destructor(Slapi_Task *task) task_data *mydata = (task_data *)slapi_task_get_data(task); if (mydata) { slapi_ch_free_string(&mydata->linkdn); + slapi_ch_free_string(&mydata->bind_dn); /* Need to cast to avoid a compiler warning */ slapi_ch_free((void **)&mydata); } @@ -144,6 +148,9 @@ linked_attrs_fixup_task_thread(void *arg) /* Fetch our task data from the task */ td = (task_data *)slapi_task_get_data(task); + /* init and set the bind dn in the thread data */ + slapi_td_set_dn(slapi_ch_strdup(td->bind_dn)); + /* Log started message. */ slapi_task_begin(task, 1); slapi_task_log_notice(task, "Linked attributes fixup task starting (link dn: \"%s\") ...\n", diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.h b/ldap/servers/plugins/linkedattrs/linked_attrs.h index 137e317..2eba62f 100644 --- a/ldap/servers/plugins/linkedattrs/linked_attrs.h +++ b/ldap/servers/plugins/linkedattrs/linked_attrs.h @@ -100,6 +100,7 @@ struct configIndex { typedef struct _task_data { char *linkdn; + char *bind_dn; } task_data; diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c index 56e34d4..655054c 100644 --- a/ldap/servers/plugins/memberof/memberof.c +++ b/ldap/servers/plugins/memberof/memberof.c @@ -2195,6 +2195,7 @@ void memberof_unlock() typedef struct _task_data { char *dn; + char *bind_dn; char *filter_str; } task_data; @@ -2208,6 +2209,9 @@ void memberof_fixup_task_thread(void *arg) /* Fetch our task data from the task */ td = (task_data *)slapi_task_get_data(task); + /* set bind DN in the thread data */ + slapi_td_set_dn(slapi_ch_strdup(td->bind_dn)); + slapi_task_begin(task, 1); slapi_task_log_notice(task, "Memberof task starts (arg: %s) ...\n", td->filter_str); @@ -2263,6 +2267,7 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e, int rv = SLAPI_DSE_CALLBACK_OK; task_data *mytaskdata = NULL; Slapi_Task *task = NULL; + char *bind_dn; const char *filter; const char *dn = 0; @@ -2292,6 +2297,7 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e, } /* setup our task data */ + slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn); mytaskdata = (task_data*)slapi_ch_malloc(sizeof(task_data)); if (mytaskdata == NULL) { @@ -2301,6 +2307,7 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e, } mytaskdata->dn = slapi_ch_strdup(dn); mytaskdata->filter_str = slapi_ch_strdup(filter); + mytaskdata->bind_dn = slapi_ch_strdup(bind_dn); /* allocate new task now */ task = slapi_new_task(slapi_entry_get_ndn(e)); @@ -2337,6 +2344,7 @@ memberof_task_destructor(Slapi_Task *task) task_data *mydata = (task_data *)slapi_task_get_data(task); if (mydata) { slapi_ch_free_string(&mydata->dn); + slapi_ch_free_string(&mydata->bind_dn); slapi_ch_free_string(&mydata->filter_str); /* Need to cast to avoid a compiler warning */ slapi_ch_free((void **)&mydata); diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c index 8ece438..fcb70fb 100644 --- a/ldap/servers/plugins/referint/referint.c +++ b/ldap/servers/plugins/referint/referint.c @@ -80,7 +80,7 @@ int referint_postop_close( Slapi_PBlock *pb); int update_integrity(char **argv, Slapi_DN *sDN, char *newrDN, Slapi_DN *newsuperior, int logChanges); void referint_thread_func(void *arg); int GetNextLine(char *dest, int size_dest, PRFileDesc *stream); -void writeintegritylog(char *logfilename, Slapi_DN *sdn, char *newrdn, Slapi_DN *newsuperior, Slapi_DN *requestorsdn); +void writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn, char *newrdn, Slapi_DN *newsuperior, Slapi_DN *requestorsdn); int my_fgetc(PRFileDesc *stream); /* global thread control stuff */ @@ -216,7 +216,7 @@ referint_postop_del( Slapi_PBlock *pb ) rc = update_integrity(argv, sdn, NULL, NULL, logChanges); }else{ /* write the entry to integrity log */ - writeintegritylog(argv[1], sdn, NULL, NULL, NULL /* slapi_get_requestor_sdn(pb) */); + writeintegritylog(pb, argv[1], sdn, NULL, NULL, NULL /* slapi_get_requestor_sdn(pb) */); rc = 0; } } else { @@ -300,7 +300,7 @@ referint_postop_modrdn( Slapi_PBlock *pb ) newsuperior, logChanges); }else{ /* write the entry to integrity log */ - writeintegritylog(argv[1], sdn, newrdn, newsuperior, NULL /* slapi_get_requestor_sdn(pb) */); + writeintegritylog(pb, argv[1], sdn, newrdn, newsuperior, NULL /* slapi_get_requestor_sdn(pb) */); rc = 0; } @@ -913,6 +913,11 @@ referint_thread_func(void *arg) return; } + /* initialize the thread data index + if(slapi_td_dn_init()){ + slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,"Failed to create thread data index\n"); + + } */ delay = atoi(plugin_argv[0]); logfilename = plugin_argv[1]; @@ -978,6 +983,13 @@ referint_thread_func(void *arg) } else { tmpsuperior = slapi_sdn_new_normdn_byref(ptoken); } + ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter); + if (strcasecmp(ptoken, "NULL") != 0) { + /* Set the bind DN in the thread data */ + if(slapi_td_set_dn(slapi_ch_strdup(ptoken))){ + slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,"Failed to set thread data\n"); + } + } update_integrity(plugin_argv, sdn, tmprdn, tmpsuperior, logChanges); @@ -1097,7 +1109,7 @@ GetNextLine(char *dest, int size_dest, PRFileDesc *stream) { } void -writeintegritylog(char *logfilename, Slapi_DN *sdn, +writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn, char *newrdn, Slapi_DN *newsuperior, Slapi_DN *requestorsdn) { PRFileDesc *prfd; @@ -1147,6 +1159,7 @@ writeintegritylog(char *logfilename, Slapi_DN *sdn, /* add the length of the newsuperior */ len_to_write += slapi_sdn_get_ndn_len(newsuperior); } + slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &requestordn); if (requestorsdn && (requestordn = slapi_sdn_get_udn(requestorsdn)) && (reqdn_len = strlen(requestordn))) { len_to_write += reqdn_len; diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c b/ldap/servers/plugins/schema_reload/schema_reload.c index 7aeab7c..338aaf4 100644 --- a/ldap/servers/plugins/schema_reload/schema_reload.c +++ b/ldap/servers/plugins/schema_reload/schema_reload.c @@ -121,6 +121,12 @@ schemareload_start(Slapi_PBlock *pb) return rc; } +typedef struct _task_data +{ + char *schemadir; + char *bind_dn; +} task_data; + /* * Task thread * This is the heart of the reload-schema-file task: @@ -134,16 +140,21 @@ schemareload_thread(void *arg) Slapi_Task *task = (Slapi_Task *)arg; int rv = 0; int total_work = 2; - /* fetch our argument from the task */ - char *schemadir = (char *)slapi_task_get_data(task); + task_data *td = NULL; + + /* Fetch our task data from the task */ + td = (task_data *)slapi_task_get_data(task); + + /* Initialize and set the bind dn in the thread data */ + slapi_td_set_dn(slapi_ch_strdup(td->bind_dn)); /* update task state to show it's running */ slapi_task_begin(task, total_work); PR_Lock(schemareload_lock); /* make schema reload serialized */ - slapi_task_log_notice(task, "Schema reload task starts (schema dir: %s) ...\n", schemadir?schemadir:"default"); - slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema reload task starts (schema dir: %s) ...\n", schemadir?schemadir:"default"); + slapi_task_log_notice(task, "Schema reload task starts (schema dir: %s) ...\n", td->schemadir?td->schemadir:"default"); + slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema reload task starts (schema dir: %s) ...\n", td->schemadir?td->schemadir:"default"); - rv = slapi_validate_schema_files(schemadir); + rv = slapi_validate_schema_files(td->schemadir); slapi_task_inc_progress(task); if (LDAP_SUCCESS == rv) { @@ -151,7 +162,7 @@ schemareload_thread(void *arg) slapi_task_log_status(task, "Schema validation passed."); slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema validation passed.\n"); - rv = slapi_reload_schema_files(schemadir); + rv = slapi_reload_schema_files(td->schemadir); slapi_task_inc_progress(task); /* update task state to say we're finished */ @@ -196,8 +207,13 @@ static void schemareload_destructor(Slapi_Task *task) { if (task) { - char *schemadir = (char *)slapi_task_get_data(task); - slapi_ch_free_string(&schemadir); + task_data *mydata = (task_data *)slapi_task_get_data(task); + if (mydata) { + slapi_ch_free_string(&mydata->schemadir); + slapi_ch_free_string(&mydata->bind_dn); + /* Need to cast to avoid a compiler warning */ + slapi_ch_free((void **)&mydata); + } } } @@ -215,6 +231,9 @@ schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e, const char *schemadir = NULL; int rv = SLAPI_DSE_CALLBACK_OK; Slapi_Task *task = NULL; + task_data *mytaskdata = NULL; + + char *bind_dn; *returncode = LDAP_SUCCESS; if (fetch_attr(e, "cn", NULL) == NULL) { @@ -223,6 +242,9 @@ schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e, goto out; } + /* get the requestor dn for our thread data*/ + slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn); + /* get arg(s) */ schemadir = fetch_attr(e, "schemadir", NULL); @@ -235,11 +257,14 @@ schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e, goto out; } + mytaskdata->schemadir = slapi_ch_strdup(schemadir); + mytaskdata->bind_dn = slapi_ch_strdup(bind_dn); + /* set a destructor that will clean up schemadir for us when the task is complete */ slapi_task_set_destructor_fn(task, schemareload_destructor); - /* Stash our argument in the task for use by the task thread */ - slapi_task_set_data(task, slapi_ch_strdup(schemadir)); + /* Stash our task_data for use by the task thread */ + slapi_task_set_data(task, mytaskdata); /* start the schema reload task as a separate thread */ thread = PR_CreateThread(PR_USER_THREAD, schemareload_thread, diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c index 12a48e3..20decae 100644 --- a/ldap/servers/plugins/usn/usn_cleanup.c +++ b/ldap/servers/plugins/usn/usn_cleanup.c @@ -44,6 +44,7 @@ struct usn_cleanup_data { char *suffix; char *maxusn_to_delete; + char *bind_dn; }; static int usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, @@ -86,6 +87,9 @@ usn_cleanup_thread(void *arg) goto bail; } + /* Initialize and set the thread data */ + slapi_td_set_dn(slapi_ch_strdup(cleanup_data->bind_dn)); + /* update task state to show it's running */ slapi_task_begin(task, total_work); if (cleanup_data->maxusn_to_delete) { @@ -184,6 +188,7 @@ bail: } slapi_ch_free_string(&cleanup_data->maxusn_to_delete); slapi_ch_free_string(&cleanup_data->suffix); + slapi_ch_free_string(&cleanup_data->bind_dn); slapi_ch_free((void **)&cleanup_data); /* this will queue the destruction of the task */ @@ -242,6 +247,7 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, char *suffix = NULL; char *backend = NULL; char *maxusn = NULL; + char *bind_dn; struct usn_cleanup_data *cleanup_data = NULL; int rv = SLAPI_DSE_CALLBACK_OK; Slapi_Task *task = NULL; @@ -253,6 +259,9 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, *returncode = LDAP_SUCCESS; + /* get the requestor dn */ + slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn); + /* make sure plugin is not closed*/ if(!usn_is_started()){ *returncode = LDAP_OPERATIONS_ERROR; @@ -310,6 +319,7 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, (struct usn_cleanup_data *)slapi_ch_malloc(sizeof(struct usn_cleanup_data)); cleanup_data->suffix = slapi_ch_strdup(suffix); cleanup_data->maxusn_to_delete = slapi_ch_strdup(maxusn); + cleanup_data->bind_dn = slapi_ch_strdup(bind_dn); /* allocate new task now */ task = slapi_new_task(slapi_entry_get_ndn(e)); diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c index 53fd3fc..204e13c 100644 --- a/ldap/servers/slapd/add.c +++ b/ldap/servers/slapd/add.c @@ -742,6 +742,7 @@ static int add_created_attrs(Operation *op, Slapi_Entry *e) { char buf[20]; + char *binddn = NULL; struct berval bv; struct berval *bvals[2]; time_t curtime; @@ -753,21 +754,39 @@ add_created_attrs(Operation *op, Slapi_Entry *e) bvals[0] = &bv; bvals[1] = NULL; - if(slapdFrontendConfig->plugin_track && !slapi_sdn_isempty(&op->o_sdn)){ - /* assume op->o_sdn holds the plugin DN */ - bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn); - bv.bv_len = strlen(bv.bv_val); + if(slapdFrontendConfig->plugin_track){ + /* plugin bindDN tracking is enabled, grab the dn from thread local storage */ + if(slapi_sdn_isempty(&op->o_sdn)){ + bv.bv_val = ""; + bv.bv_len = strlen(bv.bv_val); + } else { + bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn); + bv.bv_len = strlen(bv.bv_val); + } slapi_entry_attr_replace(e, "internalCreatorsName", bvals); slapi_entry_attr_replace(e, "internalModifiersName", bvals); - } - if (slapi_sdn_isempty(&op->o_sdn)) { - bv.bv_val = ""; - bv.bv_len = strlen(bv.bv_val); + /* Grab the thread data(binddn) */ + slapi_td_get_dn(&binddn); + + if(binddn == NULL){ + /* anonymous bind */ + bv.bv_val = ""; + bv.bv_len = strlen(bv.bv_val); + } else { + bv.bv_val = binddn; + bv.bv_len = strlen(bv.bv_val); + } } else { - bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn); - bv.bv_len = strlen(bv.bv_val); + if (slapi_sdn_isempty(&op->o_sdn)) { + bv.bv_val = ""; + bv.bv_len = strlen(bv.bv_val); + } else { + bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn); + bv.bv_len = strlen(bv.bv_val); + } } + slapi_entry_attr_replace(e, "creatorsname", bvals); slapi_entry_attr_replace(e, "modifiersname", bvals); diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c index cabfe71..13d56b6 100644 --- a/ldap/servers/slapd/connection.c +++ b/ldap/servers/slapd/connection.c @@ -2634,6 +2634,8 @@ op_copy_identity(Connection *conn, Operation *op) } else { slapi_sdn_set_dn_byval(&op->o_sdn,conn->c_dn); op->o_authtype = slapi_ch_strdup(conn->c_authtype); + /* set the thread data bind dn index */ + slapi_td_set_dn(slapi_ch_strdup(conn->c_dn)); } /* XXX We should also copy c_client_cert into *op here; it's * part of the authorization identity. The operation's copy diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c index 3455852..7b15249 100644 --- a/ldap/servers/slapd/main.c +++ b/ldap/servers/slapd/main.c @@ -1150,6 +1150,9 @@ main( int argc, char **argv) */ task_cleanup(); + /* init the thread data index for bind dn's */ + slapi_td_dn_init(); + plugin_print_lists(); plugin_startall(argc, argv, 1 /* Start Backends */, 1 /* Start Globals */); if (housekeeping_start((time_t)0, NULL) == NULL) { diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c index 12f7fdf..0101469 100644 --- a/ldap/servers/slapd/opshared.c +++ b/ldap/servers/slapd/opshared.c @@ -137,6 +137,7 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods) { char buf[20]; char *plugin_dn = NULL; + char *binddn = NULL; struct berval bv; struct berval *bvals[2]; time_t curtime; @@ -152,35 +153,52 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods) bvals[0] = &bv; bvals[1] = NULL; - if(slapdFrontendConfig->plugin_track && !slapi_sdn_isempty(&op->o_sdn)){ - /* write to the new attribute the bind dn and plugin name */ - slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid); - if (cid) - plugin=(struct slapdplugin *) cid->sci_plugin; - if(plugin) - plugin_dn = plugin_get_dn (plugin); - if(plugin_dn){ - bv.bv_val = plugin_dn; - bv.bv_len = strlen(bv.bv_val); - } else { - bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn); + if(slapdFrontendConfig->plugin_track){ + /* plugin bindDN tracking is enabled, grab the bind dn from thread local storage */ + if(slapi_sdn_isempty(&op->o_sdn)){ + bv.bv_val = ""; bv.bv_len = strlen(bv.bv_val); - } - slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, - "internalModifiersName", bvals); - } + } else { + slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid); + if (cid) + plugin=(struct slapdplugin *) cid->sci_plugin; + if(plugin) + plugin_dn = plugin_get_dn (plugin); + if(plugin_dn){ + bv.bv_val = plugin_dn; + bv.bv_len = strlen(bv.bv_val); + } else { + bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn); + bv.bv_len = strlen(bv.bv_val); + } + } + slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, + "internalModifiersName", bvals); - /* fill in modifiersname */ - if (slapi_sdn_isempty(&op->o_sdn)) { - bv.bv_val = ""; - bv.bv_len = strlen(bv.bv_val); + /* Grab the thread data(binddn) */ + slapi_td_get_dn(&binddn); + + if(binddn == NULL){ + /* anonymous bind */ + bv.bv_val = ""; + bv.bv_len = strlen(bv.bv_val); + } else { + bv.bv_val = binddn; + bv.bv_len = strlen(bv.bv_val); + } } else { - bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn); - bv.bv_len = strlen(bv.bv_val); + /* fill in modifiersname */ + if (slapi_sdn_isempty(&op->o_sdn)) { + bv.bv_val = ""; + bv.bv_len = strlen(bv.bv_val); + } else { + bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn); + bv.bv_len = strlen(bv.bv_val); + } } - slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, - "modifiersname", bvals); + slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, + "modifiersname", bvals); /* fill in modifytimestamp */ curtime = current_time(); diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c index b607f28..2a1c706 100644 --- a/ldap/servers/slapd/pblock.c +++ b/ldap/servers/slapd/pblock.c @@ -3593,6 +3593,8 @@ bind_credentials_set_nolock( Connection *conn, char *authtype, char *normdn, conn->c_dn = normdn; conn->c_isroot = slapi_dn_isroot( normdn ); + /* Set the thread data with the normalized dn */ + slapi_td_set_dn(slapi_ch_strdup(normdn)); /* set external credentials if requested */ if ( extauthtype != NULL ) { diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index 3444b7e..b4eb2a6 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -5096,6 +5096,16 @@ int slapi_apib_release(void **api); /**** End of API broker interface. *******************************************/ +/* thread_data.c */ +int slapi_td_init(int indexType); +int slapi_td_set_val(int indexType, void *value); +void slapi_td_get_val(int indexType, void **value); +int slapi_td_dn_init(); +int slapi_td_set_dn(char *dn); +void slapi_td_get_dn(char **dn); + +/* Thread Local Storage Index Types */ +#define SLAPI_TD_REQUESTOR_DN 1 /* * routines for dealing with controls diff --git a/ldap/servers/slapd/thread_data.c b/ldap/servers/slapd/thread_data.c new file mode 100644 index 0000000..ead6e88 --- /dev/null +++ b/ldap/servers/slapd/thread_data.c @@ -0,0 +1,174 @@ +/** BEGIN COPYRIGHT BLOCK + * This Program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; version 2 of the License. + * + * This Program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA. + * + * In addition, as a special exception, Red Hat, Inc. gives You the additional + * right to link the code of this Program with code not covered under the GNU + * General Public License ("Non-GPL Code") and to distribute linked combinations + * including the two, subject to the limitations in this paragraph. Non-GPL Code + * permitted under this exception must only link to the code of this Program + * through those well defined interfaces identified in the file named EXCEPTION + * found in the source code files (the "Approved Interfaces"). The files of + * Non-GPL Code may instantiate templates or use macros or inline functions from + * the Approved Interfaces without causing the resulting work to be covered by + * the GNU General Public License. Only Red Hat, Inc. may make changes or + * additions to the list of Approved Interfaces. You must obey the GNU General + * Public License in all respects for all of the Program code and other code used + * in conjunction with the Program except the Non-GPL Code covered by this + * exception. If you modify this file, you may extend this exception to your + * version of the file, but you are not obligated to do so. If you do not wish to + * provide this exception without modification, you must delete this exception + * statement from your version and license this file solely under the GPL without + * exception. + * + * + * Copyright (C) 2012 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +/* + * Thread Local Storage Functions + */ +#include +#include + +void td_dn_destructor(void *priv); + +/* + * Thread Local Storage Indexes + */ +static PRUintn td_requestor_dn; /* TD_REQUESTOR_DN */ + +/* + * Index types defined in slapi-plugin.h + * + * #define SLAPI_TD_REQUESTOR_DN 1 + * ... + * ... + */ + + +/* + * The Process: + * + * [1] Create new index type macro in slapi-plugin.h + * [2] Create new static "PRUintn" index + * [3] Update these functions with the new index: + * slapi_td_init() + * slapi_td_set_val() + * slapi_td_get_val() + * [4] Create wrapper functions if so desired, and update slapi_plugin.h + * [5] Create destructor (if necessary) + */ + +int +slapi_td_init(int indexType) +{ + switch(indexType){ + case SLAPI_TD_REQUESTOR_DN: + if(PR_NewThreadPrivateIndex(&td_requestor_dn, td_dn_destructor) == PR_FAILURE){ + return PR_FAILURE; + } + break; + + default: + return PR_FAILURE; + } + + return PR_SUCCESS; +} + +/* + * Caller needs to cast value to (void *) + */ +int +slapi_td_set_val(int indexType, void *value) +{ + switch(indexType){ + case SLAPI_TD_REQUESTOR_DN: + if(td_requestor_dn){ + if(PR_SetThreadPrivate(td_requestor_dn, value) == PR_FAILURE){ + return PR_FAILURE; + } + } else { + return PR_FAILURE; + } + break; + + default: + return PR_FAILURE; + } + + return PR_SUCCESS; +} + +/* + * Caller needs to cast value to (void **) + */ +void +slapi_td_get_val(int indexType, void **value) +{ + switch(indexType){ + case SLAPI_TD_REQUESTOR_DN: + if(td_requestor_dn){ + *value = PR_GetThreadPrivate(td_requestor_dn); + } else { + *value = NULL; + } + break; + default: + *value = NULL; + return; + } +} + +/* + * Wrapper Functions + */ + +int +slapi_td_dn_init() +{ + if(slapi_td_init(SLAPI_TD_REQUESTOR_DN) == PR_FAILURE){ + return PR_FAILURE; + } + + return PR_SUCCESS; +} + +int +slapi_td_set_dn(char *value) +{ + if(slapi_td_set_val(SLAPI_TD_REQUESTOR_DN, (void *)value) == PR_FAILURE){ + return PR_FAILURE; + } + + return PR_SUCCESS; +} + +void +slapi_td_get_dn(char **value){ + slapi_td_get_val(SLAPI_TD_REQUESTOR_DN, (void **)value); +} + + +/* + * Destructor Functions + */ + +void +td_dn_destructor(void *priv) +{ + slapi_ch_free((void **)&priv); +} + +