/* * Invoked when the task instance is added by the client (step 5 of the comment) * Get the necessary attributes from the task entry, and spawns a thread to do * the task. */ static int task_sampletask_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg) { PRThread *thread = NULL; const char *cn; int rv = SLAPI_DSE_CALLBACK_OK; Slapi_PBlock *mypb = NULL; Slapi_Task *task = NULL; const char *myarg; *returncode = LDAP_SUCCESS; if ((cn = fetch_attr(e, "cn", NULL)) == NULL) { *returncode = LDAP_OBJECT_CLASS_VIOLATION; rv = SLAPI_DSE_CALLBACK_ERROR; goto out; } /* get arg(s) */ if ((myarg = fetch_attr(e, "myarg", NULL)) == NULL) { *returncode = LDAP_OBJECT_CLASS_VIOLATION; rv = SLAPI_DSE_CALLBACK_ERROR; goto out; } /* allocate new task now */ task = slapi_new_task(slapi_entry_get_ndn(e)); if (task == NULL) { slapi_log_err(SLAPI_LOG_ERR, "sampletask", "unable to allocate new task!\n"); *returncode = LDAP_OPERATIONS_ERROR; rv = SLAPI_DSE_CALLBACK_ERROR; goto out; } /* set a destructor that will clean up myarg for us when the task is complete */ slapi_task_set_destructor_fn(task, task_sampletask_destructor); /* Stash our argument in the task for use by the task thread */ slapi_task_set_data(task, slapi_ch_strdup(myarg)); /* start the sample task as a separate thread */ thread = PR_CreateThread(PR_USER_THREAD, task_sampletask_thread, (void *)task, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); if (thread == NULL) { slapi_log_err(SLAPI_LOG_ERR, "sampletask", "unable to create sample task thread!\n"); *returncode = LDAP_OPERATIONS_ERROR; rv = SLAPI_DSE_CALLBACK_ERROR; slapi_task_finish(task, *returncode); } else { /* thread successful */ rv = SLAPI_DSE_CALLBACK_OK; } out: return rv; }
int sidgen_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg) { int ret = SLAPI_DSE_CALLBACK_ERROR; const char *str; struct worker_ctx *worker_ctx = NULL; char *endptr; Slapi_Task *task = NULL; *returncode = LDAP_OPERATIONS_ERROR; returntext[0] = '\0'; worker_ctx = (struct worker_ctx *) slapi_ch_calloc(1, sizeof(struct worker_ctx)); if (worker_ctx == NULL) { LOG_FATAL("slapi_ch_malloc failed!\n"); *returncode = LDAP_OPERATIONS_ERROR; ret = SLAPI_DSE_CALLBACK_ERROR; goto done; } worker_ctx->plugin_id = global_sidgen_plugin_id; str = fetch_attr(e, "delay", NULL); if (str != NULL) { errno = 0; worker_ctx->delay = strtol(str, &endptr, 10); if (errno != 0 || worker_ctx->delay < 0) { LOG_FATAL("invalid delay [%s]!\n", str); *returncode = LDAP_CONSTRAINT_VIOLATION; ret = SLAPI_DSE_CALLBACK_ERROR; goto done; } } LOG("delay is [%li].\n", worker_ctx->delay); str = fetch_attr(e, "nsslapd-basedn", NULL); if (str == NULL) { LOG_FATAL("Missing nsslapd-basedn!\n"); *returncode = LDAP_CONSTRAINT_VIOLATION; ret = SLAPI_DSE_CALLBACK_ERROR; goto done; } worker_ctx->base_dn = slapi_ch_strdup(str); if (worker_ctx->base_dn == NULL) { LOG_FATAL("Failed to copy base DN.\n"); *returncode = LDAP_OPERATIONS_ERROR; ret = ENOMEM; goto done; } ret = get_dom_sid(worker_ctx->plugin_id, worker_ctx->base_dn, &worker_ctx->dom_sid); if (ret != 0) { LOG_FATAL("Cannot find domain SID.\n"); goto done; } ret = get_ranges(worker_ctx->plugin_id, worker_ctx->base_dn, &worker_ctx->ranges); if (ret != 0) { LOG_FATAL("Cannot find ranges.\n"); goto done; } task = slapi_new_task(slapi_entry_get_ndn(e)); if (task == NULL) { LOG_FATAL("unable to allocate new task!\n"); *returncode = LDAP_OPERATIONS_ERROR; ret = SLAPI_DSE_CALLBACK_ERROR; goto done; } slapi_task_set_destructor_fn(task, sidgen_task_destructor); slapi_task_set_data(task, worker_ctx); ret = pthread_create(&worker_ctx->tid, NULL, sidgen_task_thread, task); if (ret != 0) { LOG_FATAL("unable to create sidgen task thread!\n"); *returncode = LDAP_OPERATIONS_ERROR; ret = SLAPI_DSE_CALLBACK_ERROR; slapi_task_finish(task, *returncode); goto done; } ret = SLAPI_DSE_CALLBACK_OK; *returncode = LDAP_SUCCESS; done: if (ret != SLAPI_DSE_CALLBACK_OK) { slapi_ch_free((void **) &worker_ctx->base_dn); slapi_ch_free((void **) &worker_ctx); } return ret; }
/* * Function Implementations */ int linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg) { PRThread *thread = NULL; int rv = SLAPI_DSE_CALLBACK_OK; task_data *mytaskdata = NULL; Slapi_Task *task = NULL; const char *linkdn = NULL; char *bind_dn; *returncode = LDAP_SUCCESS; /* make sure the plugin is not closed */ if(!linked_attrs_is_started()){ *returncode = LDAP_OPERATIONS_ERROR; rv = SLAPI_DSE_CALLBACK_ERROR; goto out; } /* get arg(s) */ 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; rv = SLAPI_DSE_CALLBACK_ERROR; goto out; } 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)); /* register our destructor for cleaning up our private data */ slapi_task_set_destructor_fn(task, linked_attrs_fixup_task_destructor); /* Stash a pointer to our data in the task */ slapi_task_set_data(task, mytaskdata); /* start the sample task as a separate thread */ thread = PR_CreateThread(PR_USER_THREAD, linked_attrs_fixup_task_thread, (void *)task, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); if (thread == NULL) { slapi_log_error( SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM, "unable to create task thread!\n"); *returncode = LDAP_OPERATIONS_ERROR; rv = SLAPI_DSE_CALLBACK_ERROR; slapi_task_finish(task, *returncode); } else { rv = SLAPI_DSE_CALLBACK_OK; } out: return rv; }