/* Apply the pending changes in the e entry to our config struct. validate must have already been called */ static int pam_passthru_apply_config (Slapi_Entry* e) { int rc = PAM_PASSTHRU_SUCCESS; char **excludes = NULL; char **includes = NULL; char *new_service = NULL; char *pam_ident_attr = NULL; char *map_method = NULL; char *dn = NULL; PRBool fallback; PRBool secure; Pam_PassthruConfig *entry = NULL; PRCList *list; Slapi_Attr *a = NULL; char *filter_str = NULL; int inserted = 0; pam_ident_attr = slapi_entry_attr_get_charptr(e, PAMPT_PAM_IDENT_ATTR); map_method = slapi_entry_attr_get_charptr(e, PAMPT_MAP_METHOD_ATTR); new_service = slapi_entry_attr_get_charptr(e, PAMPT_SERVICE_ATTR); excludes = slapi_entry_attr_get_charray(e, PAMPT_EXCLUDES_ATTR); includes = slapi_entry_attr_get_charray(e, PAMPT_INCLUDES_ATTR); fallback = slapi_entry_attr_get_bool(e, PAMPT_FALLBACK_ATTR); filter_str = slapi_entry_attr_get_charptr(e, PAMPT_FILTER_ATTR); /* Require SSL/TLS if the secure attr is not specified. We * need to check if the attribute is present to make this * determiniation. */ if (slapi_entry_attr_find(e, PAMPT_SECURE_ATTR, &a) == 0) { secure = slapi_entry_attr_get_bool(e, PAMPT_SECURE_ATTR); } else { secure = PR_TRUE; } /* Allocate a config struct. */ entry = (Pam_PassthruConfig *) slapi_ch_calloc(1, sizeof(Pam_PassthruConfig)); if (NULL == entry) { rc = PAM_PASSTHRU_FAILURE; goto bail; } /* use the RDN method to derive the PAM identity by default*/ entry->pamptconfig_map_method1 = PAMPT_MAP_METHOD_RDN; entry->pamptconfig_map_method2 = PAMPT_MAP_METHOD_NONE; entry->pamptconfig_map_method3 = PAMPT_MAP_METHOD_NONE; /* Fill in the struct. */ dn = slapi_entry_get_ndn(e); if (dn) { entry->dn = slapi_ch_strdup(dn); } entry->pamptconfig_fallback = fallback; entry->pamptconfig_secure = secure; if (!entry->pamptconfig_service || (new_service && PL_strcmp(entry->pamptconfig_service, new_service))) { slapi_ch_free_string(&entry->pamptconfig_service); entry->pamptconfig_service = new_service; new_service = NULL; /* config now owns memory */ } /* get the list of excluded suffixes */ pam_ptconfig_free_suffixes(entry->pamptconfig_excludes); entry->pamptconfig_excludes = pam_ptconfig_add_suffixes(excludes); /* get the list of included suffixes */ pam_ptconfig_free_suffixes(entry->pamptconfig_includes); entry->pamptconfig_includes = pam_ptconfig_add_suffixes(includes); if (!entry->pamptconfig_pam_ident_attr || (pam_ident_attr && PL_strcmp(entry->pamptconfig_pam_ident_attr, pam_ident_attr))) { slapi_ch_free_string(&entry->pamptconfig_pam_ident_attr); entry->pamptconfig_pam_ident_attr = pam_ident_attr; pam_ident_attr = NULL; /* config now owns memory */ } if (map_method) { parse_map_method(map_method, &entry->pamptconfig_map_method1, &entry->pamptconfig_map_method2, &entry->pamptconfig_map_method3, NULL); } if (filter_str) { entry->filter_str = filter_str; filter_str = NULL; /* config now owns memory */ entry->slapi_filter = slapi_str2filter(entry->filter_str); } /* Add config to list. We just store at the tail. */ if (!PR_CLIST_IS_EMPTY(pam_passthru_global_config)) { list = PR_LIST_HEAD(pam_passthru_global_config); while (list != pam_passthru_global_config) { list = PR_NEXT_LINK(list); if (pam_passthru_global_config == list) { /* add to tail */ PR_INSERT_BEFORE(&(entry->list), list); slapi_log_err(SLAPI_LOG_CONFIG, PAM_PASSTHRU_PLUGIN_SUBSYSTEM, "pam_passthru_apply_config - store [%s] at tail\n", entry->dn); inserted = 1; break; } } } else { /* first entry */ PR_INSERT_LINK(&(entry->list), pam_passthru_global_config); slapi_log_err(SLAPI_LOG_CONFIG, PAM_PASSTHRU_PLUGIN_SUBSYSTEM, "pam_passthru_apply_config - store [%s] at head \n", entry->dn); inserted = 1; } bail: if(!inserted){ pam_passthru_free_config_entry(&entry); } slapi_ch_free_string(&new_service); slapi_ch_free_string(&map_method); slapi_ch_free_string(&pam_ident_attr); slapi_ch_free_string(&filter_str); slapi_ch_array_free(excludes); slapi_ch_array_free(includes); return rc; }
static JSDContext* _newJSDContext(JSTaskState* jstaskstate, JSD_UserCallbacks* callbacks, void* user) { JSDContext* jsdc = NULL; if( ! jstaskstate ) return NULL; if( ! _validateUserCallbacks(callbacks) ) return NULL; jsdc = (JSDContext*) calloc(1, sizeof(JSDContext)); if( ! jsdc ) goto label_newJSDContext_failure; if( ! JSD_INIT_LOCKS(jsdc) ) goto label_newJSDContext_failure; PR_INIT_CLIST(&jsdc->links); jsdc->jstaskstate = jstaskstate; if( callbacks ) memcpy(&jsdc->userCallbacks, callbacks, callbacks->size); jsdc->user = user; #ifdef JSD_HAS_DANGEROUS_THREAD jsdc->dangerousThread = _dangerousThread; #endif PR_INIT_CLIST(&jsdc->threadsStates); PR_INIT_CLIST(&jsdc->scripts); PR_INIT_CLIST(&jsdc->sources); PR_INIT_CLIST(&jsdc->removedSources); jsdc->sourceAlterCount = 1; jsdc->jscontexts = PR_NewHashTable(256, _hash_root, PR_CompareValues, PR_CompareValues, NULL, NULL); if( ! jsdc->jscontexts ) goto label_newJSDContext_failure; jsdc->dumbContext = JS_NewContext(jsdc->jstaskstate, 256); if( ! jsdc->dumbContext ) goto label_newJSDContext_failure; jsdc->glob = JS_NewObject(jsdc->dumbContext, &global_class, NULL, NULL); if( ! jsdc->glob ) goto label_newJSDContext_failure; if( ! JS_InitStandardClasses(jsdc->dumbContext, jsdc->glob) ) goto label_newJSDContext_failure; jsdc->inited = JS_TRUE; JSD_LOCK(); PR_INSERT_LINK(&jsdc->links, &_jsd_context_list); JSD_UNLOCK(); return jsdc; label_newJSDContext_failure: if( jsdc ) free(jsdc); return NULL; }
static void MoveSourceToFront( JSDContext* jsdc, JSDSourceText* jsdsrc ) { PR_REMOVE_LINK(&jsdsrc->links); PR_INSERT_LINK(&jsdsrc->links, &jsd_source_list); }
NSFC_NewFilenameEntry(NSFCCache cip, const char *filename, PRUint32 hvalue, NSFCStatus &rfc) { PRUint32 bucket = hvalue % cip->hsize; PR_ASSERT(cip); if (cip->state != NSFCCache_Active) { rfc = NSFC_DEADCACHE; return NULL; } rfc = NSFC_OK; /* Replace file cache entries once the cache fills up */ if (_NSFC_IsTimeToReplace(cip)) { PR_Lock(cip->hitLock); if (!PR_CLIST_IS_EMPTY(&cip->hit_list)) { NSFCEntryImpl* nepDelete; PRUint32 bucketDelete; /* Get the LRU entry from the hit list and remember its bucket */ PRCList *lru = PR_LIST_TAIL(&cip->hit_list); PR_ASSERT(lru); nepDelete = (NSFCEntryImpl*)((char*)lru - offsetof(NSFCEntryImpl, hit_list)); bucketDelete = nepDelete->hash % cip->hsize; PR_Unlock(cip->hitLock); /* Get access to the LRU entry's bucket */ if (bucket != bucketDelete) { NSFC_RELEASEBUCKET(cip, bucket); NSFC_ACQUIREBUCKET(cip, bucketDelete); } /* Look for the LRU entry in the bucket */ NSFCEntryImpl *nep; for (nep = cip->hname[bucketDelete]; nep; nep = nep->next) { if (nep == nepDelete) break; } if (nep == nepDelete) { /* The LRU entry is still around, mark it for deletion */ NSFC_DeleteEntry(cip, nep, PR_TRUE); /* Increment count of replaced entries */ PR_AtomicIncrement((PRInt32*)&cip->rplcCnt); } /* Get access to the new entry's bucket */ if (bucket != bucketDelete) { NSFC_RELEASEBUCKET(cip, bucketDelete); NSFC_ACQUIREBUCKET(cip, bucket); } } else { PR_Unlock(cip->hitLock); } } /* Respect limit on number of cache entries */ if (cip->curFiles >= cip->cfg.maxFiles) { cip->cacheFull = PR_TRUE; rfc = NSFC_NOSPACE; return NULL; } /* Get a file name entry */ PR_Lock(cip->namefLock); NSFCEntryImpl *nep = cip->namefl; if (nep != NULL) { /* Found a file name entry on the free list */ PR_ASSERT(nep->refcnt == 0); PR_ASSERT(!nep->fHashed); cip->namefl = nep->next; } PR_Unlock(cip->namefLock); if (nep == NULL) { /* Allocate a new file name entry */ nep = (NSFCEntryImpl *)NSFC_Calloc(1, sizeof(*nep), cip); if (nep) { nep->seqno = 1; } } if (nep) { nep->filename = NSFC_Strdup(filename, cip); if (nep->filename) { /* Initialize entry */ nep->next = NULL; nep->pdLock = PR_NewLock(); nep->pdlist = NULL; nep->finfo.pr.type = PR_FILE_OTHER; nep->finfo.pr.size = 0; nep->finfo.pr.creationTime = 0; nep->finfo.pr.modifyTime = 0; PRIntervalTime now = ft_timeIntervalNow(); nep->finfo.lastUpdate = now; nep->finfo.fileid[0] = hvalue; nep->finfo.fileid[1] = nep->seqno; nep->finfo.prerr = 0; nep->finfo.oserr = 0; nep->hash = hvalue; nep->hitcnt = 0; nep->refcnt = 1; nep->flags = 0; nep->fHashed = 1; nep->fDelete = 0; nep->fWriting = 0; /* Add entry to cache instance hash table */ NSFC_ASSERTBUCKETHELD(cip, bucket); nep->next = cip->hname[bucket]; cip->hname[bucket] = nep; PR_AtomicIncrement((PRInt32*)&cip->curFiles); /* Add entry to the hit list */ PR_Lock(cip->hitLock); PR_INIT_CLIST(&nep->hit_list); if (cip->cfg.hitOrder == PR_TRUE) { /* * Add this entry towards the end of the hit list, * but ahead of other entries with a zero hit count. */ PRCList *prev; NSFCEntryImpl *pnep; for (prev = PR_LIST_TAIL(&cip->hit_list); prev != &cip->hit_list; prev = PR_PREV_LINK(prev)) { pnep = NSFCENTRYIMPL(prev); if (pnep->hitcnt > nep->hitcnt) { break; /* Our spot in the list */ } } PR_INSERT_AFTER(&nep->hit_list, prev); } else { /* Put new entry at head of hit list */ PR_INSERT_LINK(&nep->hit_list, &cip->hit_list); } PR_Unlock(cip->hitLock); PR_ASSERT(!nep->fDelete); } else { /* Failed, so return the entry to the free list */ PR_Lock(cip->namefLock); nep->next = cip->namefl; cip->namefl = nep; nep = NULL; PR_Unlock(cip->namefLock); cip->cacheFull = PR_TRUE; /* file cache is full */ rfc = NSFC_NOSPACE; } } else { cip->cacheFull = PR_TRUE; /* file cache is full */ rfc = NSFC_NOSPACE; } /* Cache contents have been modified */ cip->sig++; return nep; }
/* queue a job, when a socket is readable or writeable */ static PRJob * queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg, PRBool joinable, io_op_type op) { PRJob *jobp; PRIntervalTime now; jobp = alloc_job(joinable, tpool); if (NULL == jobp) { return NULL; } /* * Add a new job to io_jobq * wakeup io worker thread */ jobp->job_func = fn; jobp->job_arg = arg; jobp->tpool = tpool; jobp->iod = iod; if (JOB_IO_READ == op) { jobp->io_op = JOB_IO_READ; jobp->io_poll_flags = PR_POLL_READ; } else if (JOB_IO_WRITE == op) { jobp->io_op = JOB_IO_WRITE; jobp->io_poll_flags = PR_POLL_WRITE; } else if (JOB_IO_ACCEPT == op) { jobp->io_op = JOB_IO_ACCEPT; jobp->io_poll_flags = PR_POLL_READ; } else if (JOB_IO_CONNECT == op) { jobp->io_op = JOB_IO_CONNECT; jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT; } else { delete_job(jobp); PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return NULL; } jobp->timeout = iod->timeout; if ((PR_INTERVAL_NO_TIMEOUT == iod->timeout) || (PR_INTERVAL_NO_WAIT == iod->timeout)) { jobp->absolute = iod->timeout; } else { now = PR_IntervalNow(); jobp->absolute = now + iod->timeout; } PR_Lock(tpool->ioq.lock); if (PR_CLIST_IS_EMPTY(&tpool->ioq.list) || (PR_INTERVAL_NO_TIMEOUT == iod->timeout)) { PR_APPEND_LINK(&jobp->links,&tpool->ioq.list); } else if (PR_INTERVAL_NO_WAIT == iod->timeout) { PR_INSERT_LINK(&jobp->links,&tpool->ioq.list); } else { PRCList *qp; PRJob *tmp_jobp; /* * insert into the timeout-sorted ioq */ for (qp = tpool->ioq.list.prev; qp != &tpool->ioq.list; qp = qp->prev) { tmp_jobp = JOB_LINKS_PTR(qp); if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { break; } } PR_INSERT_AFTER(&jobp->links,qp); } jobp->on_ioq = PR_TRUE; tpool->ioq.cnt++; /* * notify io worker thread(s) */ PR_Unlock(tpool->ioq.lock); notify_ioq(tpool); return jobp; }