示例#1
0
/**
 * Canonicalize a message, merging elements of the same name
 */
int ldb_msg_normalize(struct ldb_context *ldb,
		      TALLOC_CTX *mem_ctx,
		      const struct ldb_message *msg,
		      struct ldb_message **_msg_out)
{
	unsigned int i;
	struct ldb_message *msg2;

	msg2 = ldb_msg_copy(mem_ctx, msg);
	if (msg2 == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ldb_msg_sort_elements(msg2);

	for (i=1; i < msg2->num_elements; i++) {
		struct ldb_message_element *el1 = &msg2->elements[i-1];
		struct ldb_message_element *el2 = &msg2->elements[i];

		if (ldb_msg_element_compare_name(el1, el2) == 0) {
			el1->values = talloc_realloc(msg2->elements,
			                             el1->values, struct ldb_val,
			                             el1->num_values + el2->num_values);
			if (el1->num_values + el2->num_values > 0 && el1->values == NULL) {
				talloc_free(msg2);
				return LDB_ERR_OPERATIONS_ERROR;
			}
			memcpy(el1->values + el1->num_values,
			       el2->values,
			       sizeof(struct ldb_val) * el2->num_values);
			el1->num_values += el2->num_values;
			talloc_free(discard_const_p(char, el2->name));
			if ((i+1) < msg2->num_elements) {
				memmove(el2, el2+1, sizeof(struct ldb_message_element) *
					(msg2->num_elements - (i+1)));
			}
			msg2->num_elements--;
			i--;
		}
	}
示例#2
0
static int samldb_fill_foreignSecurityPrincipal_object(struct ldb_module *module, const struct ldb_message *msg, 
						       struct ldb_message **ret_msg)
{
	struct ldb_message *msg2;
	const char *rdn_name;
	struct dom_sid *dom_sid;
	struct dom_sid *sid;
	const char *dom_attrs[] = { "name", NULL };
	struct ldb_message **dom_msgs;
	const char *errstr;
	int ret;

	TALLOC_CTX *mem_ctx = talloc_new(msg);
	if (!mem_ctx) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* build the new msg */
	msg2 = ldb_msg_copy(mem_ctx, msg);
	if (!msg2) {
		ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_foreignSecurityPrincpal_object: ldb_msg_copy failed!\n");
		talloc_free(mem_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ret = samdb_copy_template(module->ldb, msg2, 
				  "(&(CN=TemplateForeignSecurityPrincipal)(objectclass=foreignSecurityPrincipalTemplate))",
				  &errstr);
	if (ret != 0) {
		ldb_asprintf_errstring(module->ldb, 
				       "samldb_fill_foreignSecurityPrincipal_object: "
				       "Error copying template: %s",
				    errstr);
		talloc_free(mem_ctx);
		return ret;
	}

	rdn_name = ldb_dn_get_rdn_name(msg2->dn);

	if (strcasecmp(rdn_name, "cn") != 0) {
		ldb_asprintf_errstring(module->ldb, "Bad RDN (%s=) for ForeignSecurityPrincipal, should be CN=!", rdn_name);
		talloc_free(mem_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	/* Slightly different for the foreign sids.  We don't want
	 * domain SIDs ending up there, it would cause all sorts of
	 * pain */

	sid = dom_sid_parse_talloc(msg2, (const char *)ldb_dn_get_rdn_val(msg2->dn)->data);
	if (!sid) {
		ldb_set_errstring(module->ldb, "No valid found SID in ForeignSecurityPrincipal CN!");
		talloc_free(mem_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	if ( ! samldb_msg_add_sid(module, msg2, "objectSid", sid)) {
		talloc_free(sid);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	dom_sid = dom_sid_dup(mem_ctx, sid);
	if (!dom_sid) {
		talloc_free(mem_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}
	/* get the domain component part of the provided SID */
	dom_sid->num_auths--;

	/* find the domain DN */

	ret = gendb_search(module->ldb,
			   mem_ctx, NULL, &dom_msgs, dom_attrs,
			   "(&(objectSid=%s)(objectclass=domain))",
			   ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
	if (ret >= 1) {
		/* We don't really like the idea of foreign sids that are not foreign, but it happens */
		const char *name = samdb_result_string(dom_msgs[0], "name", NULL);
		ldb_debug(module->ldb, LDB_DEBUG_TRACE, "NOTE (strange but valid): Adding foreign SID record with SID %s, but this domian (%s) is already in the database", 
			  dom_sid_string(mem_ctx, sid), name); 
	} else if (ret == -1) {
		ldb_asprintf_errstring(module->ldb,
					"samldb_fill_foreignSecurityPrincipal_object: error searching for a domain with this sid: %s\n", 
					dom_sid_string(mem_ctx, dom_sid));
		talloc_free(dom_msgs);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* This isn't an operation on a domain we know about, so just
	 * check for the SID, looking for duplicates via the common
	 * code */
	ret = samldb_notice_sid(module, msg2, sid);
	if (ret == 0) {
		talloc_steal(msg, msg2);
		*ret_msg = msg2;
	}
	
	return ret;
}
示例#3
0
static int samldb_fill_user_or_computer_object(struct ldb_module *module, const struct ldb_message *msg,
							       struct ldb_message **ret_msg)
{
	int ret;
	char *name;
	struct ldb_message *msg2;
	const char *rdn_name;
	TALLOC_CTX *mem_ctx = talloc_new(msg);
	const char *errstr;
	if (!mem_ctx) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* build the new msg */
	msg2 = ldb_msg_copy(mem_ctx, msg);
	if (!msg2) {
		ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: ldb_msg_copy failed!\n");
		talloc_free(mem_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	if (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") != NULL) {

		ret = samdb_copy_template(module->ldb, msg2, 
					  "(&(CN=TemplateComputer)(objectclass=userTemplate))", 
					  &errstr);
		if (ret) {
			ldb_asprintf_errstring(module->ldb, 
					       "samldb_fill_user_or_computer_object: "
					       "Error copying computer template: %s",
					       errstr);
			talloc_free(mem_ctx);
			return ret;
		}

		/* readd user and then computer objectclasses */
		ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "user");
		if (ret) {
			talloc_free(mem_ctx);
			return ret;
		}
		ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "computer");
		if (ret) {
			talloc_free(mem_ctx);
			return ret;
		}
		
	} else {
		ret = samdb_copy_template(module->ldb, msg2, 
					  "(&(CN=TemplateUser)(objectclass=userTemplate))", 
					  &errstr);
		if (ret) {
			ldb_asprintf_errstring(module->ldb, 
					       "samldb_fill_user_or_computer_object: Error copying user template: %s\n",
					       errstr);
			talloc_free(mem_ctx);
			return ret;
		}
		/* readd user objectclass */
		ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "user");
		if (ret) {
			talloc_free(mem_ctx);
			return ret;
		}
	}

	rdn_name = ldb_dn_get_rdn_name(msg2->dn);

	if (strcasecmp(rdn_name, "cn") != 0) {
		ldb_asprintf_errstring(module->ldb, "Bad RDN (%s=) for user/computer, should be CN=!\n", rdn_name);
		talloc_free(mem_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	if (ldb_msg_find_element(msg2, "samAccountName") == NULL) {
		name = samldb_generate_samAccountName(module, mem_ctx);
		if (!name) {
			talloc_free(mem_ctx);
			return LDB_ERR_OPERATIONS_ERROR;
		}
		ret = samdb_find_or_add_attribute(module->ldb, msg2, "sAMAccountName", name);
		if (ret) {
			talloc_free(mem_ctx);
			return ret;
		}
	}

	/*
	  TODO: useraccountcontrol: setting value 0 gives 0x200 for users
	*/

	/* Manage SID allocation, conflicts etc */
	ret = samldb_handle_sid(module, mem_ctx, msg2); 

	/* TODO: objectCategory, userAccountControl, badPwdCount, codePage, countryCode, badPasswordTime, lastLogoff, lastLogon, pwdLastSet, primaryGroupID, accountExpires, logonCount */

	if (ret == 0) {
		*ret_msg = msg2;
		talloc_steal(msg, msg2);
	}
	talloc_free(mem_ctx);
	return ret;
}
示例#4
0
static int samldb_fill_group_object(struct ldb_module *module, const struct ldb_message *msg,
						    struct ldb_message **ret_msg)
{
	int ret;
	const char *name;
	struct ldb_message *msg2;
	const char *rdn_name;
	TALLOC_CTX *mem_ctx = talloc_new(msg);
	const char *errstr;
	if (!mem_ctx) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* build the new msg */
	msg2 = ldb_msg_copy(mem_ctx, msg);
	if (!msg2) {
		ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: ldb_msg_copy failed!\n");
		talloc_free(mem_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ret = samdb_copy_template(module->ldb, msg2, 
				  "(&(CN=TemplateGroup)(objectclass=groupTemplate))",
				  &errstr);
	if (ret != 0) {
		
		talloc_free(mem_ctx);
		return ret;
	}

	rdn_name = ldb_dn_get_rdn_name(msg2->dn);

	if (strcasecmp(rdn_name, "cn") != 0) {
		ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: Bad RDN (%s) for group!\n", rdn_name);
		talloc_free(mem_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	/* Generate a random name, if no samAccountName was supplied */
	if (ldb_msg_find_element(msg2, "samAccountName") == NULL) {
		name = samldb_generate_samAccountName(module, mem_ctx);
		if (!name) {
			talloc_free(mem_ctx);
			return LDB_ERR_OPERATIONS_ERROR;
		}
		ret = samdb_find_or_add_attribute(module->ldb, msg2, "sAMAccountName", name);
		if (ret) {
			talloc_free(mem_ctx);
			return ret;
		}
	}
	
	/* Manage SID allocation, conflicts etc */
	ret = samldb_handle_sid(module, mem_ctx, msg2); 

	if (ret == LDB_SUCCESS) {
		talloc_steal(msg, msg2);
		*ret_msg = msg2;
	}
	talloc_free(mem_ctx);
	return ret;
}