Example #1
0
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);
}
Example #3
0
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);

}
Example #5
0
/*
  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;
}
Example #6
0
/*
  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;
}
Example #7
0
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;
}
Example #8
0
/*
  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 {
Example #9
0
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;
}
Example #10
0
/*
 * @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;
}
Example #11
0
/*
  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;
}
Example #12
0
/*
  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;
}
Example #13
0
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;
}
Example #14
0
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;
}
Example #15
0
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;
}
Example #16
0
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;
}
Example #17
0
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;
}
Example #18
0
/*
  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;
}
Example #19
0
/*
  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];
}
Example #20
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;
}
Example #21
0
/* 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);
}
Example #22
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;
}
Example #23
0
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;
}
Example #24
0
/* 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;
		}
	}
Example #25
0
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;
}
Example #27
0
/*
  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;
}
Example #28
0
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);
}
Example #29
0
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);
}
Example #30
0
/* 
   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;
}