Ejemplo n.º 1
0
static NTSTATUS tcp_ldap_rootdse(void *data,
				 TALLOC_CTX *mem_ctx,
				 struct cldap_search *io)
{
	struct ldap_connection *conn = talloc_get_type(data,
						       struct ldap_connection);
	struct ldap_message *msg, *result;
	struct ldap_request *req;
	int i;
	NTSTATUS status;

	msg = new_ldap_message(mem_ctx);
	if (!msg) {
		return NT_STATUS_NO_MEMORY;
	}

	msg->type = LDAP_TAG_SearchRequest;
	msg->r.SearchRequest.basedn = "";
	msg->r.SearchRequest.scope = LDAP_SEARCH_SCOPE_BASE;
	msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER;
	msg->r.SearchRequest.timelimit = 0;
	msg->r.SearchRequest.sizelimit = 0;
	msg->r.SearchRequest.attributesonly = false;
	msg->r.SearchRequest.tree = ldb_parse_tree(msg, io->in.filter);
	msg->r.SearchRequest.num_attributes = str_list_length(io->in.attributes);
	msg->r.SearchRequest.attributes = io->in.attributes;

	req = ldap_request_send(conn, msg);
	if (req == NULL) {
		printf("Could not setup ldap search\n");
		return NT_STATUS_UNSUCCESSFUL;
	}

