/* Modify the local record. */ int map_modify_do_local(struct ldb_handle *handle) { struct map_context *ac; struct ldb_message *msg; char *dn; ac = talloc_get_type(handle->private_data, struct map_context); if (ac->local_dn == NULL) { /* No local record present, add it instead */ msg = discard_const_p(struct ldb_message, ac->local_req->op.mod.message); /* Add local 'IS_MAPPED' */ /* TODO: use GUIDs here instead */ dn = ldb_dn_linearize(msg, ac->remote_req->op.mod.message->dn); if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_ADD, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { return LDB_ERR_OPERATIONS_ERROR; } /* Turn request into 'add' */ ac->local_req->operation = LDB_ADD; ac->local_req->op.add.message = msg; /* TODO: Could I just leave msg in there? I think so, * but it looks clearer this way. */ }
/* add a value to a message */ int ldb_msg_add_value(struct ldb_message *msg, const char *attr_name, const struct ldb_val *val, struct ldb_message_element **return_el) { struct ldb_message_element *el; struct ldb_val *vals; int ret; el = ldb_msg_find_element(msg, attr_name); if (!el) { ret = ldb_msg_add_empty(msg, attr_name, 0, &el); if (ret != LDB_SUCCESS) { return ret; } } vals = talloc_realloc(msg->elements, el->values, struct ldb_val, el->num_values+1); if (!vals) { return LDB_ERR_OPERATIONS_ERROR; } el->values = vals; el->values[el->num_values] = *val; el->num_values++; if (return_el) { *return_el = el; } return LDB_SUCCESS; }
static int acl_childClasses(struct ldb_module *module, struct ldb_message *sd_msg, struct ldb_message *msg, const char *attrName) { struct ldb_message_element *oc_el; struct ldb_message_element *allowedClasses; struct ldb_context *ldb = ldb_module_get_ctx(module); const struct dsdb_schema *schema = dsdb_get_schema(ldb); const struct dsdb_class *sclass; int i, j, ret; /* If we don't have a schema yet, we can't do anything... */ if (schema == NULL) { return LDB_SUCCESS; } /* Must remove any existing attribute, or else confusion reins */ ldb_msg_remove_attr(msg, attrName); ret = ldb_msg_add_empty(msg, attrName, 0, &allowedClasses); if (ret != LDB_SUCCESS) { return ret; } oc_el = ldb_msg_find_element(sd_msg, "objectClass"); for (i=0; oc_el && i < oc_el->num_values; i++) { sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]); if (!sclass) { /* We don't know this class? what is going on? */ continue; } for (j=0; sclass->possibleInferiors && sclass->possibleInferiors[j]; j++) { ldb_msg_add_string(msg, attrName, sclass->possibleInferiors[j]); } } if (allowedClasses->num_values > 1) { qsort(allowedClasses->values, allowedClasses->num_values, sizeof(*allowedClasses->values), (comparison_fn_t)data_blob_cmp); for (i=1 ; i < allowedClasses->num_values; i++) { struct ldb_val *val1 = &allowedClasses->values[i-1]; struct ldb_val *val2 = &allowedClasses->values[i]; if (data_blob_cmp(val1, val2) == 0) { memmove(val1, val2, (allowedClasses->num_values - i) * sizeof(struct ldb_val)); allowedClasses->num_values--; i--; } } } return LDB_SUCCESS; }
/* Modify the local record. */ static int map_modify_do_local(struct map_context *ac) { struct ldb_request *local_req; struct ldb_context *ldb; int ret; ldb = ldb_module_get_ctx(ac->module); if (ac->local_dn == NULL) { /* No local record present, add it instead */ /* Add local 'IS_MAPPED' */ /* TODO: use GUIDs here instead */ if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED, LDB_FLAG_MOD_ADD, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, ac->remote_req->op.mod.message->dn); if (ret != 0) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare the local operation */ ret = ldb_build_add_req(&local_req, ldb, ac, ac->local_msg, ac->req->controls, ac, map_op_local_callback, ac->req); LDB_REQ_SET_LOCATION(local_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } } else { /* Prepare the local operation */ ret = ldb_build_mod_req(&local_req, ldb, ac, ac->local_msg, ac->req->controls, ac, map_op_local_callback, ac->req); LDB_REQ_SET_LOCATION(local_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } } return ldb_next_request(ac->module, local_req); }
int sysdb_upgrade_06(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_7)); ret = ldb_transaction_start(sysdb->ldb); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* Add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); if (!msg->dn) { ret = ENOMEM; goto done; } /* Case insensitive search for originalDN */ ret = ldb_msg_add_empty(msg, SYSDB_ORIG_DN, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, SYSDB_ORIG_DN, "CASE_INSENSITIVE"); 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; } /* 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, "cn=sysdb"); 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_7); 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_7, ver); talloc_free(tmp_ctx); return ret; }
/* serach all groups that have a memberUid attribute. * change it into a member attribute for a user of same domain. * remove the memberUid attribute * add the new member attribute * finally stop indexing memberUid * upgrade version to 0.2 */ int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver) { struct ldb_message_element *el; struct ldb_result *res; struct ldb_dn *basedn; struct ldb_dn *mem_dn; struct ldb_message *msg; const struct ldb_val *val; const char *filter = "(&(memberUid=*)(objectclass=group))"; const char *attrs[] = { "memberUid", NULL }; const char *mdn; char *domain; int ret, i, j; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } basedn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); if (!basedn) { ret = EIO; goto done; } ret = ldb_search(ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "%s", filter); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } for (i = 0; i < res->count; i++) { el = ldb_msg_find_element(res->msgs[i], "memberUid"); if (!el) { DEBUG(1, ("memberUid is missing from message [%s], skipping\n", ldb_dn_get_linearized(res->msgs[i]->dn))); continue; } /* create modification message */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = res->msgs[i]->dn; ret = ldb_msg_add_empty(msg, "memberUid", LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } /* get domain name component value */ val = ldb_dn_get_component_val(res->msgs[i]->dn, 2); domain = talloc_strndup(tmp_ctx, (const char *)val->data, val->length); if (!domain) { ret = ENOMEM; goto done; } for (j = 0; j < el->num_values; j++) { mem_dn = ldb_dn_new_fmt(tmp_ctx, ldb, SYSDB_TMPL_USER, (const char *)el->values[j].data, domain); if (!mem_dn) { ret = ENOMEM; goto done; } mdn = talloc_strdup(msg, ldb_dn_get_linearized(mem_dn)); if (!mdn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, SYSDB_MEMBER, mdn); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } talloc_zfree(mem_dn); } /* ok now we are ready to modify the entry */ ret = ldb_modify(ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } talloc_zfree(msg); } /* 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_2); 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 = EOK; done: ret = finish_upgrade(ret, ldb, SYSDB_VERSION_0_2, ver); talloc_free(tmp_ctx); return ret; }
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; }
int sysdb_upgrade_03(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_4)); ret = ldb_transaction_start(sysdb->ldb); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* Make this database case-sensitive */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_DELETE, NULL); 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; } /* 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_4); 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_4, ver); talloc_free(tmp_ctx); return ret; }
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; }
errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, const char *name, const char *realm, const char *flat_name, const char *domain_id, bool mpg, bool enumerate, const char *forest) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_dn *dn; struct ldb_result *res; const char *attrs[] = {"cn", SYSDB_SUBDOMAIN_REALM, SYSDB_SUBDOMAIN_FLAT, SYSDB_SUBDOMAIN_ID, SYSDB_SUBDOMAIN_MPG, SYSDB_SUBDOMAIN_ENUM, SYSDB_SUBDOMAIN_FOREST, NULL}; const char *tmp_str; bool tmp_bool; bool store = false; int realm_flags = 0; int flat_flags = 0; int id_flags = 0; int mpg_flags = 0; int enum_flags = 0; int forest_flags = 0; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, name); if (dn == NULL) { ret = EIO; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } if (res->count == 0) { ret = sysdb_domain_create(sysdb, name); if (ret) { goto done; } store = true; if (realm) realm_flags = LDB_FLAG_MOD_ADD; if (flat_name) flat_flags = LDB_FLAG_MOD_ADD; if (domain_id) id_flags = LDB_FLAG_MOD_ADD; mpg_flags = LDB_FLAG_MOD_ADD; enum_flags = LDB_FLAG_MOD_ADD; if (forest) forest_flags = LDB_FLAG_MOD_ADD; } else if (res->count != 1) { ret = EINVAL; goto done; } else { /* 1 found */ if (realm) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_REALM, NULL); if (!tmp_str || strcasecmp(tmp_str, realm) != 0) { realm_flags = LDB_FLAG_MOD_REPLACE; } } if (flat_name) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_FLAT, NULL); if (!tmp_str || strcasecmp(tmp_str, flat_name) != 0) { flat_flags = LDB_FLAG_MOD_REPLACE; } } if (domain_id) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_ID, NULL); if (!tmp_str || strcasecmp(tmp_str, domain_id) != 0) { id_flags = LDB_FLAG_MOD_REPLACE; } } tmp_bool = ldb_msg_find_attr_as_bool(res->msgs[0], SYSDB_SUBDOMAIN_MPG, !mpg); if (tmp_bool != mpg) { mpg_flags = LDB_FLAG_MOD_REPLACE; } tmp_bool = ldb_msg_find_attr_as_bool(res->msgs[0], SYSDB_SUBDOMAIN_ENUM, !enumerate); if (tmp_bool != enumerate) { enum_flags = LDB_FLAG_MOD_REPLACE; } if (forest) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_FOREST, NULL); if (!tmp_str || strcasecmp(tmp_str, forest) != 0) { forest_flags = LDB_FLAG_MOD_REPLACE; } } } if (!store && realm_flags == 0 && flat_flags == 0 && id_flags == 0 && mpg_flags == 0 && enum_flags == 0 && forest_flags == 0) { ret = EOK; goto done; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = dn; if (store) { ret = ldb_msg_add_empty(msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_SUBDOMAIN_CLASS); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (realm_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_REALM, realm_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_REALM, realm); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (flat_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FLAT, flat_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FLAT, flat_name); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (id_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_ID, id_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_ID, domain_id); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (mpg_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_MPG, mpg_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_MPG, mpg ? "TRUE" : "FALSE"); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (enum_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_ENUM, enum_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_ENUM, enumerate ? "TRUE" : "FALSE"); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (forest_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FOREST, forest_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FOREST, forest); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add subdomain attributes to " "[%s]: [%d][%s]!\n", name, ret, ldb_errstring(sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; }
errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain, const char *flat, const char *id, const char* forest) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; int ret; bool do_update = false; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); if (msg->dn == NULL) { ret = EIO; goto done; } if (flat != NULL && (domain->flat_name == NULL || strcmp(domain->flat_name, flat) != 0)) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FLAT, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FLAT, flat); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } do_update = true; } if (id != NULL && (domain->domain_id == NULL || strcmp(domain->domain_id, id) != 0)) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_ID, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_ID, id); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } do_update = true; } if (forest != NULL && (domain->forest == NULL || strcmp(domain->forest, forest) != 0)) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FOREST, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FOREST, forest); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } do_update = true; } if (do_update == false) { ret = EOK; goto done; } ret = ldb_modify(domain->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add subdomain attributes to " "[%s]: [%d][%s]!\n", domain->name, ret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } ret = sysdb_master_domain_update(domain); if (ret != EOK) { goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; }
static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct rename_context *ac; struct ldb_request *mod_req; const char *rdn_name; struct ldb_val rdn_val; struct ldb_message *msg; int ret; ac = talloc_get_type(req->context, struct rename_context); ldb = ldb_module_get_ctx(ac->module); if (!ares) { goto error; } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } /* the only supported reply right now is a LDB_REPLY_DONE */ if (ares->type != LDB_REPLY_DONE) { goto error; } /* save reply for caller */ ac->ares = talloc_steal(ac, ares); msg = ldb_msg_new(ac); if (msg == NULL) { goto error; } msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn); if (msg->dn == NULL) { goto error; } rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); if (rdn_name == NULL) { goto error; } rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->req->op.rename.newdn)); if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { goto error; } if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { goto error; } if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { goto error; } if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { goto error; } ret = ldb_build_mod_req(&mod_req, ldb, ac, msg, NULL, ac, rdn_modify_callback, req); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } talloc_steal(mod_req, msg); /* go on with the call chain */ return ldb_next_request(ac->module, mod_req); error: return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); }
/* add or modify a rdataset */ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, void *dbdata, void *version) { struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data); struct dnsp_DnssrvRpcRecord *rec; struct ldb_dn *dn; isc_result_t result; struct ldb_result *res; const char *attrs[] = { "dnsRecord", NULL }; int ret, i; struct ldb_message_element *el; enum ndr_err_code ndr_err; NTTIME t; if (state->transaction_token != (void*)version) { state->log(ISC_LOG_INFO, "samba_dlz: bad transaction version"); return ISC_R_FAILURE; } rec = talloc_zero(state, struct dnsp_DnssrvRpcRecord); if (rec == NULL) { return ISC_R_NOMEMORY; } unix_to_nt_time(&t, time(NULL)); t /= 10*1000*1000; /* convert to seconds (NT time is in 100ns units) */ t /= 3600; /* convert to hours */ rec->rank = DNS_RANK_ZONE; rec->dwSerial = state->soa_serial; rec->dwTimeStamp = (uint32_t)t; if (!b9_parse(state, rdatastr, rec)) { state->log(ISC_LOG_INFO, "samba_dlz: failed to parse rdataset '%s'", rdatastr); talloc_free(rec); return ISC_R_FAILURE; } /* find the DN of the record */ result = b9_find_name_dn(state, name, rec, &dn); if (result != ISC_R_SUCCESS) { talloc_free(rec); return result; } /* get any existing records */ ret = ldb_search(state->samdb, rec, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsNode"); if (ret == LDB_ERR_NO_SUCH_OBJECT) { if (!b9_set_session_info(state, name)) { talloc_free(rec); return ISC_R_FAILURE; } result = b9_add_record(state, name, dn, rec); b9_reset_session_info(state); talloc_free(rec); if (result == ISC_R_SUCCESS) { state->log(ISC_LOG_INFO, "samba_dlz: added %s %s", name, rdatastr); } return result; } el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); if (el == NULL) { ret = ldb_msg_add_empty(res->msgs[0], "dnsRecord", LDB_FLAG_MOD_ADD, &el); if (ret != LDB_SUCCESS) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to add dnsRecord for %s", ldb_dn_get_linearized(dn)); talloc_free(rec); return ISC_R_FAILURE; } } /* there are existing records. We need to see if this will * replace a record or add to it */ for (i=0; i<el->num_values; i++) { struct dnsp_DnssrvRpcRecord rec2; ndr_err = ndr_pull_struct_blob(&el->values[i], rec, &rec2, (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", ldb_dn_get_linearized(dn)); talloc_free(rec); return ISC_R_FAILURE; } if (b9_record_match(state, rec, &rec2)) { break; } } if (i == el->num_values) { /* adding a new value */ el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values+1); if (el->values == NULL) { talloc_free(rec); return ISC_R_NOMEMORY; } el->num_values++; }
/* add special SPNs needed for DRS replication to machine accounts when an AddEntry is done to create a nTDSDSA object */ static WERROR drsuapi_add_SPNs(struct drsuapi_bind_state *b_state, struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, const struct drsuapi_DsReplicaObjectListItem *first_object) { int ret; const struct drsuapi_DsReplicaObjectListItem *obj; const char *attrs[] = { "serverReference", "objectGUID", NULL }; for (obj = first_object; obj; obj=obj->next_object) { const char *dn_string = obj->object.identifier->dn; struct ldb_dn *dn = ldb_dn_new(mem_ctx, b_state->sam_ctx, dn_string); struct ldb_result *res, *res2; struct ldb_dn *ref_dn; struct GUID ntds_guid; struct ldb_message *msg; struct ldb_message_element *el; const char *ntds_guid_str; const char *dom_string; const char *attrs2[] = { "dNSHostName", "cn", NULL }; const char *dNSHostName, *cn; DEBUG(6,(__location__ ": Adding SPNs for %s\n", ldb_dn_get_linearized(dn))); ret = ldb_search(b_state->sam_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "(objectClass=ntDSDSA)"); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find dn '%s'\n", dn_string)); return WERR_DS_DRA_INTERNAL_ERROR; } if (res->count < 1) { /* we only add SPNs for nTDSDSA objects */ continue; } ref_dn = samdb_result_dn(b_state->sam_ctx, mem_ctx, res->msgs[0], "serverReference", NULL); if (ref_dn == NULL) { /* we only add SPNs for objects with a serverReference */ continue; } DEBUG(6,(__location__ ": serverReference %s\n", ldb_dn_get_linearized(ref_dn))); ntds_guid = samdb_result_guid(res->msgs[0], "objectGUID"); ntds_guid_str = GUID_string(res, &ntds_guid); dom_string = lpcfg_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); /* get the dNSHostName and cn */ ret = ldb_search(b_state->sam_ctx, mem_ctx, &res2, ref_dn, LDB_SCOPE_BASE, attrs2, NULL); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find ref_dn '%s'\n", ldb_dn_get_linearized(ref_dn))); return WERR_DS_DRA_INTERNAL_ERROR; } dNSHostName = ldb_msg_find_attr_as_string(res2->msgs[0], "dNSHostName", NULL); cn = ldb_msg_find_attr_as_string(res2->msgs[0], "cn", NULL); /* * construct a modify request to add the new SPNs to * the machine account */ msg = ldb_msg_new(mem_ctx); if (msg == NULL) { return WERR_NOT_ENOUGH_MEMORY; } msg->dn = ref_dn; ret = ldb_msg_add_empty(msg, "servicePrincipalName", LDB_FLAG_MOD_ADD, &el); if (ret != LDB_SUCCESS) { return WERR_NOT_ENOUGH_MEMORY; } ldb_msg_add_steal_string(msg, "servicePrincipalName", talloc_asprintf(el->values, "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s", ntds_guid_str, dom_string)); ldb_msg_add_steal_string(msg, "servicePrincipalName", talloc_asprintf(el->values, "ldap/%s._msdcs.%s", ntds_guid_str, dom_string)); if (cn) { ldb_msg_add_steal_string(msg, "servicePrincipalName", talloc_asprintf(el->values, "ldap/%s", cn)); } if (dNSHostName) { ldb_msg_add_steal_string(msg, "servicePrincipalName", talloc_asprintf(el->values, "ldap/%s", dNSHostName)); } if (el->num_values < 2) { return WERR_NOT_ENOUGH_MEMORY; } ret = dsdb_modify(b_state->sam_ctx, msg, DSDB_MODIFY_PERMISSIVE); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to add SPNs - %s\n", ldb_errstring(b_state->sam_ctx))); return WERR_DS_DRA_INTERNAL_ERROR; } } return WERR_OK; }
int sysdb_upgrade_08(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_9)); ret = ldb_transaction_start(sysdb->ldb); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* Add new indexes */ 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; } /* Add Index for servicePort and serviceProtocol */ 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", "servicePort"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "serviceProtocol"); 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; } /* 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_9); 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_9, ver); talloc_free(tmp_ctx); return ret; }
static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32_t type, DATA_BLOB data) { struct ldb_message *msg; char *name_dup, *type_str; int ret; msg = talloc_zero(mem_ctx, struct ldb_message); if (msg == NULL) { return NULL; } name_dup = talloc_strdup(msg, name); if (name_dup == NULL) { talloc_free(msg); return NULL; } ret = ldb_msg_add_string(msg, "value", name_dup); if (ret != LDB_SUCCESS) { talloc_free(msg); return NULL; } switch (type) { case REG_SZ: case REG_EXPAND_SZ: if ((data.length > 0) && (data.data != NULL)) { struct ldb_val *val; bool ret2 = false; val = talloc_zero(msg, struct ldb_val); if (val == NULL) { talloc_free(msg); return NULL; } /* The data is provided as UTF16 string */ ret2 = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, (void *)data.data, data.length, (void **)&val->data, &val->length); if (ret2) { ret = ldb_msg_add_value(msg, "data", val, NULL); } else { /* workaround for non-standard data */ ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL); } } else { ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL); } break; case REG_DWORD: case REG_DWORD_BIG_ENDIAN: if ((data.length > 0) && (data.data != NULL)) { if (data.length == sizeof(uint32_t)) { char *conv_str; conv_str = talloc_asprintf(msg, "0x%8.8x", IVAL(data.data, 0)); if (conv_str == NULL) { talloc_free(msg); return NULL; } ret = ldb_msg_add_string(msg, "data", conv_str); } else { /* workaround for non-standard data */ talloc_free(msg); return NULL; } } else { ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL); } break; case REG_QWORD: if ((data.length > 0) && (data.data != NULL)) { if (data.length == sizeof(uint64_t)) { char *conv_str; conv_str = talloc_asprintf(msg, "0x%16.16llx", (unsigned long long)BVAL(data.data, 0)); if (conv_str == NULL) { talloc_free(msg); return NULL; } ret = ldb_msg_add_string(msg, "data", conv_str); } else { /* workaround for non-standard data */ talloc_free(msg); return NULL; } } else { ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL); } break; case REG_BINARY: default: if ((data.length > 0) && (data.data != NULL)) { ret = ldb_msg_add_value(msg, "data", &data, NULL); } else { ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL); } break; }
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; }
static int acl_sDRightsEffective(struct ldb_module *module, struct ldb_message *sd_msg, struct ldb_message *msg, struct acl_context *ac) { struct ldb_message_element *rightsEffective; int ret; struct security_descriptor *sd; struct dom_sid *sid = NULL; uint32_t flags = 0; /* Must remove any existing attribute, or else confusion reins */ ldb_msg_remove_attr(msg, "sDRightsEffective"); ret = ldb_msg_add_empty(msg, "sDRightsEffective", 0, &rightsEffective); if (ret != LDB_SUCCESS) { return ret; } if (ac->user_type == SECURITY_SYSTEM) { flags = SECINFO_OWNER | SECINFO_GROUP | SECINFO_SACL | SECINFO_DACL; } else { /* Get the security descriptor from the message */ ret = get_sd_from_ldb_message(msg, sd_msg, &sd); if (ret != LDB_SUCCESS) { return ret; } ret = get_dom_sid_from_ldb_message(msg, sd_msg, &sid); if (ret != LDB_SUCCESS) { return ret; } ret = acl_check_access_on_attribute(module, msg, sd, sid, SEC_STD_WRITE_OWNER, NULL); if (ret == LDB_SUCCESS) { flags |= SECINFO_OWNER | SECINFO_GROUP; } ret = acl_check_access_on_attribute(module, msg, sd, sid, SEC_STD_WRITE_DAC, NULL); if (ret == LDB_SUCCESS) { flags |= SECINFO_DACL; } ret = acl_check_access_on_attribute(module, msg, sd, sid, SEC_FLAG_SYSTEM_SECURITY, NULL); if (ret == LDB_SUCCESS) { flags |= SECINFO_SACL; } } ldb_msg_add_fmt(msg, "sDRightsEffective", "%u", flags); return LDB_SUCCESS; }
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; }
static errno_t sysdb_svc_update(struct sysdb_ctx *sysdb, struct ldb_dn *dn, int port, const char **aliases, const char **protocols) { errno_t ret; struct ldb_message *msg; int lret; unsigned int i; if (!dn || !protocols || !protocols[0]) { return EINVAL; } msg = ldb_msg_new(NULL); if (!msg) { ret = ENOMEM; goto done; } msg->dn = dn; /* Update the port */ ret = add_ulong(msg, SYSDB_MOD_REP, SYSDB_SVC_PORT, port); if (ret != EOK) goto done; if (aliases && aliases[0]) { /* Update the aliases */ lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS, SYSDB_MOD_REP, NULL); if (lret != LDB_SUCCESS) { ret = ENOMEM; goto done; } for (i = 0; aliases[i]; i++) { lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]); if (lret != LDB_SUCCESS) { ret = EINVAL; goto done; } } } /* Update the protocols */ lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO, SYSDB_MOD_REP, NULL); if (lret != LDB_SUCCESS) { ret = ENOMEM; goto done; } for (i = 0; protocols[i]; i++) { lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]); if (lret != LDB_SUCCESS) { ret = EINVAL; goto done; } } lret = ldb_modify(sysdb->ldb, msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); } ret = sysdb_error_to_errno(lret); done: if (ret) { DEBUG(SSSDBG_TRACE_INTERNAL, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(msg); return ret; }
WERROR dns_replace_records(struct dns_server *dns, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, bool needs_add, const struct dnsp_DnssrvRpcRecord *records, uint16_t rec_count) { struct ldb_message_element *el; uint16_t i; int ret; struct ldb_message *msg = NULL; msg = ldb_msg_new(mem_ctx); W_ERROR_HAVE_NO_MEMORY(msg); msg->dn = dn; ret = ldb_msg_add_empty(msg, "dnsRecord", LDB_FLAG_MOD_REPLACE, &el); if (ret != LDB_SUCCESS) { return DNS_ERR(SERVER_FAILURE); } el->values = talloc_zero_array(el, struct ldb_val, rec_count); if (rec_count > 0) { W_ERROR_HAVE_NO_MEMORY(el->values); } for (i = 0; i < rec_count; i++) { static const struct dnsp_DnssrvRpcRecord zero; struct ldb_val *v = &el->values[el->num_values]; enum ndr_err_code ndr_err; if (memcmp(&records[i], &zero, sizeof(zero)) == 0) { continue; } ndr_err = ndr_push_struct_blob(v, el->values, &records[i], (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0, ("Failed to grab dnsp_DnssrvRpcRecord\n")); return DNS_ERR(SERVER_FAILURE); } el->num_values++; } if (el->num_values == 0) { if (needs_add) { return WERR_OK; } /* TODO: Delete object? */ } if (needs_add) { ret = ldb_msg_add_string(msg, "objectClass", "dnsNode"); if (ret != LDB_SUCCESS) { return DNS_ERR(SERVER_FAILURE); } ret = ldb_add(dns->samdb, msg); if (ret != LDB_SUCCESS) { return DNS_ERR(SERVER_FAILURE); } return WERR_OK; } ret = ldb_modify(dns->samdb, msg); if (ret != LDB_SUCCESS) { return DNS_ERR(SERVER_FAILURE); } return WERR_OK; }