static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; ldb = ldb_module_get_ctx(module); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.mod.message->dn)) { return ldb_next_request(module, req); } if (ldb_msg_find_element(req->op.mod.message, "name")) { ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead", ldb_dn_get_linearized(req->op.mod.message->dn)); return LDB_ERR_NOT_ALLOWED_ON_RDN; } if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) { ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead", ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn)); return LDB_ERR_NOT_ALLOWED_ON_RDN; } /* All OK, they kept their fingers out of the special attributes */ return ldb_next_request(module, req); }
static char *sldb_string_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name, const char *defval) { struct ldb_message *msg; struct ldb_message_element *el; const char *colon; if (scfg == NULL) return talloc_strdup(mem_ctx, defval); msg = talloc_get_type(scfg->opaque, struct ldb_message); colon = strchr(opt_name, ':'); if (colon != NULL) { char *name; name = talloc_strdup(scfg, opt_name); if (!name) { return NULL; } name[colon-opt_name] = '-'; el = ldb_msg_find_element(msg, name); TALLOC_FREE(name); } else { el = ldb_msg_find_element(msg, opt_name); } if (el == NULL) { return talloc_strdup(mem_ctx, defval); } return (char *)(el->values[0].data); }
static const char *sldb_string_option(struct share_config *scfg, const char *opt_name, const char *defval) { struct ldb_message *msg; struct ldb_message_element *el; if (scfg == NULL) return defval; msg = talloc_get_type(scfg->opaque, struct ldb_message); if (strchr(opt_name, ':')) { char *name, *p; name = talloc_strdup(scfg, opt_name); if (!name) { return NULL; } p = strchr(name, ':'); *p = '-'; el = ldb_msg_find_element(msg, name); } else { el = ldb_msg_find_element(msg, opt_name); } if (el == NULL) { return defval; } return (const char *)(el->values[0].data); }
/* * Attempt to modify an objectSID DSDB_CONTROL_REPLICATED_UPDATE_OID set * this should succeed */ static void test_modify_of_objectSID_replicated(void **state) { struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_context *ldb = test_ctx->ldb; struct ldb_message *msg = ldb_msg_new(test_ctx); struct ldb_message_element *el = NULL; struct ldb_request *request = NULL; struct ldb_request *original_request = NULL; int rc; msg->dn = ldb_dn_new(msg, ldb, "dc=test"); add_sid(msg, LOCAL_SID); rc = ldb_build_mod_req( &request, test_ctx->ldb, test_ctx, msg, NULL, NULL, ldb_op_default_callback, NULL); assert_int_equal(rc, LDB_SUCCESS); assert_non_null(request); original_request = request; rc = ldb_request_add_control( request, DSDB_CONTROL_REPLICATED_UPDATE_OID, false, NULL); assert_int_equal(rc, LDB_SUCCESS); rc = unique_object_sids_modify(test_ctx->module, request); assert_int_equal(rc, LDB_SUCCESS); /* * Check that a copy of the request was passed to the next module * and not the original request */ assert_ptr_not_equal(last_request, original_request); /* * Check the flag was set on the request passed to the next * module */ el = ldb_msg_find_element(last_request->op.add.message, "objectSID"); assert_non_null(el); assert_true(el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX); /* * Check the flag was not set on the original request */ el = ldb_msg_find_element(request->op.add.message, "objectSID"); assert_non_null(el); assert_false(el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX); }
/* make sure we only add repsFrom entries for DCs who are masters for the partition */ static bool check_MasterNC(struct kccsrv_partition *p, struct repsFromToBlob *r, struct ldb_result *res) { struct repsFromTo1 *r1 = &r->ctr.ctr1; struct GUID invocation_id = r1->source_dsa_invocation_id; unsigned int i, j; /* we are expecting only version 1 */ SMB_ASSERT(r->version == 1); for (i=0; i<res->count; i++) { struct ldb_message *msg = res->msgs[i]; struct ldb_message_element *el; struct ldb_dn *dn; struct GUID id2 = samdb_result_guid(msg, "invocationID"); if (GUID_all_zero(&id2) || !GUID_equal(&invocation_id, &id2)) { continue; } el = ldb_msg_find_element(msg, "msDS-hasMasterNCs"); if (!el || el->num_values == 0) { el = ldb_msg_find_element(msg, "hasMasterNCs"); if (!el || el->num_values == 0) { continue; } } for (j=0; j<el->num_values; j++) { dn = ldb_dn_from_ldb_val(p, p->service->samdb, &el->values[j]); if (!ldb_dn_validate(dn)) { talloc_free(dn); continue; } if (ldb_dn_compare(dn, p->dn) == 0) { talloc_free(dn); DEBUG(5,("%s %s match on %s in %s\n", r1->other_info->dns_name, el->name, ldb_dn_get_linearized(dn), ldb_dn_get_linearized(msg->dn))); return true; } talloc_free(dn); } } return false; }
/* 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 errno_t find_sss_id_type(struct ldb_message *msg, bool mpg, enum sss_id_type *id_type) { size_t c; struct ldb_message_element *el; struct ldb_val *val = NULL; el = ldb_msg_find_element(msg, SYSDB_OBJECTCATEGORY); if (el == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Objectcategory attribute not found.\n"); return EINVAL; } for (c = 0; c < el->num_values; c++) { val = &(el->values[c]); if (strncasecmp(SYSDB_USER_CLASS, (char *)val->data, val->length) == 0) { break; } } if (c == el->num_values) { *id_type = SSS_ID_TYPE_GID; } else { if (mpg) { *id_type = SSS_ID_TYPE_BOTH; } else { *id_type = SSS_ID_TYPE_UID; } } return EOK; }
/* add one element to a message */ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_element *el, int check_duplicates) { unsigned int i; struct ldb_message_element *e2, *elnew; if (check_duplicates && ldb_msg_find_element(ret, el->name)) { /* its already there */ return 0; } e2 = talloc_realloc(ret, ret->elements, struct ldb_message_element, ret->num_elements+1); if (!e2) { return -1; } ret->elements = e2; elnew = &e2[ret->num_elements]; elnew->name = talloc_strdup(ret->elements, el->name); if (!elnew->name) { return -1; } if (el->num_values) { elnew->values = talloc_array(ret->elements, struct ldb_val, el->num_values); if (!elnew->values) { return -1; } } else {
static int get_dom_sid_from_ldb_message(TALLOC_CTX *mem_ctx, struct ldb_message *acl_res, struct dom_sid **sid) { struct ldb_message_element *sid_element; enum ndr_err_code ndr_err; sid_element = ldb_msg_find_element(acl_res, "objectSid"); if (!sid_element) { *sid = NULL; return LDB_SUCCESS; } *sid = talloc(mem_ctx, struct dom_sid); if(!*sid) { return LDB_ERR_OPERATIONS_ERROR; } ndr_err = ndr_pull_struct_blob(&sid_element->values[0], *sid, NULL, *sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; }
/* * @brief Decrypt all the secret attributes on an ldb_message * * Decrypt all the secret attributes on an ldb_message. Any secret attributes * are removed from message and decrypted copies of the attributes added. * In the event of an error the contents of the message will be inconsistent. * * @param ldb ldb context, to allow logging. * @param msg The ldb_message to have it's secret attributes encrypted. * @param data The context data for this module. * * @returns ldb status code * LDB_SUCESS If the value was successfully encrypted * LDB_ERR_OPERATIONS_ERROR If there was an error. */ static int decrypt_secret_attributes(struct ldb_context *ldb, struct ldb_message *msg, struct es_data *data) { int i, ret; if (ldb_dn_is_special(msg->dn)) { return LDB_SUCCESS; } for (i = 0; i < num_secret_attributes; i++) { struct ldb_message_element *el = ldb_msg_find_element(msg, secret_attributes[i]); if (el != NULL) { const int flags = el->flags; struct ldb_message_element* dec = decrypt_element(&ret, msg->elements, ldb, el, data); if (ret != LDB_SUCCESS) { return ret; } ldb_msg_remove_element(msg, el); ret = ldb_msg_add(msg, dec, flags); if (ret != LDB_SUCCESS) { return ret; } } } return LDB_SUCCESS; }
/* delete all elements having a specified attribute name */ static int msg_delete_attribute(struct ldb_module *module, struct ldb_context *ldb, struct ldb_message *msg, const char *name) { unsigned int i; int ret; struct ldb_message_element *el; el = ldb_msg_find_element(msg, name); if (el == NULL) { return LDB_ERR_NO_SUCH_ATTRIBUTE; } i = el - msg->elements; ret = ltdb_index_del_element(module, msg->dn, el); if (ret != LDB_SUCCESS) { return ret; } talloc_free(el->values); if (msg->num_elements > (i+1)) { memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1))); } msg->num_elements--; msg->elements = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements); return LDB_SUCCESS; }
/* return an array of SIDs from a ldb_message given an attribute name assumes the SIDs are in extended DN format */ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, struct ldb_message *msg, TALLOC_CTX *mem_ctx, const char *attr, const struct dom_sid ***sids) { struct ldb_message_element *el; unsigned int i; el = ldb_msg_find_element(msg, attr); if (!el) { *sids = NULL; return WERR_OK; } (*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1); W_ERROR_HAVE_NO_MEMORY(*sids); for (i=0; i<el->num_values; i++) { struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, sam_ctx, &el->values[i]); NTSTATUS status; struct dom_sid *sid; sid = talloc(*sids, struct dom_sid); W_ERROR_HAVE_NO_MEMORY(sid); status = dsdb_get_extended_dn_sid(dn, sid, "SID"); if (!NT_STATUS_IS_OK(status)) { return WERR_INTERNAL_DB_CORRUPTION; } (*sids)[i] = sid; } (*sids)[i] = NULL; return WERR_OK; }
int dsdb_get_sd_from_ldb_message(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_message *acl_res, struct security_descriptor **sd) { struct ldb_message_element *sd_element; enum ndr_err_code ndr_err; sd_element = ldb_msg_find_element(acl_res, "nTSecurityDescriptor"); if (sd_element == NULL) { return ldb_error(ldb, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS, "nTSecurityDescriptor is missing"); } *sd = talloc(mem_ctx, struct security_descriptor); if(!*sd) { return ldb_oom(ldb); } ndr_err = ndr_pull_struct_blob(&sd_element->values[0], *sd, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ldb_operr(ldb); } return LDB_SUCCESS; }
static int get_sd_from_ldb_message(TALLOC_CTX *mem_ctx, struct ldb_message *acl_res, struct security_descriptor **sd) { struct ldb_message_element *sd_element; enum ndr_err_code ndr_err; sd_element = ldb_msg_find_element(acl_res, "nTSecurityDescriptor"); if (!sd_element) { *sd = NULL; return LDB_SUCCESS; } *sd = talloc(mem_ctx, struct security_descriptor); if(!*sd) { return LDB_ERR_OPERATIONS_ERROR; } ndr_err = ndr_pull_struct_blob(&sd_element->values[0], *sd, NULL, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; }
WERROR dreplsrv_load_partitions(struct dreplsrv_service *s) { WERROR status; static const char *attrs[] = { "namingContexts", NULL }; unsigned int i; int ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_message_element *el; tmp_ctx = talloc_new(s); W_ERROR_HAVE_NO_MEMORY(tmp_ctx); ret = ldb_search(s->samdb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, s->samdb, ""), LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } el = ldb_msg_find_element(res->msgs[0], "namingContexts"); if (!el) { DEBUG(1,("Finding namingContexts element in root_res failed: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } for (i=0; i<el->num_values; i++) { struct ldb_dn *pdn; struct dreplsrv_partition *p; pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]); if (pdn == NULL) { talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } if (!ldb_dn_validate(pdn)) { return WERR_DS_DRA_INTERNAL_ERROR; } p = talloc_zero(s, struct dreplsrv_partition); W_ERROR_HAVE_NO_MEMORY(p); p->dn = talloc_steal(p, pdn); DLIST_ADD(s->partitions, p); DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn))); } talloc_free(tmp_ctx); status = dreplsrv_refresh_partitions(s); W_ERROR_NOT_OK_RETURN(status); return WERR_OK; }
bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *res, const char *field, uint32_t *ret) { if (ldb_msg_find_element(res->msgs[0], field) == NULL) { return false; } *ret = ldb_msg_find_attr_as_uint(res->msgs[0], field, 0); return true; }
errno_t sss_mc_refresh_nested_group(struct tools_ctx *tctx, const char *name) { errno_t ret; struct ldb_message *msg; struct ldb_message_element *el; const char *attrs[] = { SYSDB_MEMBEROF, SYSDB_NAME, NULL }; size_t i; char *parent_name; ret = sss_mc_refresh_group(name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, ("Cannot refresh group %s from memory cache\n", name)); /* try to carry on */ } ret = sysdb_search_group_by_name(tctx, tctx->sysdb, tctx->local, name, attrs, &msg); if (ret) { DEBUG(SSSDBG_OP_FAILURE, ("Search failed: %s (%d)\n", strerror(ret), ret)); return ret; } el = ldb_msg_find_element(msg, SYSDB_MEMBEROF); if (!el || el->num_values == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, ("Group %s has no parents\n", name)); talloc_free(msg); return EOK; } /* This group is nested. We need to invalidate all its parents, too */ for (i=0; i < el->num_values; i++) { ret = sysdb_group_dn_name(tctx->sysdb, tctx, (const char *) el->values[i].data, &parent_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, ("Malformed DN [%s]? Skipping\n", (const char *) el->values[i].data)); talloc_free(parent_name); continue; } ret = sss_mc_refresh_group(parent_name); talloc_free(parent_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, ("Cannot refresh group %s from memory cache\n", name)); /* try to carry on */ } } talloc_free(msg); return EOK; }
/* construct msDS-isRODC attr */ static int construct_msds_isrodc(struct ldb_module *module, struct ldb_message *msg, enum ldb_scope scope, struct ldb_request *parent) { struct ldb_message_element * object_class; struct ldb_message_element * object_category; unsigned int i; object_class = ldb_msg_find_element(msg, "objectClass"); if (!object_class) { DEBUG(4,(__location__ ": Can't get objectClass for %s \n", ldb_dn_get_linearized(msg->dn))); return ldb_operr(ldb_module_get_ctx(module)); } for (i=0; i<object_class->num_values; i++) { if (strequal((const char*)object_class->values[i].data, "nTDSDSA")) { /* If TO!objectCategory equals the DN of the classSchema object for the nTDSDSA * object class, then TO!msDS-isRODC is false. Otherwise, TO!msDS-isRODC is true. */ object_category = ldb_msg_find_element(msg, "objectCategory"); if (!object_category) { DEBUG(4,(__location__ ": Can't get objectCategory for %s \n", ldb_dn_get_linearized(msg->dn))); return LDB_SUCCESS; } return construct_msds_isrodc_with_dn(module, msg, object_category); } if (strequal((const char*)object_class->values[i].data, "server")) { /* Let TN be the nTDSDSA object whose DN is "CN=NTDS Settings," prepended to * the DN of TO. Apply the previous rule for the "TO is an nTDSDSA object" case, * substituting TN for TO. */ return construct_msds_isrodc_with_server_dn(module, msg, msg->dn, parent); } if (strequal((const char*)object_class->values[i].data, "computer")) { /* Let TS be the server object named by TO!serverReferenceBL. Apply the previous * rule for the "TO is a server object" case, substituting TS for TO. */ return construct_msds_isrodc_with_computer_dn(module, msg, parent); } } return LDB_SUCCESS; }
/* convenience functions to return common types from a message these return the first value if the attribute is multi-valued */ const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name) { struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name); if (!el || el->num_values == 0) { return NULL; } return &el->values[0]; }
/* match a simple leaf node */ static int ldb_match_equality(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, bool *matched) { unsigned int i; struct ldb_message_element *el; const struct ldb_schema_attribute *a; struct ldb_dn *valuedn; int ret; if (ldb_attr_dn(tree->u.equality.attr) == 0) { valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value); if (valuedn == NULL) { return LDB_ERR_INVALID_DN_SYNTAX; } ret = ldb_dn_compare(msg->dn, valuedn); talloc_free(valuedn); *matched = (ret == 0); return LDB_SUCCESS; } /* TODO: handle the "*" case derived from an extended search operation without the attibute type defined */ el = ldb_msg_find_element(msg, tree->u.equality.attr); if (el == NULL) { *matched = false; return LDB_SUCCESS; } a = ldb_schema_attribute_by_name(ldb, el->name); if (a == NULL) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } for (i=0;i<el->num_values;i++) { if (a->syntax->operator_fn) { ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, &tree->u.equality.value, &el->values[i], matched); if (ret != LDB_SUCCESS) return ret; if (*matched) return LDB_SUCCESS; } else { if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value, &el->values[i]) == 0) { *matched = true; return LDB_SUCCESS; } } } *matched = false; return LDB_SUCCESS; }
/* Generate a remote message with a mapped objectClass. */ static void map_objectclass_generate_remote(struct ldb_module *module, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local) { const struct ldb_map_context *data = map_get_context(module); struct ldb_context *ldb; struct ldb_message_element *el, *oc; struct ldb_val val; bool found_extensibleObject = false; unsigned int i; ldb = ldb_module_get_ctx(module); /* Find old local objectClass */ oc = ldb_msg_find_element(old, "objectClass"); if (oc == NULL) { return; } /* Prepare new element */ el = talloc_zero(remote, struct ldb_message_element); if (el == NULL) { ldb_oom(ldb); return; /* TODO: fail? */ } /* Copy local objectClass element, reverse space for an extra value */ el->num_values = oc->num_values + 1; el->values = talloc_array(el, struct ldb_val, el->num_values); if (el->values == NULL) { talloc_free(el); ldb_oom(ldb); return; /* TODO: fail? */ } /* Copy local element name "objectClass" */ el->name = talloc_strdup(el, local_attr); /* Convert all local objectClasses */ for (i = 0; i < el->num_values - 1; i++) { el->values[i] = map_objectclass_convert_local(module, el->values, &oc->values[i]); if (ldb_attr_cmp((char *)el->values[i].data, data->add_objectclass) == 0) { found_extensibleObject = true; } } if (!found_extensibleObject) { val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); val.length = strlen((char *)val.data); /* Append additional objectClass data->add_objectclass */ el->values[i] = val; } else { el->num_values--; } /* Add new objectClass to remote message */ ldb_msg_add(remote, el, 0); }
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; }
WERROR dreplsrv_load_partitions(struct dreplsrv_service *s) { WERROR status; struct ldb_dn *basedn; struct ldb_result *r; struct ldb_message_element *el; static const char *attrs[] = { "namingContexts", NULL }; uint32_t i; int ret; basedn = ldb_dn_new(s, s->samdb, NULL); W_ERROR_HAVE_NO_MEMORY(basedn); ret = ldb_search(s->samdb, s, &r, basedn, LDB_SCOPE_BASE, attrs, "(objectClass=*)"); talloc_free(basedn); if (ret != LDB_SUCCESS) { return WERR_FOOBAR; } else if (r->count != 1) { talloc_free(r); return WERR_FOOBAR; } el = ldb_msg_find_element(r->msgs[0], "namingContexts"); if (!el) { return WERR_FOOBAR; } for (i=0; el && i < el->num_values; i++) { const char *v = (const char *)el->values[i].data; struct ldb_dn *pdn; struct dreplsrv_partition *p; pdn = ldb_dn_new(s, s->samdb, v); if (!ldb_dn_validate(pdn)) { return WERR_FOOBAR; } p = talloc_zero(s, struct dreplsrv_partition); W_ERROR_HAVE_NO_MEMORY(p); p->dn = talloc_steal(p, pdn); DLIST_ADD(s->partitions, p); DEBUG(2, ("dreplsrv_partition[%s] loaded\n", v)); } talloc_free(r); status = dreplsrv_refresh_partitions(s); W_ERROR_NOT_OK_RETURN(status); return WERR_OK; }
/* Generate a local message with a mapped objectClass. */ static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote) { const struct ldb_map_context *data = map_get_context(module); struct ldb_context *ldb; struct ldb_message_element *el, *oc; struct ldb_val val; unsigned int i; ldb = ldb_module_get_ctx(module); /* Find old remote objectClass */ oc = ldb_msg_find_element(remote, "objectClass"); if (oc == NULL) { return NULL; } /* Prepare new element */ el = talloc_zero(mem_ctx, struct ldb_message_element); if (el == NULL) { ldb_oom(ldb); return NULL; } /* Copy remote objectClass element */ el->num_values = oc->num_values; el->values = talloc_array(el, struct ldb_val, el->num_values); if (el->values == NULL) { talloc_free(el); ldb_oom(ldb); return NULL; } /* Copy remote element name "objectClass" */ el->name = talloc_strdup(el, local_attr); /* Convert all remote objectClasses */ for (i = 0; i < el->num_values; i++) { el->values[i] = map_objectclass_convert_remote(module, el->values, &oc->values[i]); } val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); val.length = strlen((char *)val.data); /* Remove last value if it was the string in data->add_objectclass (eg samba4top, extensibleObject) */ if (ldb_val_equal_exact(&val, &el->values[i-1])) { el->num_values--; el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values); if (el->values == NULL) { talloc_free(el); ldb_oom(ldb); return NULL; } }
static int ldb_match_comparison(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, enum ldb_parse_op comp_op, bool *matched) { unsigned int i; struct ldb_message_element *el; const struct ldb_schema_attribute *a; /* FIXME: APPROX comparison not handled yet */ if (comp_op == LDB_OP_APPROX) { return LDB_ERR_INAPPROPRIATE_MATCHING; } el = ldb_msg_find_element(msg, tree->u.comparison.attr); if (el == NULL) { *matched = false; return LDB_SUCCESS; } a = ldb_schema_attribute_by_name(ldb, el->name); if (!a) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } for (i = 0; i < el->num_values; i++) { if (a->syntax->operator_fn) { int ret; ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched); if (ret != LDB_SUCCESS) return ret; if (*matched) return LDB_SUCCESS; } else { int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); if (ret == 0) { *matched = true; return LDB_SUCCESS; } if (ret > 0 && comp_op == LDB_OP_GREATER) { *matched = true; return LDB_SUCCESS; } if (ret < 0 && comp_op == LDB_OP_LESS) { *matched = true; return LDB_SUCCESS; } } } *matched = false; return LDB_SUCCESS; }
/** \details Retrieve a property on a LDB message \param mem_ctx pointer to the memory context \param message_object the openchangedb message to retrieve data from \param proptag the MAPI property tag to lookup \param data pointer on pointer to the data to return \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_message_get_property(TALLOC_CTX *mem_ctx, void *message_object, uint32_t proptag, void **data) { struct openchangedb_message *msg; struct ldb_message *message; char *PidTagAttr = NULL; bool tofree = false; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!data, MAPI_E_NOT_INITIALIZED, NULL); msg = (struct openchangedb_message *)message_object; /* Get results from correct location */ switch (msg->status) { case OPENCHANGEDB_MESSAGE_CREATE: OPENCHANGE_RETVAL_IF(!msg->msg, MAPI_E_NOT_INITIALIZED, NULL); message = msg->msg; break; case OPENCHANGEDB_MESSAGE_OPEN: OPENCHANGE_RETVAL_IF(!msg->res, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!msg->res->count, MAPI_E_NOT_INITIALIZED, NULL); message = msg->res->msgs[0]; break; default: return MAPI_E_INVALID_PARAMETER; } /* Turn property into PidTagAttr */ PidTagAttr = (char *) openchangedb_property_get_attribute(proptag); if (!PidTagAttr) { tofree = true; PidTagAttr = talloc_asprintf(mem_ctx, "%.8x", proptag); } /* Ensure the element exists */ OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(message, PidTagAttr), MAPI_E_NOT_FOUND, (tofree == true) ? PidTagAttr : NULL); /* Retrieve data */ *data = openchangedb_get_property_data_message(mem_ctx, message, proptag, PidTagAttr); OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, (tofree == true) ? PidTagAttr : NULL); if (tofree == true) { talloc_free(PidTagAttr); } return MAPI_E_NOT_FOUND; }
/* enumerate sids that have the given alias set in member */ static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, size_t *num) { const char *attrs[] = { "member", NULL }; int ret, i; NTSTATUS status = NT_STATUS_OK; struct ldb_result *res=NULL; struct ldb_dn *dn; struct ldb_message_element *el; *sids = NULL; *num = 0; dn = mapping_dn(ldb, alias); if (dn == NULL) { return NT_STATUS_NO_MEMORY; } ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, attrs, &res); if (ret == LDB_SUCCESS && res->count == 0) { talloc_free(res); talloc_free(dn); return NT_STATUS_OK; } if (ret != LDB_SUCCESS) { talloc_free(dn); return NT_STATUS_INTERNAL_DB_CORRUPTION; } talloc_steal(dn, res); el = ldb_msg_find_element(res->msgs[0], "member"); if (el == NULL) { talloc_free(dn); return NT_STATUS_OK; } for (i=0;i<el->num_values;i++) { DOM_SID sid; string_to_sid(&sid, (const char *)el->values[i].data); status = add_sid_to_array_unique(NULL, &sid, sids, num); if (!NT_STATUS_IS_OK(status)) { goto done; } } done: talloc_free(dn); return status; }
const struct GUID *get_oc_guid_from_message(struct ldb_module *module, const struct dsdb_schema *schema, struct ldb_message *msg) { struct ldb_message_element *oc_el; oc_el = ldb_msg_find_element(msg, "objectClass"); if (!oc_el) { return NULL; } return class_schemaid_guid_by_lDAPDisplayName(schema, (char *)oc_el->values[oc_el->num_values-1].data); }
static const struct GUID *get_oc_guid_from_message(struct ldb_module *module, struct ldb_message *msg) { struct ldb_message_element *oc_el; struct ldb_context *ldb = ldb_module_get_ctx(module); oc_el = ldb_msg_find_element(msg, "objectClass"); if (!oc_el) { return NULL; } return class_schemaid_guid_by_lDAPDisplayName(dsdb_get_schema(ldb), (char *)oc_el->values[oc_el->num_values-1].data); }
/* This operation happens on session setup, so it should better be fast. We store a list of aliases a SID is member of hanging off MEMBEROF/SID. */ static NTSTATUS one_alias_membership(const DOM_SID *member, DOM_SID **sids, size_t *num) { const char *attrs[] = { "sid", NULL }; DOM_SID alias; char *expr; int ret, i; struct ldb_result *res=NULL; fstring string_sid; NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION; if (!sid_to_fstring(string_sid, member)) { return NT_STATUS_INVALID_PARAMETER; } expr = talloc_asprintf(ldb, "(&(member=%s)(objectClass=groupMap))", string_sid); if (expr == NULL) goto failed; ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, attrs, &res); talloc_steal(expr, res); if (ret != LDB_SUCCESS) { goto failed; } for (i=0;i<res->count;i++) { struct ldb_message_element *el; el = ldb_msg_find_element(res->msgs[i], "sid"); if (el == NULL || el->num_values != 1) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; goto failed; } string_to_sid(&alias, (char *)el->values[0].data); status = add_sid_to_array_unique(NULL, &alias, sids, num); if (!NT_STATUS_IS_OK(status)) { goto failed; } } talloc_free(expr); return NT_STATUS_OK; failed: talloc_free(expr); return status; }