static int confdb_purge(struct confdb_ctx *cdb) { int ret, i; TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_dn *dn; const char *attrs[] = { "dn", NULL }; tmp_ctx = talloc_new(NULL); dn = ldb_dn_new(tmp_ctx, cdb->ldb, "cn=config"); /* Get the list of all DNs */ ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } for(i=0; i<res->count; i++) { /* Delete this DN */ ret = ldb_delete(cdb->ldb, res->msgs[i]->dn); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } done: talloc_free(tmp_ctx); return ret; }
/* process modifies for one file */ static int process_file(struct ldb_context *ldb, FILE *f, int *count) { struct ldb_ldif *ldif; int ret = LDB_SUCCESS; while ((ldif = ldb_ldif_read_file(ldb, f))) { switch (ldif->changetype) { case LDB_CHANGETYPE_NONE: case LDB_CHANGETYPE_ADD: ret = ldb_add(ldb, ldif->msg); break; case LDB_CHANGETYPE_DELETE: ret = ldb_delete(ldb, ldif->msg->dn); break; case LDB_CHANGETYPE_MODIFY: ret = ldb_modify(ldb, ldif->msg); break; } if (ret != LDB_SUCCESS) { fprintf(stderr, "ERR: \"%s\" on DN %s\n", ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn)); failures++; } else { (*count)++; } ldb_ldif_read_free(ldb, ldif); } return ret; }
static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn) { int ret, i, total=0; const char *attrs[] = { NULL }; struct ldb_result *res; ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*"); if (ret != LDB_SUCCESS) return -1; /* sort the DNs, deepest first */ qsort(res->msgs, res->count, sizeof(res->msgs[0]), dn_cmp); for (i = 0; i < res->count; i++) { if (ldb_delete(ldb, res->msgs[i]->dn) == 0) { total++; } else { printf("Failed to delete '%s' - %s\n", ldb_dn_get_linearized(res->msgs[i]->dn), ldb_errstring(ldb)); } } talloc_free(res); if (total == 0) { return -1; } printf("Deleted %d records\n", total); return 0; }
static int confdb_write_ldif(struct confdb_ctx *cdb, const char *config_ldif, bool replace_whole_db) { int ret; struct ldb_ldif *ldif; while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) { if (ldif->changetype == LDB_CHANGETYPE_DELETE) { /* We should remove this section */ ret = ldb_delete(cdb->ldb, ldif->msg->dn); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* Removing a non-existing section is not an error */ ret = LDB_SUCCESS; } } else { ret = ldb_add(cdb->ldb, ldif->msg); if (ret != LDB_SUCCESS && replace_whole_db == false) { /* This section already existed, remove and re-add it. We * really want to replace the whole thing instead of messing * around with changetypes and flags on individual elements */ ret = ldb_delete(cdb->ldb, ldif->msg->dn); if (ret == LDB_SUCCESS) { ret = ldb_add(cdb->ldb, ldif->msg); } } } if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to initialize DB (%d,[%s]), aborting!\n", ret, ldb_errstring(cdb->ldb)); return EIO; } ldb_ldif_read_free(cdb->ldb, ldif); } return EOK; }
/* drsuapi_DsRemoveDSServer */ static WERROR dcesrv_drsuapi_DsRemoveDSServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsRemoveDSServer *r) { struct drsuapi_bind_state *b_state; struct dcesrv_handle *h; struct ldb_dn *ntds_dn; int ret; bool ok; WERROR status; ZERO_STRUCT(r->out.res); *r->out.level_out = 1; status = drs_security_level_check(dce_call, "DsRemoveDSServer"); if (!W_ERROR_IS_OK(status)) { return status; } DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); b_state = h->data; switch (r->in.level) { case 1: ntds_dn = ldb_dn_new(mem_ctx, b_state->sam_ctx, r->in.req->req1.server_dn); W_ERROR_HAVE_NO_MEMORY(ntds_dn); ok = ldb_dn_validate(ntds_dn); if (!ok) { return WERR_FOOBAR; } /* TODO: it's likely that we need more checks here */ ok = ldb_dn_add_child_fmt(ntds_dn, "CN=NTDS Settings"); if (!ok) { return WERR_FOOBAR; } if (r->in.req->req1.commit) { ret = ldb_delete(b_state->sam_ctx, ntds_dn); if (ret != LDB_SUCCESS) { return WERR_FOOBAR; } } return WERR_OK; default: break; } return WERR_FOOBAR; }
/* Remove a group mapping entry. */ static bool group_map_remove(const DOM_SID *sid) { struct ldb_dn *dn; int ret; dn = mapping_dn(ldb, sid); if (dn == NULL) { return False; } ret = ldb_delete(ldb, dn); talloc_free(dn); return ret == LDB_SUCCESS; }
int main(int argc, const char **argv) { struct ldb_context *ldb; int ret = 0, i; struct ldb_cmdline *options; ldb = ldb_init(NULL, NULL); options = ldb_cmdline_process(ldb, argc, argv, usage); if (options->argc < 1) { usage(); exit(1); } for (i=0;i<options->argc;i++) { struct ldb_dn *dn; dn = ldb_dn_new(ldb, ldb, options->argv[i]); if ( ! ldb_dn_validate(dn)) { printf("Invalid DN format\n"); exit(1); } if (options->recursive) { ret = ldb_delete_recursive(ldb, dn); } else { ret = ldb_delete(ldb, dn); if (ret == 0) { printf("Deleted 1 record\n"); } } if (ret != 0) { printf("delete of '%s' failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb)); } } talloc_free(ldb); return ret; }
static WERROR sptr_DeletePrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_DeleteForm *r) { struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context); struct ldb_message **msgs; const char * const attrs[] = { "flags", NULL}; int count, ret; enum spoolss_FormFlags flags; /* TODO: do checks access here * if (!(server->access_mask & desired_access)) { * return WERR_FOOBAR; * } */ if (!r->in.form_name) { return WERR_FOOBAR; } count = sptr_db_search(sptr_db, mem_ctx, ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"), &msgs, attrs, "(&(form-name=%s)(objectclass=form))", r->in.form_name); if (count == 0) return WERR_FOOBAR; if (count > 1) return WERR_FOOBAR; if (count < 0) return WERR_GENERAL_FAILURE; flags = ldb_msg_find_attr_as_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN); if (flags != SPOOLSS_FORM_USER) { return WERR_FOOBAR; } ret = ldb_delete(sptr_db, msgs[0]->dn); if (ret != 0) { return WERR_FOOBAR; } return WERR_OK; }
static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn) { int ret, i, total=0; const char *attrs[] = { NULL }; struct ldb_result *res; ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*"); if (ret != LDB_SUCCESS) return -1; for (i = 0; i < res->count; i++) { if (ldb_delete(ldb, res->msgs[i]->dn) == 0) { total++; } } talloc_free(res); if (total == 0) { return -1; } printf("Deleted %d records\n", total); return 0; }
static NTSTATUS sldb_remove(struct share_context *ctx, const char *name) { struct ldb_context *ldb; struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; NTSTATUS ret; int err; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { DEBUG(0,("ERROR: Out of memory!\n")); return NT_STATUS_NO_MEMORY; } ldb = talloc_get_type(ctx->priv_data, struct ldb_context); dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name); if (!dn) { DEBUG(0,("ERROR: Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } err = ldb_delete(ldb, dn); if (err != LDB_SUCCESS) { DEBUG(2,("ERROR: unable to remove share %s from share.ldb\n" " err=%d [%s]\n", name, err, ldb_errstring(ldb))); ret = NT_STATUS_UNSUCCESSFUL; goto done; } ret = NT_STATUS_OK; done: talloc_free(tmp_ctx); return ret; }
static NTSTATUS torture_leave_ads_domain(struct torture_context *torture, TALLOC_CTX *mem_ctx, struct libnet_JoinDomain *libnet_r) { int rtn; TALLOC_CTX *tmp_ctx; struct ldb_dn *server_dn; struct ldb_context *ldb_ctx; char *remote_ldb_url; /* Check if we are a domain controller. If not, exit. */ if (!libnet_r->out.server_dn_str) { return NT_STATUS_OK; } tmp_ctx = talloc_named(mem_ctx, 0, "torture_leave temporary context"); if (!tmp_ctx) { libnet_r->out.error_string = NULL; return NT_STATUS_NO_MEMORY; } ldb_ctx = ldb_init(tmp_ctx, torture->ev); if (!ldb_ctx) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } /* Remove CN=Servers,... entry from the AD. */ server_dn = ldb_dn_new(tmp_ctx, ldb_ctx, libnet_r->out.server_dn_str); if (! ldb_dn_validate(server_dn)) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s", libnet_r->out.samr_binding->host); if (!remote_ldb_url) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } ldb_set_opaque(ldb_ctx, "credentials", cmdline_credentials); ldb_set_opaque(ldb_ctx, "loadparm", cmdline_lp_ctx); rtn = ldb_connect(ldb_ctx, remote_ldb_url, 0, NULL); if (rtn != 0) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_UNSUCCESSFUL; } rtn = ldb_delete(ldb_ctx, server_dn); if (rtn != 0) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_UNSUCCESSFUL; } DEBUG(0, ("%s removed successfully.\n", libnet_r->out.server_dn_str)); talloc_free(tmp_ctx); return NT_STATUS_OK; }
int sysdb_check_upgrade_02(struct sss_domain_info *domains, const char *db_path) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_context *ldb; char *ldb_file; struct sysdb_ctx *sysdb; struct sss_domain_info *dom; struct ldb_message_element *el; struct ldb_message *msg; struct ldb_result *res; struct ldb_dn *verdn; const char *version = NULL; bool do_02_upgrade = false; bool ctx_trans = false; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_get_db_file(tmp_ctx, "local", "UPGRADE", db_path, &ldb_file); if (ret != EOK) { goto exit; } ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb); if (ret != EOK) { DEBUG(1, ("sysdb_ldb_connect failed.\n")); return ret; } verdn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); if (!verdn) { ret = EIO; goto exit; } ret = ldb_search(ldb, tmp_ctx, &res, verdn, LDB_SCOPE_BASE, NULL, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto exit; } if (res->count > 1) { ret = EIO; goto exit; } if (res->count == 1) { el = ldb_msg_find_element(res->msgs[0], "version"); if (el) { if (el->num_values != 1) { ret = EINVAL; goto exit; } version = talloc_strndup(tmp_ctx, (char *)(el->values[0].data), el->values[0].length); if (!version) { ret = ENOMEM; goto exit; } if (strcmp(version, SYSDB_VERSION) == 0) { /* all fine, return */ ret = EOK; goto exit; } DEBUG(4, ("Upgrading DB from version: %s\n", version)); if (strcmp(version, SYSDB_VERSION_0_1) == 0) { /* convert database */ ret = sysdb_upgrade_01(ldb, &version); if (ret != EOK) goto exit; } if (strcmp(version, SYSDB_VERSION_0_2) == 0) { /* need to convert database to split files */ do_02_upgrade = true; } } } if (!do_02_upgrade) { /* not a v2 upgrade, return and let the normal code take over any * further upgrade */ ret = EOK; goto exit; } /* == V2->V3 UPGRADE == */ DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3)); /* ldb uses posix locks, * posix is stupid and kills all locks when you close *any* file * descriptor associated to the same file. * Therefore we must close and reopen the ldb file here */ /* == Backup and reopen ldb == */ /* close */ talloc_zfree(ldb); /* backup*/ ret = backup_file(ldb_file, 0); if (ret != EOK) { goto exit; } /* reopen */ ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb); if (ret != EOK) { DEBUG(1, ("sysdb_ldb_connect failed.\n")); return ret; } /* open a transaction */ ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret)); ret = EIO; goto exit; } /* == Upgrade contents == */ for (dom = domains; dom; dom = dom->next) { struct ldb_dn *domain_dn; struct ldb_dn *users_dn; struct ldb_dn *groups_dn; int i; /* skip local */ if (strcasecmp(dom->provider, "local") == 0) { continue; } /* create new dom db */ ret = sysdb_domain_init_internal(tmp_ctx, dom, db_path, false, &sysdb); if (ret != EOK) { goto done; } ret = ldb_transaction_start(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret)); ret = EIO; goto done; } ctx_trans = true; /* search all entries for this domain in local, * copy them all in the new database, * then remove them from local */ domain_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, sysdb->domain->name); if (!domain_dn) { ret = ENOMEM; goto done; } ret = ldb_search(ldb, tmp_ctx, &res, domain_dn, LDB_SCOPE_SUBTREE, NULL, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } users_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_USER_BASE, sysdb->domain->name); if (!users_dn) { ret = ENOMEM; goto done; } groups_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_GROUP_BASE, sysdb->domain->name); if (!groups_dn) { ret = ENOMEM; goto done; } for (i = 0; i < res->count; i++) { struct ldb_dn *orig_dn; msg = res->msgs[i]; /* skip pre-created congtainers */ if ((ldb_dn_compare(msg->dn, domain_dn) == 0) || (ldb_dn_compare(msg->dn, users_dn) == 0) || (ldb_dn_compare(msg->dn, groups_dn) == 0)) { continue; } /* regenerate the DN against the new ldb as it may have different * casefolding rules (example: name changing from case insensitive * to case sensitive) */ orig_dn = msg->dn; msg->dn = ldb_dn_new(msg, sysdb->ldb, ldb_dn_get_linearized(orig_dn)); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_add(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(0, ("WARNING: Could not add entry %s," " to new ldb file! (%d [%s])\n", ldb_dn_get_linearized(msg->dn), ret, ldb_errstring(sysdb->ldb))); } ret = ldb_delete(ldb, orig_dn); if (ret != LDB_SUCCESS) { DEBUG(0, ("WARNING: Could not remove entry %s," " from old ldb file! (%d [%s])\n", ldb_dn_get_linearized(orig_dn), ret, ldb_errstring(ldb))); } } /* now remove the basic containers from local */ /* these were optional so debug at level 9 in case * of failure just for tracing */ ret = ldb_delete(ldb, groups_dn); if (ret != LDB_SUCCESS) { DEBUG(9, ("WARNING: Could not remove entry %s," " from old ldb file! (%d [%s])\n", ldb_dn_get_linearized(groups_dn), ret, ldb_errstring(ldb))); } ret = ldb_delete(ldb, users_dn); if (ret != LDB_SUCCESS) { DEBUG(9, ("WARNING: Could not remove entry %s," " from old ldb file! (%d [%s])\n", ldb_dn_get_linearized(users_dn), ret, ldb_errstring(ldb))); } ret = ldb_delete(ldb, domain_dn); if (ret != LDB_SUCCESS) { DEBUG(9, ("WARNING: Could not remove entry %s," " from old ldb file! (%d [%s])\n", ldb_dn_get_linearized(domain_dn), ret, ldb_errstring(ldb))); } ret = ldb_transaction_commit(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret)); ret = EIO; goto done; } ctx_trans = false; talloc_zfree(domain_dn); talloc_zfree(groups_dn); talloc_zfree(users_dn); talloc_zfree(res); } /* conversion done, upgrade version number */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_3); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_transaction_commit(ldb); if (ret != LDB_SUCCESS) { DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret)); ret = EIO; goto exit; } ret = EOK; done: if (ret != EOK) { if (ctx_trans) { ret = ldb_transaction_cancel(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret)); } } ret = ldb_transaction_cancel(ldb); if (ret != LDB_SUCCESS) { DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret)); } } exit: talloc_free(tmp_ctx); return ret; }
int sysdb_upgrade_10(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_result *res; struct ldb_message *msg; struct ldb_message *user; struct ldb_message_element *memberof_el; const char *name; struct ldb_dn *basedn; const char *filter = "(&(objectClass=user)(!(uidNumber=*))(memberOf=*))"; const char *attrs[] = { "name", "memberof", NULL }; int i, j; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_USER_BASE, sysdb->domain->name); if (basedn == NULL) { ret = EIO; goto done; } DEBUG(SSSDBG_CRIT_FAILURE, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_11)); ret = ldb_transaction_start(sysdb->ldb); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "%s", filter); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } for (i = 0; i < res->count; i++) { user = res->msgs[i]; memberof_el = ldb_msg_find_element(user, "memberof"); name = ldb_msg_find_attr_as_string(user, "name", NULL); if (name == NULL) { ret = EIO; goto done; } for (j = 0; j < memberof_el->num_values; j++) { msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]); if (msg->dn == NULL) { ret = ENOMEM; goto done; } if (!ldb_dn_validate(msg->dn)) { DEBUG(SSSDBG_MINOR_FAILURE, ("DN validation failed during " "upgrade: [%s]\n", memberof_el->values[j].data)); talloc_zfree(msg); continue; } ret = ldb_msg_add_empty(msg, "ghost", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "ghost", name); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "member", LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "member", ldb_dn_get_linearized(user->dn)); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); talloc_zfree(msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } ret = ldb_delete(sysdb->ldb, user->dn); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } /* conversion done, upgrade version number */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_11); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = EOK; done: ret = finish_upgrade(ret, sysdb->ldb, SYSDB_VERSION_0_11, ver); talloc_free(tmp_ctx); return ret; }
int ctl_cmd_parse(struct data_node *p_node) { int ret = 0; unsigned int loop = 0; int ok = 0; unsigned int i, j = 0; int offset = 0; size_t mlen = 0; char *p_new = NULL; char *p_old = NULL; char *result = NULL; char ret_number[16] = { 0 }; int size = 0; int sum = 0; if (p_node->status == X_MALLOC_FAILED) { add_send_node(p_node, OPT_NO_MEMORY, strlen(OPT_NO_MEMORY)); return X_MALLOC_FAILED; } if (p_node->gtlen > MAX_CMD_LEN) { add_send_node(p_node, OPT_DATA_TOO_LARGE, strlen(OPT_DATA_TOO_LARGE)); return X_DATA_TOO_LARGE; } /* parse cmd */ char *data = p_node->svbf; log_debug("%s", data); if (data[0] == '*') { // 1. read the arg count: if (p_node->kvs == 0) { p_new = p_old = &data[1]; CHECK_BUFFER(p_new, 0); p_node->kvs = atoi(p_old); p_node->doptr = p_new - data; } // 2. read the request name if (p_node->cmd == 0) { if (data[p_node->doptr] != '$') { goto E_OUT_PUT; } p_new = p_old = &data[p_node->doptr + 1]; CHECK_BUFFER(p_new, 0); mlen = atoi(p_old); p_old = p_new; CHECK_BUFFER(p_new, mlen); for (i = 0; i < mlen; i++) { if (*(p_old + i) > 'Z') { *(p_old + i) -= 32;/* 'A' - 'a' */ } p_node->cmd = p_node->cmd * 26 + (*(p_old + i) - 'A');/* A~Z is 26 numbers */ } p_node->doptr = p_new - data; }log_debug("%d", p_node->cmd); // 3. read a arg switch (p_node->cmd) { case LDB_SET: if (LDB_READONLY_SWITCH == 1 || p_node->kvs != LDB_SET_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); PARSE_LEN(p_node->vlen); PARSE_MEMBER(p_node->val, p_node->vlen); // x_out_time(&g_dbg_time); ok = ldb_put(g_ldb, &data[p_node->key], p_node->klen, &data[p_node->val], p_node->vlen); // x_out_time(&g_dbg_time); goto W_OUT_PUT; case LDB_DEL: if (LDB_READONLY_SWITCH == 1 || p_node->kvs < LDB_DEL_MIN) { goto E_OUT_PUT; } loop = p_node->kvs - 1; sum = 0; for (j = 0; j < loop; ++j) { PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); ok = ldb_delete(g_ldb, &data[p_node->key], p_node->klen); if (ok < 0) { goto E_OUT_PUT; } sum += ok; p_node->kvs -= 1; p_node->key = 0; p_node->klen = 0; } goto NUM_OUT_PUT; case LDB_MSET:/* use one thread to write, otherwise (one thread should use one leveldb_writebatch_t) or (add a mutex lock) */ if (LDB_READONLY_SWITCH == 1) { goto E_OUT_PUT; } loop = (p_node->kvs - 1) / 2; if (loop < 1) { goto E_OUT_PUT; } for (j = 0; j < loop; ++j) { PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); PARSE_LEN(p_node->vlen); PARSE_MEMBER(p_node->val, p_node->vlen); ldb_batch_put(g_ldb, &data[p_node->key], p_node->klen, &data[p_node->val], p_node->vlen); p_node->kvs -= 2; p_node->klen = 0; p_node->key = 0; p_node->vlen = 0; p_node->val = 0; } ok = ldb_batch_commit(g_ldb); goto W_OUT_PUT; case LDB_GET: if (p_node->kvs != LDB_GET_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); log_debug("key = %s", &data[ p_node->key ]); result = ldb_get(g_ldb, &data[p_node->key], p_node->klen, &size); log_debug("val = %s", result); goto R_BULK_OUT_PUT; case LDB_LRANGE: if (p_node->kvs != LDB_LRANGE_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); /* look as prefix key */ PARSE_LEN(p_node->vlen); PARSE_MEMBER(p_node->val, p_node->vlen); /* look as start time */ PARSE_LEN(p_node->vlen2); PARSE_MEMBER(p_node->val2, p_node->vlen2); /* look as end time */ log_debug("prefix key = %s", &data[ p_node->key ]); log_debug("start = %s", &data[ p_node->val ]); log_debug("end = %s", &data[ p_node->val2 ]); result = ldb_lrangeget(g_ldb, &data[p_node->key], p_node->klen, &data[p_node->val], p_node->vlen, &data[p_node->val2], p_node->vlen2, &size); goto R_MULTI_OUT_PUT; case LDB_KEYS: if (p_node->kvs != LDB_KEYS_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); result = ldb_keys(g_ldb, &data[p_node->key], p_node->klen, &size); log_debug("size = %d", size); goto R_MULTI_OUT_PUT; case LDB_INFO: if (p_node->kvs != LDB_INFO_CNT) { goto E_OUT_PUT; } result = ldb_info(g_ldb, &size); log_debug("size = %d\n", size); goto R_MULTI_OUT_PUT; case LDB_PING: if (p_node->kvs != LDB_PING_CNT) { goto E_OUT_PUT; } add_send_node(p_node, OPT_PONG, strlen(OPT_PONG)); return X_DATA_IS_ALL; case LDB_EXISTS: if (p_node->kvs != LDB_EXISTS_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); ok = ldb_exists(g_ldb, &data[p_node->key], p_node->klen); if (ok == -1) { goto E_OUT_PUT; } sum = ok; goto NUM_OUT_PUT; case LDB_QUIT: log_debug("-----------------------------------------------------"); return X_CLIENT_QUIT; default: goto E_OUT_PUT; } E_OUT_PUT: add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR)); return X_ERROR_CMD; W_OUT_PUT: if (ok == 0) { log_debug("------------------------------------------"); add_send_node(p_node, OPT_OK, strlen(OPT_OK)); return X_DATA_IS_ALL; } else { add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR)); return X_ERROR_LDB; } NUM_OUT_PUT: sprintf(ret_number, OPT_NUMBER, sum); log_debug("%s", ret_number); add_send_node(p_node, ret_number, strlen(ret_number)); return X_DATA_IS_ALL; R_BULK_OUT_PUT: if (result) { char tmp[32] = { 0 }; sprintf(tmp, "$%d\r\n", size); ret = add_send_node(p_node, tmp, strlen(tmp)); ret = add_send_node(p_node, result, size); leveldb_free(result); if (ret == X_MALLOC_FAILED) { clean_send_node(p_node); add_send_node(p_node, OPT_NO_MEMORY, strlen(OPT_NO_MEMORY)); return X_MALLOC_FAILED; } ret = add_send_node(p_node, "\r\n", 2); return X_DATA_IS_ALL; } else { if (size == 0) { add_send_node(p_node, OPT_NULL, strlen(OPT_NULL)); return X_DATA_IS_ALL; } else { add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR)); return X_ERROR_LDB; } } R_MULTI_OUT_PUT: if (result) { set_send_node(p_node, result, size); return X_DATA_IS_ALL; } else { if (size == 0) { add_send_node(p_node, OPT_NULL, strlen(OPT_NULL)); return X_DATA_IS_ALL; } else { add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR)); return X_ERROR_LDB; } } } else if (data[0] == '$') { #if 0 // 1. read the request name if (p_node->cmd == 0) { p_new = p_old = &data[1]; CHECK_BUFFER(p_new, 0); mlen = atoi( p_old ); p_old = p_new; CHECK_BUFFER(p_new, mlen); for (i = 0; i < mlen; i++) { p_node->cmd = p_node->cmd * 26 + ( *(p_old + i) - 'A' );/* A~Z is 26 numbers */ } p_node->doptr = p_new - data; } log_debug("%d\n", p_node->cmd); // 2. read a arg switch (p_node->cmd) { case LDB_QUIT: return CLIENT_QUIT; default: log_debug("-----------------------------------------------------\n"); return -1; } //TODO #endif add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR)); return X_ERROR_CMD; } else { add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR)); return X_ERROR_CMD; } return X_DATA_IS_ALL; }
/* remember an established session key for a netr server authentication use a simple ldb structure */ NTSTATUS schannel_store_session_key_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct creds_CredentialState *creds) { struct ldb_message *msg; struct ldb_val val, seed, client_state, server_state; char *f; char *sct; int ret; f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags); if (f == NULL) { return NT_STATUS_NO_MEMORY; } sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type); if (sct == NULL) { return NT_STATUS_NO_MEMORY; } msg = ldb_msg_new(ldb); if (msg == NULL) { return NT_STATUS_NO_MEMORY; } msg->dn = ldb_dn_new_fmt(msg, ldb, "computerName=%s", creds->computer_name); if ( ! msg->dn) { return NT_STATUS_NO_MEMORY; } val.data = creds->session_key; val.length = sizeof(creds->session_key); seed.data = creds->seed.data; seed.length = sizeof(creds->seed.data); client_state.data = creds->client.data; client_state.length = sizeof(creds->client.data); server_state.data = creds->server.data; server_state.length = sizeof(creds->server.data); ldb_msg_add_string(msg, "objectClass", "schannelState"); ldb_msg_add_value(msg, "sessionKey", &val, NULL); ldb_msg_add_value(msg, "seed", &seed, NULL); ldb_msg_add_value(msg, "clientState", &client_state, NULL); ldb_msg_add_value(msg, "serverState", &server_state, NULL); ldb_msg_add_string(msg, "negotiateFlags", f); ldb_msg_add_string(msg, "secureChannelType", sct); ldb_msg_add_string(msg, "accountName", creds->account_name); ldb_msg_add_string(msg, "computerName", creds->computer_name); ldb_msg_add_string(msg, "flatname", creds->domain); samdb_msg_add_dom_sid(ldb, mem_ctx, msg, "objectSid", creds->sid); ldb_delete(ldb, msg->dn); ret = ldb_add(ldb, msg); if (ret != 0) { DEBUG(0,("Unable to add %s to session key db - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } return NT_STATUS_OK; }
static int local_db_delete(TALLOC_CTX *mem_ctx, struct local_context *lctx, const char *req_path) { TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; static const char *attrs[] = { NULL }; struct ldb_result *res; int ret; DEBUG(SSSDBG_TRACE_FUNC, "Removing a secret from [%s]\n", req_path); tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) return ENOMEM; ret = local_db_dn(mem_ctx, lctx->ldb, req_path, &dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Searching for [%s] at [%s] with scope=base\n", LOCAL_CONTAINER_FILTER, ldb_dn_get_linearized(dn)); ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, LOCAL_CONTAINER_FILTER); if (ret != EOK) { DEBUG(SSSDBG_TRACE_LIBS, "ldb_search returned %d: %s\n", ret, ldb_strerror(ret)); goto done; } if (res->count == 1) { DEBUG(SSSDBG_TRACE_INTERNAL, "Searching for children of [%s]\n", ldb_dn_get_linearized(dn)); ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL, attrs, NULL); if (ret != EOK) { DEBUG(SSSDBG_TRACE_LIBS, "ldb_search returned %d: %s\n", ret, ldb_strerror(ret)); goto done; } if (res->count > 0) { ret = EEXIST; DEBUG(SSSDBG_OP_FAILURE, "Failed to remove '%s': Container is not empty\n", ldb_dn_get_linearized(dn)); goto done; } } ret = ldb_delete(lctx->ldb, dn); if (ret != EOK) { DEBUG(SSSDBG_TRACE_LIBS, "ldb_delete returned %d: %s\n", ret, ldb_strerror(ret)); /* fallthrough */ } ret = sysdb_error_to_errno(ret); done: talloc_free(tmp_ctx); return ret; }