} END_TEST // ^ Unit test ---------------------------------------------------------------- // v Suite definition --------------------------------------------------------- static void create_ldb_from_ldif(const char *ldb_path, const char *ldif_path, const char *default_context, const char *root_context) { FILE *f; struct ldb_ldif *ldif; struct ldb_context *ldb_ctx = NULL; TALLOC_CTX *local_mem_ctx = talloc_new(NULL); struct ldb_message *msg; ldb_ctx = ldb_init(local_mem_ctx, NULL); ldb_connect(ldb_ctx, ldb_path, 0, 0); f = fopen(ldif_path, "r"); msg = ldb_msg_new(local_mem_ctx); msg->dn = ldb_dn_new(msg, ldb_ctx, "@INDEXLIST"); ldb_msg_add_string(msg, "@IDXATTR", "cn"); ldb_msg_add_string(msg, "@IDXATTR", "oleguid"); ldb_msg_add_string(msg, "@IDXATTR", "mappedId"); msg->elements[0].flags = LDB_FLAG_MOD_ADD; ldb_add(ldb_ctx, msg); while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) { struct ldb_message *normalized_msg; ldb_msg_normalize(ldb_ctx, local_mem_ctx, ldif->msg, &normalized_msg); ldb_add(ldb_ctx, normalized_msg); talloc_free(normalized_msg); ldb_ldif_read_free(ldb_ctx, ldif); } if (default_context && root_context) { msg = ldb_msg_new(local_mem_ctx); msg->dn = ldb_dn_new(msg, ldb_ctx, "@ROOTDSE"); ldb_msg_add_string(msg, "defaultNamingContext", default_context); ldb_msg_add_string(msg, "rootDomainNamingContext", root_context); msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; ldb_add(ldb_ctx, msg); } fclose(f); talloc_free(local_mem_ctx); }
/** \details Save (commit) message in openchangedb database \param msg the message object \param SaveFlags flags associated to the save operation \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_message_save(void *_msg, uint8_t SaveFlags) { struct openchangedb_message *msg = (struct openchangedb_message *)_msg; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!msg, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!msg->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); switch (msg->status) { case OPENCHANGEDB_MESSAGE_CREATE: OPENCHANGE_RETVAL_IF(!msg->msg, MAPI_E_NOT_INITIALIZED, NULL); if (ldb_add(msg->ldb_ctx, msg->msg) != LDB_SUCCESS) { return MAPI_E_CALL_FAILED; } break; case OPENCHANGEDB_MESSAGE_OPEN: if (ldb_modify(msg->ldb_ctx, msg->res->msgs[0]) != LDB_SUCCESS) { return MAPI_E_CALL_FAILED; } break; } /* FIXME: Deal with SaveFlags */ return MAPI_E_SUCCESS; }
/* add records from an opened file */ static int process_file(struct ldb_context *ldb, FILE *f, int *count, int *failures) { struct ldb_ldif *ldif; int ret = LDB_SUCCESS; while ((ldif = ldb_ldif_read_file(ldb, f))) { if (ldif->changetype != LDB_CHANGETYPE_ADD && ldif->changetype != LDB_CHANGETYPE_NONE) { fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n"); break; } ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg); ret = ldb_add(ldb, ldif->msg); if (ret != LDB_SUCCESS) { fprintf(stderr, "ERR: \"%s\" on DN %s\n", ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn)); (*failures)++; } else { (*count)++; } ldb_ldif_read_free(ldb, ldif); } return ret; }
/* add a new record */ static isc_result_t b9_add_record(struct dlz_bind9_data *state, const char *name, struct ldb_dn *dn, struct dnsp_DnssrvRpcRecord *rec) { struct ldb_message *msg; enum ndr_err_code ndr_err; struct ldb_val v; int ret; msg = ldb_msg_new(rec); if (msg == NULL) { return ISC_R_NOMEMORY; } msg->dn = dn; ret = ldb_msg_add_string(msg, "objectClass", "dnsNode"); if (ret != LDB_SUCCESS) { return ISC_R_FAILURE; } ndr_err = ndr_push_struct_blob(&v, rec, rec, (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ISC_R_FAILURE; } ret = ldb_msg_add_value(msg, "dnsRecord", &v, NULL); if (ret != LDB_SUCCESS) { return ISC_R_FAILURE; } ret = ldb_add(state->samdb, msg); if (ret != LDB_SUCCESS) { return ISC_R_FAILURE; } return ISC_R_SUCCESS; }
/* 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 bool ldb_add_record(struct ldb_context *ldb, unsigned rid) { struct ldb_message *msg; int ret; msg = ldb_msg_new(ldb); if (msg == NULL) { return false; } msg->dn = ldb_dn_new_fmt(msg, ldb, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", rid); if (msg->dn == NULL) { return false; } if (ldb_msg_add_fmt(msg, "UID", "%u", rid) != 0) { return false; } ret = ldb_add(ldb, msg); talloc_free(msg); return ret == LDB_SUCCESS; }
/* setup some initial ldif in a ldb */ int gendb_add_ldif(struct ldb_context *ldb, const char *ldif_string) { struct ldb_ldif *ldif; int ret; ldif = ldb_ldif_read_string(ldb, &ldif_string); if (ldif == NULL) return -1; ret = ldb_add(ldb, ldif->msg); talloc_free(ldif); return ret; }
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; }
/** \details return the mapped property ID matching the nameid structure passed in parameter. \param ldb_ctx pointer to the namedprops ldb context \param nameid the MAPINAMEID structure to lookup \param propID pointer to the property ID the function returns \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ _PUBLIC_ enum mapistore_error mapistore_namedprops_create_id(struct ldb_context *ldb_ctx, struct MAPINAMEID nameid, uint16_t mapped_id) { int ret; TALLOC_CTX *mem_ctx; char *ldif_record; struct ldb_ldif *ldif; char *hex_id, *dec_id, *dec_mappedid, *guid; struct ldb_message *normalized_msg; const char *ldif_records[] = { NULL, NULL }; mem_ctx = talloc_zero(NULL, TALLOC_CTX); dec_mappedid = talloc_asprintf(mem_ctx, "%u", mapped_id); guid = GUID_string(mem_ctx, &nameid.lpguid); switch (nameid.ulKind) { case MNID_ID: hex_id = talloc_asprintf(mem_ctx, "%.4x", nameid.kind.lid); dec_id = talloc_asprintf(mem_ctx, "%u", nameid.kind.lid); ldif_record = talloc_asprintf(mem_ctx, "dn: CN=0x%s,CN=%s,CN=default\nobjectClass: MNID_ID\ncn: 0x%s\npropType: PT_NULL\noleguid: %s\nmappedId: %s\npropId: %s\n", hex_id, guid, hex_id, guid, dec_mappedid, dec_id); break; case MNID_STRING: ldif_record = talloc_asprintf(mem_ctx, "dn: CN=%s,CN=%s,CN=default\nobjectClass: MNID_STRING\ncn: %s\npropType: PT_NULL\noleguid: %s\nmappedId: %s\npropName: %s\n", nameid.kind.lpwstr.Name, guid, nameid.kind.lpwstr.Name, guid, dec_mappedid, nameid.kind.lpwstr.Name); break; default: abort(); } DEBUG(5, ("inserting record:\n%s\n", ldif_record)); ldif_records[0] = ldif_record; ldif = ldb_ldif_read_string(ldb_ctx, ldif_records); ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL); ret = ldb_add(ldb_ctx, normalized_msg); talloc_free(normalized_msg); if (ret != LDB_SUCCESS) { MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL); } /* we invalidate the cache, if present */ if (nameids_cache) { talloc_free(nameids_cache); nameids_cache = NULL; } return ret; }
/* add a group mapping entry */ static bool add_mapping_entry(GROUP_MAP *map, int flag) { struct ldb_message *msg; int ret, i; fstring string_sid; msg = ldb_msg_new(ldb); if (msg == NULL) { return False; } msg->dn = mapping_dn(msg, &map->sid); if (msg->dn == NULL) { goto failed; } if (ldb_msg_add_string(msg, "objectClass", "groupMap") != LDB_SUCCESS || ldb_msg_add_string(msg, "sid", sid_to_fstring(string_sid, &map->sid)) != LDB_SUCCESS || ldb_msg_add_fmt(msg, "gidNumber", "%u", (unsigned)map->gid) != LDB_SUCCESS || ldb_msg_add_fmt(msg, "sidNameUse", "%u", (unsigned)map->sid_name_use) != LDB_SUCCESS || ldb_msg_add_string(msg, "comment", map->comment) != LDB_SUCCESS || ldb_msg_add_string(msg, "ntName", map->nt_name) != LDB_SUCCESS) { goto failed; } ret = ldb_add(ldb, msg); /* if it exists we update it. This is a hangover from the semantics the tdb backend had */ if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { for (i=0;i<msg->num_elements;i++) { msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } ret = ldb_modify(ldb, msg); } talloc_free(msg); return ret == LDB_SUCCESS; failed: talloc_free(msg); return False; }
int confdb_create_base(struct confdb_ctx *cdb) { int ret; struct ldb_ldif *ldif; const char *base_ldif = CONFDB_BASE_LDIF; while ((ldif = ldb_ldif_read_string(cdb->ldb, &base_ldif))) { ret = ldb_add(cdb->ldb, ldif->msg); if (ret != LDB_SUCCESS) { DEBUG(0, ("Failed to initialize DB (%d,[%s]), aborting!\n", ret, ldb_errstring(cdb->ldb))); return EIO; } ldb_ldif_read_free(cdb->ldb, ldif); } return EOK; }
/* test ldb speed */ static bool test_ldb_speed(struct torture_context *torture, const void *_data) { struct timeval tv; struct ldb_context *ldb; int timelimit = torture_setting_int(torture, "timelimit", 10); int i, count; TALLOC_CTX *tmp_ctx = talloc_new(torture); struct ldb_ldif *ldif; const char *init_ldif = "dn: @INDEXLIST\n" \ "@IDXATTR: UID\n"; float ldb_speed; unlink("./test.ldb"); torture_comment(torture, "Testing ldb speed for sidmap\n"); ldb = ldb_wrap_connect(tmp_ctx, torture->ev, torture->lp_ctx, "tdb://test.ldb", NULL, NULL, LDB_FLG_NOSYNC, NULL); if (!ldb) { unlink("./test.ldb"); talloc_free(tmp_ctx); torture_fail(torture, "Failed to open test.ldb"); } /* add an index */ ldif = ldb_ldif_read_string(ldb, &init_ldif); if (ldif == NULL) goto failed; if (ldb_add(ldb, ldif->msg) != LDB_SUCCESS) goto failed; talloc_free(ldif); torture_comment(torture, "Adding %d SID records\n", torture_entries); for (i=0;i<torture_entries;i++) { if (!ldb_add_record(ldb, i)) { torture_result(torture, TORTURE_FAIL, "Failed to add SID %d\n", i); goto failed; } } if (talloc_total_blocks(torture) > 100) { torture_result(torture, TORTURE_FAIL, "memory leak in ldb add\n"); goto failed; } torture_comment(torture, "Testing for %d seconds\n", timelimit); tv = timeval_current(); for (count=0;timeval_elapsed(&tv) < timelimit;count++) { struct ldb_dn *dn; struct ldb_result *res; i = random() % torture_entries; dn = ldb_dn_new_fmt(tmp_ctx, ldb, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", i); if (ldb_search(ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL) != LDB_SUCCESS || res->count != 1) { torture_fail(torture, talloc_asprintf(torture, "Failed to find SID %d", i)); } talloc_free(res); talloc_free(dn); if (ldb_search(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, NULL, "(UID=%u)", i) != LDB_SUCCESS || res->count != 1) { torture_fail(torture, talloc_asprintf(torture, "Failed to find UID %d", i)); } talloc_free(res); } if (talloc_total_blocks(torture) > 100) { unlink("./test.ldb"); talloc_free(tmp_ctx); torture_fail(torture, "memory leak in ldb search"); } ldb_speed = count/timeval_elapsed(&tv); torture_comment(torture, "ldb speed %.2f ops/sec\n", ldb_speed); torture_comment(torture, "ldb/tdb speed ratio is %.2f%%\n", (100*ldb_speed/tdb_speed)); unlink("./test.ldb"); talloc_free(tmp_ctx); return true; failed: unlink("./test.ldb"); talloc_free(tmp_ctx); return false; }
static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schema *schema, bool write_attributes) { int ret = LDB_SUCCESS; struct ldb_result *res; struct ldb_result *res_idx; struct dsdb_attribute *attr; struct ldb_message *mod_msg; TALLOC_CTX *mem_ctx; struct ldb_message *msg; struct ldb_message *msg_idx; /* setup our own attribute name to schema handler */ ldb_schema_attribute_set_override_handler(ldb, dsdb_attribute_handler_override, schema); if (!write_attributes) { return ret; } mem_ctx = talloc_new(ldb); if (!mem_ctx) { return ldb_oom(ldb); } msg = ldb_msg_new(mem_ctx); if (!msg) { ldb_oom(ldb); goto op_error; } msg_idx = ldb_msg_new(mem_ctx); if (!msg_idx) { ldb_oom(ldb); goto op_error; } msg->dn = ldb_dn_new(msg, ldb, "@ATTRIBUTES"); if (!msg->dn) { ldb_oom(ldb); goto op_error; } msg_idx->dn = ldb_dn_new(msg_idx, ldb, "@INDEXLIST"); if (!msg_idx->dn) { ldb_oom(ldb); goto op_error; } ret = ldb_msg_add_string(msg_idx, "@IDXONE", "1"); if (ret != LDB_SUCCESS) { goto op_error; } ret = ldb_msg_add_string(msg_idx, "@IDXVERSION", SAMDB_INDEXING_VERSION); if (ret != LDB_SUCCESS) { goto op_error; } for (attr = schema->attributes; attr; attr = attr->next) { const char *syntax = attr->syntax->ldb_syntax; if (!syntax) { syntax = attr->syntax->ldap_oid; } /* * Write out a rough approximation of the schema * as an @ATTRIBUTES value, for bootstrapping */ if (strcmp(syntax, LDB_SYNTAX_INTEGER) == 0) { ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "INTEGER"); } else if (strcmp(syntax, LDB_SYNTAX_DIRECTORY_STRING) == 0) { ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "CASE_INSENSITIVE"); } if (ret != LDB_SUCCESS) { break; } if (attr->searchFlags & SEARCH_FLAG_ATTINDEX) { ret = ldb_msg_add_string(msg_idx, "@IDXATTR", attr->lDAPDisplayName); if (ret != LDB_SUCCESS) { break; } } } if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; } /* * Try to avoid churning the attributes too much, * we only want to do this if they have changed */ ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL, NULL); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ret = ldb_add(ldb, msg); } else if (ret != LDB_SUCCESS) { } else if (res->count != 1) { ret = ldb_add(ldb, msg); } else { ret = LDB_SUCCESS; /* Annoyingly added to our search results */ ldb_msg_remove_attr(res->msgs[0], "distinguishedName"); ret = ldb_msg_difference(ldb, mem_ctx, res->msgs[0], msg, &mod_msg); if (ret != LDB_SUCCESS) { goto op_error; } if (mod_msg->num_elements > 0) { ret = dsdb_replace(ldb, mod_msg, 0); } talloc_free(mod_msg); } if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) { /* We might be on a read-only DB or LDAP */ ret = LDB_SUCCESS; } if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; } /* Now write out the indexes, as found in the schema (if they have changed) */ ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE, NULL, NULL); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ret = ldb_add(ldb, msg_idx); } else if (ret != LDB_SUCCESS) { } else if (res_idx->count != 1) { ret = ldb_add(ldb, msg_idx); } else { ret = LDB_SUCCESS; /* Annoyingly added to our search results */ ldb_msg_remove_attr(res_idx->msgs[0], "distinguishedName"); ret = ldb_msg_difference(ldb, mem_ctx, res_idx->msgs[0], msg_idx, &mod_msg); if (ret != LDB_SUCCESS) { goto op_error; } if (mod_msg->num_elements > 0) { ret = dsdb_replace(ldb, mod_msg, 0); } talloc_free(mod_msg); } if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) { /* We might be on a read-only DB */ ret = LDB_SUCCESS; } talloc_free(mem_ctx); return ret; op_error: talloc_free(mem_ctx); return ldb_operr(ldb); }
errno_t sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx, struct sss_domain_info *domain, const char *map, const char *key, const char *value, struct sysdb_attrs *attrs) { errno_t ret; TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_dn *dn; const char *name; DEBUG(SSSDBG_TRACE_FUNC, ("Adding autofs entry [%s] - [%s]\n", key, value)); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } } ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, SYSDB_AUTOFS_ENTRY_OC); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry object class [%d]: %s\n", ret, strerror(ret))); goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_KEY, key); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry key [%d]: %s\n", ret, strerror(ret))); goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_VALUE, value); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry key [%d]: %s\n", ret, strerror(ret))); goto done; } name = talloc_asprintf(tmp_ctx, "%s%s", key, value); if (!name) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Could not set name attribute [%d]: %s\n", ret, strerror(ret))); goto done; } dn = sysdb_autofsentry_dn(tmp_ctx, sysdb_ctx, domain, map, key, value); if (!dn) { ret = ENOMEM; goto done; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = dn; msg->elements = attrs->a; msg->num_elements = attrs->num; ret = ldb_add(sysdb_ctx->ldb, msg); ret = sysdb_error_to_errno(ret); done: talloc_free(tmp_ctx); return ret; }
/* Add a user, SAMR style, including the correct transaction * semantics. Used by the SAMR server and by pdb_samba4 */ NTSTATUS dsdb_add_user(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *account_name, uint32_t acct_flags, struct dom_sid **sid, struct ldb_dn **dn) { const char *name; struct ldb_message *msg; int ret; const char *container, *obj_class=NULL; char *cn_name; size_t cn_name_len; const char *attrs[] = { "objectSid", "userAccountControl", NULL }; uint32_t user_account_control; struct ldb_dn *account_dn; struct dom_sid *account_sid; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); /* * Start a transaction, so we can query and do a subsequent atomic * modify */ ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { DEBUG(0,("Failed to start a transaction for user creation: %s\n", ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } /* check if the user already exists */ name = samdb_search_string(ldb, tmp_ctx, NULL, "sAMAccountName", "(&(sAMAccountName=%s)(objectclass=user))", ldb_binary_encode_string(tmp_ctx, account_name)); if (name != NULL) { ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); return NT_STATUS_USER_EXISTS; } cn_name = talloc_strdup(tmp_ctx, account_name); if (!cn_name) { ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } cn_name_len = strlen(cn_name); if (cn_name_len < 1) { ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); return NT_STATUS_INVALID_PARAMETER; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } /* This must be one of these values *only* */ if (acct_flags == ACB_NORMAL) { container = "CN=Users"; obj_class = "user"; } else if (acct_flags == ACB_WSTRUST) { if (cn_name[cn_name_len - 1] != '$') { ldb_transaction_cancel(ldb); return NT_STATUS_FOOBAR; } cn_name[cn_name_len - 1] = '\0'; container = "CN=Computers"; obj_class = "computer"; } else if (acct_flags == ACB_SVRTRUST) { if (cn_name[cn_name_len - 1] != '$') { ldb_transaction_cancel(ldb); return NT_STATUS_FOOBAR; } cn_name[cn_name_len - 1] = '\0'; container = "OU=Domain Controllers"; obj_class = "computer"; } else { ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); return NT_STATUS_INVALID_PARAMETER; } /* add core elements to the ldb_message for the user */ msg->dn = ldb_dn_copy(msg, ldb_get_default_basedn(ldb)); if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) { ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); return NT_STATUS_FOOBAR; } ldb_msg_add_string(msg, "sAMAccountName", account_name); ldb_msg_add_string(msg, "objectClass", obj_class); /* create the user */ ret = ldb_add(ldb, msg); switch (ret) { case LDB_SUCCESS: break; case LDB_ERR_ENTRY_ALREADY_EXISTS: ldb_transaction_cancel(ldb); DEBUG(0,("Failed to create user record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_USER_EXISTS; case LDB_ERR_UNWILLING_TO_PERFORM: case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: ldb_transaction_cancel(ldb); DEBUG(0,("Failed to create user record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_ACCESS_DENIED; default: ldb_transaction_cancel(ldb); DEBUG(0,("Failed to create user record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } account_dn = msg->dn; /* retrieve the sid and account control bits for the user just created */ ret = dsdb_search_one(ldb, tmp_ctx, &msg, account_dn, LDB_SCOPE_BASE, attrs, 0, NULL); if (ret != LDB_SUCCESS) { ldb_transaction_cancel(ldb); DEBUG(0,("Can't locate the account we just created %s: %s\n", ldb_dn_get_linearized(account_dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } account_sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid"); if (account_sid == NULL) { ldb_transaction_cancel(ldb); DEBUG(0,("Apparently we failed to get the objectSid of the just created account record %s\n", ldb_dn_get_linearized(msg->dn))); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } /* Change the account control to be the correct account type. * The default is for a workstation account */ user_account_control = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0); user_account_control = (user_account_control & ~(UF_NORMAL_ACCOUNT | UF_INTERDOMAIN_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT | UF_SERVER_TRUST_ACCOUNT)); user_account_control |= ds_acb2uf(acct_flags); talloc_free(msg); msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } msg->dn = account_dn; if (samdb_msg_add_uint(ldb, tmp_ctx, msg, "userAccountControl", user_account_control) != LDB_SUCCESS) { ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } /* modify the samdb record */ ret = dsdb_replace(ldb, msg, 0); if (ret != LDB_SUCCESS) { DEBUG(0,("Failed to modify account record %s to set userAccountControl: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); ldb_transaction_cancel(ldb); talloc_free(tmp_ctx); /* we really need samdb.c to return NTSTATUS */ return NT_STATUS_UNSUCCESSFUL; } ret = ldb_transaction_commit(ldb); if (ret != LDB_SUCCESS) { DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } *dn = talloc_steal(mem_ctx, account_dn); *sid = talloc_steal(mem_ctx, account_sid); talloc_free(tmp_ctx); return NT_STATUS_OK; }
/* connect to the group mapping ldb */ static bool init_group_mapping(void) { bool existed; const char *init_ldif[] = { "dn: @ATTRIBUTES\n" \ "ntName: CASE_INSENSITIVE\n" \ "\n", "dn: @INDEXLIST\n" \ "@IDXATTR: gidNumber\n" \ "@IDXATTR: ntName\n" \ "@IDXATTR: member\n" }; const char *db_path, *tdb_path; int ret; int flags = 0; if (ldb != NULL) { return True; } /* this is needed as Samba3 doesn't have this globally yet */ ldb_global_init(); db_path = state_path("group_mapping.ldb"); ldb = ldb_init(NULL); if (ldb == NULL) goto failed; /* Ensure this db is created read/write for root only. */ ldb_set_create_perms(ldb, 0600); existed = file_exist(db_path, NULL); if (lp_parm_bool(-1, "groupmap", "nosync", False)) { flags |= LDB_FLG_NOSYNC; } if (!lp_use_mmap()) { flags |= LDB_FLG_NOMMAP; } ret = ldb_connect(ldb, db_path, flags, NULL); if (ret != LDB_SUCCESS) { goto failed; } /* force the permissions on the ldb to 0600 - this will fix existing databases as well as new ones */ if (chmod(db_path, 0600) != 0) { goto failed; } if (!existed) { /* initialise the ldb with an index */ struct ldb_ldif *ldif; int i; for (i=0;i<ARRAY_SIZE(init_ldif);i++) { ldif = ldb_ldif_read_string(ldb, &init_ldif[i]); if (ldif == NULL) goto failed; ret = ldb_add(ldb, ldif->msg); talloc_free(ldif); if (ret == -1) goto failed; } } /* possibly upgrade */ tdb_path = state_path("group_mapping.tdb"); if (file_exist(tdb_path, NULL) && !mapping_upgrade(tdb_path)) { unlink(state_path("group_mapping.ldb")); goto failed; } return True; failed: DEBUG(0,("Failed to open group mapping ldb '%s' - '%s'\n", db_path, ldb?ldb_errstring(ldb):strerror(errno))); talloc_free(ldb); ldb = NULL; return False; }
int confdb_init_db(const char *config_file, struct confdb_ctx *cdb) { TALLOC_CTX *tmp_ctx; int ret; int sret = EOK; int version; char timestr[21]; char *lasttimestr; bool in_transaction = false; const char *config_ldif; const char *vals[2] = { timestr, NULL }; struct ldb_ldif *ldif; struct sss_ini_initdata *init_data; tmp_ctx = talloc_new(cdb); if (tmp_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory.\n"); return ENOMEM; } init_data = sss_ini_initdata_init(tmp_ctx); if (!init_data) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory.\n"); ret = ENOMEM; goto done; } /* Open config file */ ret = sss_ini_config_file_open(init_data, config_file); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "sss_ini_config_file_open failed: %s [%d]\n", strerror(ret), ret); if (ret == ENOENT) { /* sss specific error denoting missing configuration file */ ret = ERR_MISSING_CONF; } goto done; } ret = sss_ini_config_access_check(init_data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Permission check on config file failed.\n"); ret = EPERM; goto done; } /* Determine if the conf file has changed since we last updated * the confdb */ ret = sss_ini_get_stat(init_data); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Status check on config file failed.\n"); ret = errno; goto done; } errno = 0; ret = sss_ini_get_mtime(init_data, sizeof(timestr), timestr); if (ret <= 0 || ret >= sizeof(timestr)) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to convert time_t to string ??\n"); ret = errno ? errno : EFAULT; } ret = confdb_get_string(cdb, tmp_ctx, "config", "lastUpdate", NULL, &lasttimestr); if (ret == EOK) { /* check if we lastUpdate and last file modification change differ*/ if ((lasttimestr != NULL) && (strcmp(lasttimestr, timestr) == 0)) { /* not changed, get out, nothing more to do */ ret = EOK; goto done; } } else { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get lastUpdate attribute.\n"); goto done; } ret = sss_ini_get_config(init_data, config_file); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load configuration\n"); goto done; } /* Make sure that the config file version matches the confdb version */ ret = sss_ini_get_cfgobj(init_data, "sssd", "config_file_version"); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Internal error determining config_file_version\n"); goto done; } ret = sss_ini_check_config_obj(init_data); if (ret != EOK) { /* No known version. Assumed to be version 1 */ DEBUG(SSSDBG_FATAL_FAILURE, "Config file is an old version. " "Please run configuration upgrade script.\n"); ret = EINVAL; goto done; } version = sss_ini_get_int_config_value(init_data, 1, -1, &ret); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Config file version could not be determined\n"); goto done; } else if (version < CONFDB_VERSION_INT) { DEBUG(SSSDBG_FATAL_FAILURE, "Config file is an old version. " "Please run configuration upgrade script.\n"); ret = EINVAL; goto done; } else if (version > CONFDB_VERSION_INT) { DEBUG(SSSDBG_FATAL_FAILURE, "Config file version is newer than confdb\n"); ret = EINVAL; goto done; } /* Set up a transaction to replace the configuration */ ret = ldb_transaction_start(cdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to start a transaction for " "updating the configuration\n"); ret = sysdb_error_to_errno(ret); goto done; } in_transaction = true; /* Purge existing database */ ret = confdb_purge(cdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not purge existing configuration\n"); goto done; } ret = sss_confdb_create_ldif(tmp_ctx, init_data, &config_ldif); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create LDIF for confdb\n"); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "LDIF file to import: \n%s", config_ldif); while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) { 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)); ret = EIO; goto done; } ldb_ldif_read_free(cdb->ldb, ldif); } /* now store the lastUpdate time so that we do not re-init if nothing * changed on restart */ ret = confdb_add_param(cdb, true, "config", "lastUpdate", vals); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set last update time on db!\n"); goto done; } ret = ldb_transaction_commit(cdb->ldb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = ldb_transaction_cancel(cdb->ldb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } sss_ini_config_destroy(init_data); sss_ini_close_file(init_data); talloc_zfree(tmp_ctx); return ret; }
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; }
/* 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; }
/** \details Initialize the named properties database or return pointer to the existing one if already initialized/opened. \param mem_ctx pointer to the memory context \param ldb_ctx pointer on pointer to the ldb context the function returns \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ enum mapistore_error mapistore_namedprops_init(TALLOC_CTX *mem_ctx, struct ldb_context **_ldb_ctx) { int ret; struct stat sb; struct ldb_context *ldb_ctx = NULL; struct ldb_ldif *ldif; char *filename; FILE *f; struct tevent_context *ev; char *database; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mem_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!_ldb_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); ev = tevent_context_init(mem_ctx); MAPISTORE_RETVAL_IF(!ev, MAPISTORE_ERR_NO_MEMORY, NULL); database = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), MAPISTORE_DB_NAMED); DEBUG(0, ("database = %s\n", database)); /* Step 1. Stat the database and populate it if it doesn't exist */ if (stat(database, &sb) == -1) { ldb_ctx = mapistore_ldb_wrap_connect(ldb_ctx, ev, database, 0); talloc_free(database); MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_DATABASE_INIT, NULL); filename = talloc_asprintf(mem_ctx, "%s/mapistore_namedprops.ldif", mapistore_namedprops_get_ldif_path()); f = fopen(filename, "r"); talloc_free(filename); MAPISTORE_RETVAL_IF(!f, MAPISTORE_ERROR, NULL); ldb_transaction_start(ldb_ctx); while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) { struct ldb_message *normalized_msg; ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL); ret = ldb_add(ldb_ctx, normalized_msg); talloc_free(normalized_msg); if (ret != LDB_SUCCESS) { fclose(f); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL); } ldb_ldif_read_free(ldb_ctx, ldif); } ldb_transaction_commit(ldb_ctx); fclose(f); } else { ldb_ctx = mapistore_ldb_wrap_connect(ldb_ctx, ev, database, 0); talloc_free(database); MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_DATABASE_INIT, NULL); } *_ldb_ctx = ldb_ctx; return MAPISTORE_SUCCESS; }
static NTSTATUS sldb_create(struct share_context *ctx, const char *name, struct share_info *info, int count) { struct ldb_context *ldb; struct ldb_message *msg; TALLOC_CTX *tmp_ctx; NTSTATUS ret; int err, i, j; for (i = 0, j = 0; i < count && j != 0x03; i++) { if (strcasecmp(info[i].name, SHARE_TYPE) == 0) j |= 0x02; if (strcasecmp(info[i].name, SHARE_PATH) == 0) j |= 0x01; if (strcasecmp(info[i].name, SHARE_NAME) == 0) { if (strcasecmp(name, (char *)info[i].value) != 0) { return NT_STATUS_INVALID_PARAMETER; } } } if (!name || j != 0x03) { return NT_STATUS_INVALID_PARAMETER; } 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); msg = ldb_msg_new(tmp_ctx); if (!msg) { DEBUG(0,("ERROR: Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } /* TODO: escape info->name */ msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name); if (!msg->dn) { DEBUG(0,("ERROR: Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } SHARE_ADD_STRING("objectClass", "top"); SHARE_ADD_STRING("objectClass", "share"); SHARE_ADD_STRING("cn", name); SHARE_ADD_STRING(SHARE_NAME, name); for (i = 0; i < count; i++) { if (strcasecmp(info[i].name, SHARE_NAME) == 0) continue; switch (info[i].type) { case SHARE_INFO_STRING: SHARE_ADD_STRING(info[i].name, (char *)info[i].value); break; case SHARE_INFO_INT: SHARE_ADD_INT(info[i].name, *((int *)info[i].value)); break; case SHARE_INFO_BLOB: SHARE_ADD_BLOB(info[i].name, (DATA_BLOB *)info[i].value); break; default: DEBUG(2,("ERROR: Invalid share info type for %s\n", info[i].name)); ret = NT_STATUS_INVALID_PARAMETER; goto done; } } /* TODO: Security Descriptor */ SHARE_ADD_STRING(SHARE_AVAILABLE, "true"); SHARE_ADD_STRING(SHARE_BROWSEABLE, "true"); SHARE_ADD_STRING(SHARE_READONLY, "false"); SHARE_ADD_STRING(SHARE_NTVFS_HANDLER, "unixuid"); SHARE_ADD_STRING(SHARE_NTVFS_HANDLER, "posix"); err = ldb_add(ldb, msg); if (err != LDB_SUCCESS) { DEBUG(2,("ERROR: unable to add share %s to share.ldb\n" " err=%d [%s]\n", name, err, ldb_errstring(ldb))); if (err == LDB_ERR_NO_SUCH_OBJECT) { ret = NT_STATUS_OBJECT_NAME_NOT_FOUND; } else if (err == LDB_ERR_ENTRY_ALREADY_EXISTS) { ret = NT_STATUS_OBJECT_NAME_COLLISION; } else { ret = NT_STATUS_UNSUCCESSFUL; } goto done; } ret = NT_STATUS_OK; done: talloc_free(tmp_ctx); return ret; }
NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *alias_name, struct dom_sid **sid, struct ldb_dn **dn) { const char *name; struct ldb_message *msg; struct dom_sid *alias_sid; int ret; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); if (ldb_transaction_start(ldb) != LDB_SUCCESS) { DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb))); return NT_STATUS_INTERNAL_ERROR; } /* Check if alias already exists */ name = samdb_search_string(ldb, tmp_ctx, NULL, "sAMAccountName", "(sAMAccountName=%s)(objectclass=group))", ldb_binary_encode_string(mem_ctx, alias_name)); if (name != NULL) { talloc_free(tmp_ctx); ldb_transaction_cancel(ldb); return NT_STATUS_ALIAS_EXISTS; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { talloc_free(tmp_ctx); ldb_transaction_cancel(ldb); return NT_STATUS_NO_MEMORY; } /* add core elements to the ldb_message for the alias */ msg->dn = ldb_dn_copy(mem_ctx, ldb_get_default_basedn(ldb)); ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name); if (!msg->dn) { talloc_free(tmp_ctx); ldb_transaction_cancel(ldb); return NT_STATUS_NO_MEMORY; } ldb_msg_add_string(msg, "sAMAccountName", alias_name); ldb_msg_add_string(msg, "objectClass", "group"); samdb_msg_add_int(ldb, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); /* create the alias */ ret = ldb_add(ldb, msg); switch (ret) { case LDB_SUCCESS: break; case LDB_ERR_ENTRY_ALREADY_EXISTS: talloc_free(tmp_ctx); ldb_transaction_cancel(ldb); return NT_STATUS_ALIAS_EXISTS; case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: talloc_free(tmp_ctx); ldb_transaction_cancel(ldb); return NT_STATUS_ACCESS_DENIED; default: DEBUG(0,("Failed to create alias record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); ldb_transaction_cancel(ldb); return NT_STATUS_INTERNAL_DB_CORRUPTION; } /* retrieve the sid for the alias just created */ alias_sid = samdb_search_dom_sid(ldb, tmp_ctx, msg->dn, "objectSid", NULL); if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb))); return NT_STATUS_INTERNAL_ERROR; } *dn = talloc_steal(mem_ctx, msg->dn); *sid = talloc_steal(mem_ctx, alias_sid); talloc_free(tmp_ctx); return NT_STATUS_OK; }
static int local_db_put_simple(TALLOC_CTX *mem_ctx, struct local_context *lctx, const char *req_path, const char *secret) { struct ldb_message *msg; const char *enctype = "masterkey"; char *enc_secret; int ret; msg = ldb_msg_new(mem_ctx); if (!msg) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Adding a secret to [%s]\n", req_path); ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } /* make sure containers exist */ ret = local_db_check_containers(msg, lctx, msg->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "local_db_check_containers failed for [%s]: [%d]: %s\n", ldb_dn_get_linearized(msg->dn), ret, sss_strerror(ret)); goto done; } ret = local_db_check_number_of_secrets(msg, lctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "local_db_check_number_of_secrets failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = local_encrypt(lctx, msg, secret, enctype, &enc_secret); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "local_encrypt failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ldb_msg_add_string(msg, "type", "simple"); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed adding type:simple [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ldb_msg_add_string(msg, "enctype", enctype); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed adding enctype [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ldb_msg_add_string(msg, "secret", enc_secret); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed adding secret [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed adding creationTime [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ldb_add(lctx->ldb, msg); if (ret != EOK) { if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { DEBUG(SSSDBG_OP_FAILURE, "Secret %s already exists\n", ldb_dn_get_linearized(msg->dn)); ret = EEXIST; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add secret [%s]: [%d]: %s\n", ldb_dn_get_linearized(msg->dn), ret, ldb_strerror(ret)); ret = EIO; } goto done; } ret = EOK; done: talloc_free(msg); return ret; }
static int local_db_create(TALLOC_CTX *mem_ctx, struct local_context *lctx, const char *req_path) { struct ldb_message *msg; int ret; msg = ldb_msg_new(mem_ctx); if (!msg) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Creating a container at [%s]\n", req_path); ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } /* make sure containers exist */ ret = local_db_check_containers(msg, lctx, msg->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "local_db_check_containers failed for [%s]: [%d]: %s\n", ldb_dn_get_linearized(msg->dn), ret, sss_strerror(ret)); goto done; } ret = local_db_check_containers_nest_level(lctx, msg->dn); if (ret != EOK) goto done; ret = ldb_msg_add_string(msg, "type", "container"); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed adding type:container [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed adding creationTime [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ldb_add(lctx->ldb, msg); if (ret != EOK) { if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { DEBUG(SSSDBG_OP_FAILURE, "Secret %s already exists\n", ldb_dn_get_linearized(msg->dn)); ret = EEXIST; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add secret [%s]: [%d]: %s\n", ldb_dn_get_linearized(msg->dn), ret, ldb_strerror(ret)); ret = EIO; } goto done; } ret = EOK; done: talloc_free(msg); return ret; }
/* * find out Site specific stuff: * 1. Lookup the Site name. * 2. Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>. * TODO: 3.) use DsAddEntry() to create CN=NTDS Settings,CN=<netbios name>,CN=Servers,CN=<site name>,... */ NTSTATUS libnet_JoinSite(struct libnet_context *ctx, struct ldb_context *remote_ldb, struct libnet_JoinDomain *libnet_r) { NTSTATUS status; TALLOC_CTX *tmp_ctx; struct libnet_JoinSite *r; struct ldb_dn *server_dn; struct ldb_message *msg; int rtn; const char *server_dn_str; const char *config_dn_str; struct nbt_name name; const char *dest_addr = NULL; tmp_ctx = talloc_named(libnet_r, 0, "libnet_JoinSite temp context"); if (!tmp_ctx) { libnet_r->out.error_string = NULL; return NT_STATUS_NO_MEMORY; } r = talloc(tmp_ctx, struct libnet_JoinSite); if (!r) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } make_nbt_name_client(&name, libnet_r->out.samr_binding->host); status = resolve_name(lp_resolve_context(ctx->lp_ctx), &name, r, &dest_addr, ctx->event_ctx); if (!NT_STATUS_IS_OK(status)) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return status; } /* Resolve the site name and AD DN's. */ r->in.dest_address = dest_addr; r->in.netbios_name = libnet_r->in.netbios_name; r->in.domain_dn_str = libnet_r->out.domain_dn_str; r->in.cldap_port = lp_cldap_port(ctx->lp_ctx); status = libnet_FindSite(tmp_ctx, ctx, r); if (!NT_STATUS_IS_OK(status)) { libnet_r->out.error_string = talloc_steal(libnet_r, r->out.error_string); talloc_free(tmp_ctx); return status; } config_dn_str = r->out.config_dn_str; server_dn_str = r->out.server_dn_str; /* Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>. */ msg = ldb_msg_new(tmp_ctx); if (!msg) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } rtn = ldb_msg_add_string(msg, "objectClass", "server"); if (rtn != 0) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } rtn = ldb_msg_add_string(msg, "systemFlags", "50000000"); if (rtn != 0) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } rtn = ldb_msg_add_string(msg, "serverReference", libnet_r->out.account_dn_str); if (rtn != 0) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } server_dn = ldb_dn_new(tmp_ctx, remote_ldb, server_dn_str); if ( ! ldb_dn_validate(server_dn)) { libnet_r->out.error_string = talloc_asprintf(libnet_r, "Invalid server dn: %s", server_dn_str); talloc_free(tmp_ctx); return NT_STATUS_UNSUCCESSFUL; } msg->dn = server_dn; rtn = ldb_add(remote_ldb, msg); if (rtn == LDB_ERR_ENTRY_ALREADY_EXISTS) { int i; /* make a 'modify' msg, and only for serverReference */ msg = ldb_msg_new(tmp_ctx); if (!msg) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } msg->dn = server_dn; rtn = ldb_msg_add_string(msg, "serverReference",libnet_r->out.account_dn_str); if (rtn != 0) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } /* mark all the message elements (should be just one) as LDB_FLAG_MOD_REPLACE */ for (i=0; i<msg->num_elements; i++) { msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } rtn = ldb_modify(remote_ldb, msg); if (rtn != 0) { libnet_r->out.error_string = talloc_asprintf(libnet_r, "Failed to modify server entry %s: %s: %d", server_dn_str, ldb_errstring(remote_ldb), rtn); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } } else if (rtn != 0) { libnet_r->out.error_string = talloc_asprintf(libnet_r, "Failed to add server entry %s: %s: %d", server_dn_str, ldb_errstring(remote_ldb), rtn); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } DEBUG(0, ("We still need to perform a DsAddEntry() so that we can create the CN=NTDS Settings container.\n")); /* Store the server DN in libnet_r */ libnet_r->out.server_dn_str = server_dn_str; talloc_steal(libnet_r, server_dn_str); talloc_free(tmp_ctx); return NT_STATUS_OK; }
int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_5)); ret = ldb_transaction_start(sysdb->ldb); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* Add new index */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "originalDN"); 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; } /* Rebuild memberuid and memberoif attributes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@MEMBEROF-REBUILD"); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_add(sysdb->ldb, msg); 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_5); 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_5, ver); talloc_free(tmp_ctx); return ret; }
static WERROR sptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_AddForm *r) { struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context); struct ldb_message *msg,**msgs; const char * const attrs[] = {"flags", NULL }; int count, ret; /* TODO: do checks access here * if (!(server->access_mask & desired_access)) { * return WERR_FOOBAR; * } */ switch (r->in.level) { case 1: if (!r->in.info.info1) { 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.info.info1->form_name); if (count == 1) return WERR_FOOBAR; if (count > 1) return WERR_FOOBAR; if (count < 0) return WERR_GENERAL_FAILURE; if (r->in.info.info1->flags != SPOOLSS_FORM_USER) { return WERR_FOOBAR; } msg = ldb_msg_new(mem_ctx); W_ERROR_HAVE_NO_MEMORY(msg); /* add core elements to the ldb_message for the Form */ msg->dn = ldb_dn_new_fmt(msg, sptr_db, "form-name=%s,CN=Forms,CN=PrintServer", r->in.info.info1->form_name); SET_STRING(sptr_db, msg, "objectClass", "form"); SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags); SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name); SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width); SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height); SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left); SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top); SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right); SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom); break; default: return WERR_UNKNOWN_LEVEL; } ret = ldb_add(sptr_db, msg); if (ret != 0) { return WERR_FOOBAR; } return WERR_OK; }
/* remember an established session key for a netr server authentication use a simple ldb structure */ NTSTATUS schannel_store_session_key_ldb(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct netlogon_creds_CredentialState *creds) { struct ldb_message *msg; struct ldb_val val, seed, client_state, server_state; struct ldb_val *sid_val; 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; } sid_val = schannel_dom_sid_ldb_val(msg, creds->sid); if (sid_val == NULL) { 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_value(msg, "objectSid", sid_val, NULL); ret = ldb_add(ldb, msg); if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { int i; /* from samdb_replace() */ /* mark all the message elements as LDB_FLAG_MOD_REPLACE */ for (i=0;i<msg->num_elements;i++) { msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } ret = ldb_modify(ldb, msg); } /* We don't need a transaction here, as we either add or * modify records, never delete them, so it must exist */ if (ret != LDB_SUCCESS) { 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; }
errno_t sysdb_svc_add(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *primary_name, int port, const char **aliases, const char **protocols, struct ldb_dn **dn) { errno_t ret; int lret; TALLOC_CTX *tmp_ctx; struct ldb_message *msg; unsigned long i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } /* svc dn */ msg->dn = sysdb_svc_dn(domain->sysdb, msg, domain->name, primary_name); if (!msg->dn) { ret = ENOMEM; goto done; } /* Objectclass */ ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_OBJECTCLASS, SYSDB_SVC_CLASS); if (ret != EOK) goto done; /* Set the primary name */ ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, primary_name); if (ret != EOK) goto done; /* Set the port number */ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_SVC_PORT, port); if (ret != EOK) goto done; /* If this service has any aliases, include them */ if (aliases && aliases[0]) { /* Set the name aliases */ lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } for (i=0; aliases[i]; i++) { lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } } /* Set the protocols */ lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } for (i=0; protocols[i]; i++) { lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } /* creation time */ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME, (unsigned long)time(NULL)); if (ret) goto done; lret = ldb_add(domain->sysdb->ldb, msg); ret = sysdb_error_to_errno(lret); if (ret == EOK && dn) { *dn = talloc_steal(mem_ctx, msg->dn); } done: if (ret) { DEBUG(SSSDBG_TRACE_INTERNAL, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; }
/* called by samr_CreateDomainGroup and pdb_samba4 */ NTSTATUS dsdb_add_domain_group(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *groupname, struct dom_sid **sid, struct ldb_dn **dn) { const char *name; struct ldb_message *msg; struct dom_sid *group_sid; int ret; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); /* check if the group already exists */ name = samdb_search_string(ldb, tmp_ctx, NULL, "sAMAccountName", "(&(sAMAccountName=%s)(objectclass=group))", ldb_binary_encode_string(tmp_ctx, groupname)); if (name != NULL) { return NT_STATUS_GROUP_EXISTS; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { return NT_STATUS_NO_MEMORY; } /* add core elements to the ldb_message for the user */ msg->dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(ldb)); ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", groupname); if (!msg->dn) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } ldb_msg_add_string(msg, "sAMAccountName", groupname); ldb_msg_add_string(msg, "objectClass", "group"); /* create the group */ ret = ldb_add(ldb, msg); switch (ret) { case LDB_SUCCESS: break; case LDB_ERR_ENTRY_ALREADY_EXISTS: DEBUG(0,("Failed to create group record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_GROUP_EXISTS; case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: DEBUG(0,("Failed to create group record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_ACCESS_DENIED; default: DEBUG(0,("Failed to create group record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } /* retrieve the sid for the group just created */ group_sid = samdb_search_dom_sid(ldb, tmp_ctx, msg->dn, "objectSid", NULL); if (group_sid == NULL) { return NT_STATUS_UNSUCCESSFUL; } *dn = talloc_steal(mem_ctx, msg->dn); *sid = talloc_steal(mem_ctx, group_sid); talloc_free(tmp_ctx); return NT_STATUS_OK; }