	ZERO_STRUCT(io->out);
	for (i = 0; i < 2; ++i) {
		status = ldap_result_n(req, i, &result);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}
		switch (result->type) {
		case LDAP_TAG_SearchResultEntry:
			if (i != 0) {
				return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
			}
			io->out.response = &result->r.SearchResultEntry;
			break;
		case LDAP_TAG_SearchResultDone:
			io->out.result = &result->r.SearchResultDone;
			if (io->out.result->resultcode != LDAP_SUCCESS) {
				return NT_STATUS_LDAP(io->out.result->resultcode);
			}

			return NT_STATUS_OK;
		default:
			return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
		}
	}

	return NT_STATUS_OK;
}
Ejemplo n.º 2
0
static NTSTATUS unbecomeDC_ldap_move_computer(struct libnet_UnbecomeDC_state *s)
{
	int ret;
	struct ldb_result *r;
	struct ldb_dn *basedn;
	struct ldb_dn *old_dn;
	struct ldb_dn *new_dn;
	static const char *_1_1_attrs[] = {
		"1.1",
		NULL
	};

	basedn = ldb_dn_new_fmt(s, s->ldap.ldb, "<WKGUID=aa312825768811d1aded00c04fd8d5cd,%s>",
				s->domain.dn_str);
	NT_STATUS_HAVE_NO_MEMORY(basedn);

	ret = ldb_search(s->ldap.ldb, s, &r, basedn, LDB_SCOPE_BASE,
			 _1_1_attrs, "(objectClass=*)");
	talloc_free(basedn);
	if (ret != LDB_SUCCESS) {
		return NT_STATUS_LDAP(ret);
	} else if (r->count != 1) {
		talloc_free(r);
		return NT_STATUS_INVALID_NETWORK_RESPONSE;
	}

	old_dn = ldb_dn_new(r, s->ldap.ldb, s->dest_dsa.computer_dn_str);
	NT_STATUS_HAVE_NO_MEMORY(old_dn);

	new_dn = r->msgs[0]->dn;

	if (!ldb_dn_add_child_fmt(new_dn, "CN=%s", s->dest_dsa.netbios_name)) {
		talloc_free(r);
		return NT_STATUS_NO_MEMORY;
	}

	if (ldb_dn_compare(old_dn, new_dn) == 0) {
		/* we don't need to rename if the old and new dn match */
		talloc_free(r);
		return NT_STATUS_OK;
	}

	ret = ldb_rename(s->ldap.ldb, old_dn, new_dn);
	if (ret != LDB_SUCCESS) {
		talloc_free(r);
		return NT_STATUS_LDAP(ret);
	}

	s->dest_dsa.computer_dn_str = ldb_dn_alloc_linearized(s, new_dn);
	NT_STATUS_HAVE_NO_MEMORY(s->dest_dsa.computer_dn_str);

	talloc_free(r);

	return NT_STATUS_OK;
}
Ejemplo n.º 3
0
static NTSTATUS unbecomeDC_ldap_computer_object(struct libnet_UnbecomeDC_state *s)
{
	int ret;
	struct ldb_result *r;
	struct ldb_dn *basedn;
	static const char *attrs[] = {
		"distinguishedName",
		"userAccountControl",
		NULL
	};

	basedn = ldb_dn_new(s, s->ldap.ldb, s->domain.dn_str);
	NT_STATUS_HAVE_NO_MEMORY(basedn);

	ret = ldb_search(s->ldap.ldb, s, &r, basedn, LDB_SCOPE_SUBTREE, attrs,
			 "(&(|(objectClass=user)(objectClass=computer))(sAMAccountName=%s$))",
			 s->dest_dsa.netbios_name);
	talloc_free(basedn);
	if (ret != LDB_SUCCESS) {
		return NT_STATUS_LDAP(ret);
	} else if (r->count != 1) {
		talloc_free(r);
		return NT_STATUS_INVALID_NETWORK_RESPONSE;
	}

	s->dest_dsa.computer_dn_str	= ldb_msg_find_attr_as_string(r->msgs[0], "distinguishedName", NULL);
	if (!s->dest_dsa.computer_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
	talloc_steal(s, s->dest_dsa.computer_dn_str);

	s->dest_dsa.user_account_control = ldb_msg_find_attr_as_uint(r->msgs[0], "userAccountControl", 0);

	talloc_free(r);
	return NT_STATUS_OK;
}
Ejemplo n.º 4
0
/*
  do a rough conversion between ads error codes and NT status codes
  we'll need to fill this in more
*/
NTSTATUS ads_ntstatus(ADS_STATUS status)
{
	switch (status.error_type) {
	case ENUM_ADS_ERROR_NT:
		return status.err.nt_status;	
	case ENUM_ADS_ERROR_SYSTEM:
		return map_nt_error_from_unix(status.err.rc);
#ifdef HAVE_LDAP
	case ENUM_ADS_ERROR_LDAP:
		if (status.err.rc == LDAP_SUCCESS) {
			return NT_STATUS_OK;
		}
		return NT_STATUS_LDAP(status.err.rc);
#endif
#ifdef HAVE_KRB5
	case ENUM_ADS_ERROR_KRB5:
		return krb5_to_nt_status(status.err.rc);
#endif
	default:
		break;
	}

	if (ADS_ERR_OK(status)) {
		return NT_STATUS_OK;
	}
	return NT_STATUS_UNSUCCESSFUL;
}
Ejemplo n.º 5
0
static NTSTATUS get_ldapi_ctx(TALLOC_CTX *mem_ctx, struct tldap_context **pld)
{
	struct tldap_context *ld;
	struct sockaddr_un addr;
	char *sockaddr;
	int fd;
	NTSTATUS status;
	int res;

	sockaddr = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
				   lp_private_dir());
	if (sockaddr == NULL) {
		DEBUG(10, ("talloc failed\n"));
		return NT_STATUS_NO_MEMORY;
	}

	ZERO_STRUCT(addr);
	addr.sun_family = AF_UNIX;
	strncpy(addr.sun_path, sockaddr, sizeof(addr.sun_path));
	TALLOC_FREE(sockaddr);

	status = open_socket_out((struct sockaddr_storage *)(void *)&addr,
				 0, 0, &fd);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("Could not connect to %s: %s\n", addr.sun_path,
			   nt_errstr(status)));
		return status;
	}
	set_blocking(fd, false);

	ld = tldap_context_create(mem_ctx, fd);
	if (ld == NULL) {
		close(fd);
		return NT_STATUS_NO_MEMORY;
	}
	res = tldap_fetch_rootdse(ld);
	if (res != TLDAP_SUCCESS) {
		DEBUG(10, ("tldap_fetch_rootdse failed: %s\n",
			   tldap_errstr(talloc_tos(), ld, res)));
		TALLOC_FREE(ld);
		return NT_STATUS_LDAP(res);
	}
	*pld = ld;
	return NT_STATUS_OK;;
}
Ejemplo n.º 6
0
static NTSTATUS unbecomeDC_ldap_modify_computer(struct libnet_UnbecomeDC_state *s)
{
	int ret;
	struct ldb_message *msg;
	uint32_t user_account_control = UF_WORKSTATION_TRUST_ACCOUNT;
	unsigned int i;

	/* as the value is already as we want it to be, we're done */
	if (s->dest_dsa.user_account_control == user_account_control) {
		return NT_STATUS_OK;
	}

	/* make a 'modify' msg, and only for serverReference */
	msg = ldb_msg_new(s);
	NT_STATUS_HAVE_NO_MEMORY(msg);
	msg->dn = ldb_dn_new(msg, s->ldap.ldb, s->dest_dsa.computer_dn_str);
	NT_STATUS_HAVE_NO_MEMORY(msg->dn);

	ret = samdb_msg_add_uint(s->ldap.ldb, msg, msg, "userAccountControl",
				 user_account_control);
	if (ret != LDB_SUCCESS) {
		talloc_free(msg);
		return NT_STATUS_NO_MEMORY;
	}

	/* mark all the message elements (should be just one)
	   as LDB_FLAG_MOD_REPLACE */
	for (i=0;i<msg->num_elements;i++) {
		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
	}

	ret = ldb_modify(s->ldap.ldb, msg);
	talloc_free(msg);
	if (ret != LDB_SUCCESS) {
		return NT_STATUS_LDAP(ret);
	}

	s->dest_dsa.user_account_control = user_account_control;

	return NT_STATUS_OK;
}
Ejemplo n.º 7
0
static NTSTATUS unbecomeDC_ldap_rootdse(struct libnet_UnbecomeDC_state *s)
{
	int ret;
	struct ldb_result *r;
	struct ldb_dn *basedn;
	static const char *attrs[] = {
		"defaultNamingContext",
		"configurationNamingContext",
		NULL
	};

	basedn = ldb_dn_new(s, s->ldap.ldb, NULL);
	NT_STATUS_HAVE_NO_MEMORY(basedn);

	ret = ldb_search(s->ldap.ldb, s, &r, basedn, LDB_SCOPE_BASE, attrs,
			 "(objectClass=*)");
	talloc_free(basedn);
	if (ret != LDB_SUCCESS) {
		return NT_STATUS_LDAP(ret);
	} else if (r->count != 1) {
		talloc_free(r);
		return NT_STATUS_INVALID_NETWORK_RESPONSE;
	}

	s->domain.dn_str	= ldb_msg_find_attr_as_string(r->msgs[0], "defaultNamingContext", NULL);
	if (!s->domain.dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
	talloc_steal(s, s->domain.dn_str);

	s->forest.config_dn_str	= ldb_msg_find_attr_as_string(r->msgs[0], "configurationNamingContext", NULL);
	if (!s->forest.config_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
	talloc_steal(s, s->forest.config_dn_str);

	s->dest_dsa.server_dn_str = talloc_asprintf(s, "CN=%s,CN=Servers,CN=%s,CN=Sites,%s",
						    s->dest_dsa.netbios_name,
						    s->dest_dsa.site_name,
				                    s->forest.config_dn_str);
	NT_STATUS_HAVE_NO_MEMORY(s->dest_dsa.server_dn_str);

	talloc_free(r);
	return NT_STATUS_OK;
}
Ejemplo n.º 8
0
static NTSTATUS mymachinepw(uint8_t pwd[16])
{
	TALLOC_CTX *frame = talloc_stackframe();
	struct tldap_context *ld = NULL;
	struct tldap_message *rootdse, **msg;
	const char *attrs[1] = { "unicodePwd" };
	char *default_nc, *myname;
	int rc, num_msg;
	DATA_BLOB pwdblob;
	NTSTATUS status;

	status = get_ldapi_ctx(talloc_tos(), &ld);
	if (!NT_STATUS_IS_OK(status)) {
		goto fail;
	}
	rootdse = tldap_rootdse(ld);
	if (rootdse == NULL) {
		DEBUG(10, ("Could not get rootdse\n"));
		status = NT_STATUS_INTERNAL_ERROR;
		goto fail;
	}
	default_nc = tldap_talloc_single_attribute(
		rootdse, "defaultNamingContext", talloc_tos());
	if (default_nc == NULL) {
		DEBUG(10, ("Could not get defaultNamingContext\n"));
		status = NT_STATUS_NO_MEMORY;
		goto fail;
	}
	DEBUG(10, ("default_nc = %s\n", default_nc));

	myname = talloc_asprintf_strupper_m(talloc_tos(), "%s$",
					    global_myname());
	if (myname == NULL) {
		DEBUG(10, ("talloc failed\n"));
		status = NT_STATUS_NO_MEMORY;
		goto fail;
	}

	rc = tldap_search_fmt(
		ld, default_nc, TLDAP_SCOPE_SUB, attrs, ARRAY_SIZE(attrs), 0,
		talloc_tos(), &msg,
		"(&(sAMAccountName=%s)(objectClass=computer))", myname);
	if (rc != TLDAP_SUCCESS) {
		DEBUG(10, ("Could not retrieve our account: %s\n",
			   tldap_errstr(talloc_tos(), ld, rc)));
		status = NT_STATUS_LDAP(rc);
		goto fail;
	}
	num_msg = talloc_array_length(msg);
	if (num_msg != 1) {
		DEBUG(10, ("Got %d accounts, expected one\n", num_msg));
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto fail;
	}
	if (!tldap_get_single_valueblob(msg[0], "unicodePwd", &pwdblob)) {
		char *dn = NULL;
		tldap_entry_dn(msg[0], &dn);
		DEBUG(10, ("No unicodePwd attribute in %s\n",
			   dn ? dn : "<unknown DN>"));
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto fail;
	}
	if (pwdblob.length != 16) {
		DEBUG(10, ("Password hash hash has length %d, expected 16\n",
			   (int)pwdblob.length));
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto fail;
	}
	memcpy(pwd, pwdblob.data, 16);

fail:
	TALLOC_FREE(frame);
	return status;
}