📄 ldb_ldap.c
字号:
return lldb_ldap_to_ldb(ret);}/* rename a record*/static int lldb_rename(struct ldb_module *module, struct ldb_request *req){ struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private); struct lldb_context *lldb_ac; char *old_dn; char *newrdn; char *parentdn; int ret; /* ltdb specials should not reach this point */ if (ldb_dn_is_special(req->op.rename.olddn) || ldb_dn_is_special(req->op.rename.newdn)) { return LDB_ERR_INVALID_DN_SYNTAX; } lldb_ac = init_lldb_handle(lldb, req); if (lldb_ac == NULL) { return LDB_ERR_OPERATIONS_ERROR; } old_dn = ldb_dn_alloc_linearized(lldb_ac, req->op.rename.olddn); if (old_dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } newrdn = talloc_asprintf(lldb_ac, "%s=%s", ldb_dn_get_rdn_name(req->op.rename.newdn), ldb_dn_escape_value(lldb, *(ldb_dn_get_rdn_val(req->op.rename.newdn)))); if (!newrdn) { return LDB_ERR_OPERATIONS_ERROR; } parentdn = ldb_dn_alloc_linearized(lldb_ac, ldb_dn_get_parent(lldb_ac, req->op.rename.newdn)); if (!parentdn) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldap_rename(lldb->ldap, old_dn, newrdn, parentdn, 1, NULL, NULL, &lldb_ac->msgid); if (ret != LDAP_SUCCESS) { ldb_set_errstring(module->ldb, ldap_err2string(ret)); } return lldb_ldap_to_ldb(ret);}static int lldb_parse_result(struct lldb_context *ac, LDAPMessage *result){ struct ldb_handle *handle = ac->handle; struct lldb_private *lldb = ac->lldb; struct ldb_reply *ares = NULL; LDAPMessage *msg; int type; char *matcheddnp = NULL; char *errmsgp = NULL; char **referralsp = NULL; LDAPControl **serverctrlsp = NULL; int ret = LDB_SUCCESS; type = ldap_msgtype(result); handle->status = 0; switch (type) { case LDAP_RES_SEARCH_ENTRY: msg = ldap_first_entry(lldb->ldap, result); if (msg != NULL) { BerElement *berptr = NULL; char *attr, *dn; ares = talloc_zero(ac, struct ldb_reply); if (!ares) { ret = LDB_ERR_OPERATIONS_ERROR; goto error; } ares->message = ldb_msg_new(ares); if (!ares->message) { ret = LDB_ERR_OPERATIONS_ERROR; goto error; } dn = ldap_get_dn(lldb->ldap, msg); if (!dn) { ret = LDB_ERR_OPERATIONS_ERROR; goto error; } ares->message->dn = ldb_dn_new(ares->message, ac->lldb->module->ldb, dn); if ( ! ldb_dn_validate(ares->message->dn)) { ret = LDB_ERR_OPERATIONS_ERROR; goto error; } ldap_memfree(dn); ares->message->num_elements = 0; ares->message->elements = NULL; /* loop over all attributes */ for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr); attr; attr=ldap_next_attribute(lldb->ldap, msg, berptr)) { struct berval **bval; bval = ldap_get_values_len(lldb->ldap, msg, attr); if (bval) { lldb_add_msg_attr(ac->lldb->module->ldb, ares->message, attr, bval); ldap_value_free_len(bval); } } if (berptr) ber_free(berptr, 0); ares->type = LDB_REPLY_ENTRY; ret = ac->callback(ac->lldb->module->ldb, ac->context, ares); } else { handle->status = LDB_ERR_PROTOCOL_ERROR; handle->state = LDB_ASYNC_DONE; } break; case LDAP_RES_SEARCH_REFERENCE: if (ldap_parse_result(lldb->ldap, result, &handle->status, &matcheddnp, &errmsgp, &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { ret = LDB_ERR_OPERATIONS_ERROR; goto error; } if (referralsp == NULL) { handle->status = LDB_ERR_PROTOCOL_ERROR; goto error; } ares = talloc_zero(ac, struct ldb_reply); if (!ares) { ret = LDB_ERR_OPERATIONS_ERROR; goto error; } ares->referral = talloc_strdup(ares, *referralsp); ares->type = LDB_REPLY_REFERRAL; ret = ac->callback(ac->lldb->module->ldb, ac->context, ares); break; case LDAP_RES_SEARCH_RESULT: if (ldap_parse_result(lldb->ldap, result, &handle->status, &matcheddnp, &errmsgp, &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { handle->status = LDB_ERR_OPERATIONS_ERROR; goto error; } ares = talloc_zero(ac, struct ldb_reply); if (!ares) { ret = LDB_ERR_OPERATIONS_ERROR; goto error; } if (serverctrlsp != NULL) { /* FIXME: transform the LDAPControl list into an ldb_control one */ ares->controls = NULL; } ares->type = LDB_REPLY_DONE; handle->state = LDB_ASYNC_DONE; ret = ac->callback(ac->lldb->module->ldb, ac->context, ares); break; case LDAP_RES_MODIFY: case LDAP_RES_ADD: case LDAP_RES_DELETE: case LDAP_RES_MODDN: if (ldap_parse_result(lldb->ldap, result, &handle->status, &matcheddnp, &errmsgp, &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { handle->status = LDB_ERR_OPERATIONS_ERROR; goto error; } if (ac->callback && handle->status == LDB_SUCCESS) { ares = NULL; /* FIXME: build a corresponding ares to pass on */ ret = ac->callback(ac->lldb->module->ldb, ac->context, ares); } handle->state = LDB_ASYNC_DONE; break; default: ret = LDB_ERR_PROTOCOL_ERROR; goto error; } if (matcheddnp) ldap_memfree(matcheddnp); if (errmsgp && *errmsgp) { ldb_set_errstring(ac->lldb->module->ldb, errmsgp); } else if (handle->status) { ldb_set_errstring(ac->lldb->module->ldb, ldap_err2string(handle->status)); } if (errmsgp) { ldap_memfree(errmsgp); } if (referralsp) ldap_value_free(referralsp); if (serverctrlsp) ldap_controls_free(serverctrlsp); ldap_msgfree(result); return lldb_ldap_to_ldb(handle->status);error: handle->state = LDB_ASYNC_DONE; ldap_msgfree(result); return ret;}static int lldb_wait(struct ldb_handle *handle, enum ldb_wait_type type){ struct lldb_context *ac = talloc_get_type(handle->private_data, struct lldb_context); struct lldb_private *lldb = ac->lldb; struct timeval timeout; LDAPMessage *result; int ret, lret; if (handle->state == LDB_ASYNC_DONE) { return handle->status; } if (!ac || !ac->msgid) { return LDB_ERR_OPERATIONS_ERROR; } handle->state = LDB_ASYNC_PENDING; handle->status = LDB_SUCCESS; switch(type) { case LDB_WAIT_NONE: if ((ac->timeout != -1) && ((ac->starttime + ac->timeout) > time(NULL))) { return LDB_ERR_TIME_LIMIT_EXCEEDED; } timeout.tv_sec = 0; timeout.tv_usec = 0; lret = ldap_result(lldb->ldap, ac->msgid, 0, &timeout, &result); if (lret == -1) { return LDB_ERR_OPERATIONS_ERROR; } if (lret == 0) { ret = LDB_SUCCESS; goto done; } return lldb_parse_result(ac, result); case LDB_WAIT_ALL: timeout.tv_usec = 0; ret = LDB_ERR_OPERATIONS_ERROR; while (handle->status == LDB_SUCCESS && handle->state != LDB_ASYNC_DONE) { if (ac->timeout == -1) { lret = ldap_result(lldb->ldap, ac->msgid, 0, NULL, &result); } else { timeout.tv_sec = ac->timeout - (time(NULL) - ac->starttime); if (timeout.tv_sec <= 0) return LDB_ERR_TIME_LIMIT_EXCEEDED; lret = ldap_result(lldb->ldap, ac->msgid, 0, &timeout, &result); } if (lret == -1) { return LDB_ERR_OPERATIONS_ERROR; } if (lret == 0) { return LDB_ERR_TIME_LIMIT_EXCEEDED; } ret = lldb_parse_result(ac, result); if (ret != LDB_SUCCESS) { return ret; } } break; default: handle->state = LDB_ASYNC_DONE; ret = LDB_ERR_OPERATIONS_ERROR; }done: return ret;}static int lldb_start_trans(struct ldb_module *module){ /* TODO implement a local transaction mechanism here */ return LDB_SUCCESS;}static int lldb_end_trans(struct ldb_module *module){ /* TODO implement a local transaction mechanism here */ return LDB_SUCCESS;}static int lldb_del_trans(struct ldb_module *module){ /* TODO implement a local transaction mechanism here */ return LDB_SUCCESS;}static int lldb_request(struct ldb_module *module, struct ldb_request *req){ return LDB_ERR_OPERATIONS_ERROR;}static const struct ldb_module_ops lldb_ops = { .name = "ldap", .search = lldb_search, .add = lldb_add, .modify = lldb_modify, .del = lldb_delete, .rename = lldb_rename, .request = lldb_request, .start_transaction = lldb_start_trans, .end_transaction = lldb_end_trans, .del_transaction = lldb_del_trans, .wait = lldb_wait};static int lldb_destructor(struct lldb_private *lldb){ ldap_unbind(lldb->ldap); return 0;}/* connect to the database*/static int lldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[], struct ldb_module **_module){ struct ldb_module *module; struct lldb_private *lldb; int version = 3; int ret; module = talloc(ldb, struct ldb_module); if (module == NULL) { ldb_oom(ldb); talloc_free(lldb); return -1; } talloc_set_name_const(module, "ldb_ldap backend"); module->ldb = ldb; module->prev = module->next = NULL; module->private_data = NULL; module->ops = &lldb_ops; lldb = talloc(module, struct lldb_private); if (!lldb) { ldb_oom(ldb); goto failed; } module->private_data = lldb; lldb->module = module; lldb->ldap = NULL; ret = ldap_initialize(&lldb->ldap, url); if (ret != LDAP_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s\n", url, ldap_err2string(ret)); goto failed; } talloc_set_destructor(lldb, lldb_destructor); ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); if (ret != LDAP_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s\n", ldap_err2string(ret)); goto failed; } *_module = module; return 0;failed: talloc_free(module); return -1;}const struct ldb_backend_ops ldb_ldap_backend_ops = { .name = "ldap", .connect_fn = lldb_connect};const struct ldb_backend_ops ldb_ldapi_backend_ops = { .name = "ldapi", .connect_fn = lldb_connect};const struct ldb_backend_ops ldb_ldaps_backend_ops = { .name = "ldaps", .connect_fn = lldb_connect};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -