diff options
| author | Volker Lendecke <vl@samba.org> | 2009-06-13 11:59:39 +0200 | 
|---|---|---|
| committer | Volker Lendecke <vl@samba.org> | 2009-06-19 14:28:22 +0200 | 
| commit | b9c99a29286c748bbd706fd8757be6ef3fa9abc1 (patch) | |
| tree | 505fcc81dba4db2affa85cbd620f508114807a6a /source3/lib | |
| parent | 663e841ecdd4baddcdc4905a72c78c2868a8c408 (diff) | |
| download | samba-b9c99a29286c748bbd706fd8757be6ef3fa9abc1.tar.gz samba-b9c99a29286c748bbd706fd8757be6ef3fa9abc1.tar.bz2 samba-b9c99a29286c748bbd706fd8757be6ef3fa9abc1.zip  | |
Add tldap_fetch_rootdse
Diffstat (limited to 'source3/lib')
| -rw-r--r-- | source3/lib/tldap_util.c | 131 | 
1 files changed, 131 insertions, 0 deletions
diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c index 7c579162a5..042665f15f 100644 --- a/source3/lib/tldap_util.c +++ b/source3/lib/tldap_util.c @@ -378,3 +378,134 @@ bool tldap_pull_uint32(struct tldap_message *msg, const char *attr,  	*presult = (uint32_t)result;  	return true;  } + +struct tldap_fetch_rootdse_state { +	struct tldap_context *ld; +	struct tldap_message *rootdse; +}; + +static void tldap_fetch_rootdse_done(struct tevent_req *subreq); + +struct tevent_req *tldap_fetch_rootdse_send(TALLOC_CTX *mem_ctx, +					    struct tevent_context *ev, +					    struct tldap_context *ld) +{ +	struct tevent_req *req, *subreq; +	struct tldap_fetch_rootdse_state *state; +	static const char *attrs[2] = { "*", "+" }; + +	req = tevent_req_create(mem_ctx, &state, +				struct tldap_fetch_rootdse_state); +	if (req == NULL) { +		return NULL; +	} +	state->ld = ld; +	state->rootdse = NULL; + +	subreq = tldap_search_send( +		mem_ctx, ev, ld, "", TLDAP_SCOPE_BASE, "(objectclass=*)", +		attrs, ARRAY_SIZE(attrs), 0, NULL, NULL, 0, 0, 0); +	if (tevent_req_nomem(subreq, req)) { +		return tevent_req_post(req, ev); +	} +	tevent_req_set_callback(subreq, tldap_fetch_rootdse_done, req); +	return req; +} + +static void tldap_fetch_rootdse_done(struct tevent_req *subreq) +{ +	struct tevent_req *req = tevent_req_callback_data( +		subreq, struct tevent_req); +	struct tldap_fetch_rootdse_state *state = tevent_req_data( +		req, struct tldap_fetch_rootdse_state); +	struct tldap_message *msg; +	int rc; + +	rc = tldap_search_recv(subreq, state, &msg); +	if (rc != TLDAP_SUCCESS) { +		TALLOC_FREE(subreq); +		tevent_req_error(req, rc); +		return; +	} + +	switch (tldap_msg_type(msg)) { +	case TLDAP_RES_SEARCH_ENTRY: +		if (state->rootdse != NULL) { +			goto protocol_error; +		} +		state->rootdse = msg; +		break; +	case TLDAP_RES_SEARCH_RESULT: +		TALLOC_FREE(subreq); +		if (state->rootdse == NULL) { +			goto protocol_error; +		} +		tevent_req_done(req); +		break; +	default: +		goto protocol_error; +	} +	tevent_req_done(req); +	return; + +protocol_error: +	tevent_req_error(req, TLDAP_PROTOCOL_ERROR); +	return; +} + +int tldap_fetch_rootdse_recv(struct tevent_req *req) +{ +	struct tldap_fetch_rootdse_state *state = tevent_req_data( +		req, struct tldap_fetch_rootdse_state); +	int err; +	char *dn; + +	if (tevent_req_is_ldap_error(req, &err)) { +		return err; +	} +	/* Trigger parsing the dn, just to make sure it's ok */ +	if (!tldap_entry_dn(state->rootdse, &dn)) { +		return TLDAP_DECODING_ERROR; +	} +	if (!tldap_context_setattr(state->ld, "tldap:rootdse", +				   &state->rootdse)) { +		return TLDAP_NO_MEMORY; +	} +	return 0; +} + +int tldap_fetch_rootdse(struct tldap_context *ld) +{ +	TALLOC_CTX *frame = talloc_stackframe(); +	struct tevent_context *ev; +	struct tevent_req *req; +	int result; + +	ev = event_context_init(frame); +	if (ev == NULL) { +		result = TLDAP_NO_MEMORY; +		goto fail; +	} + +	req = tldap_fetch_rootdse_send(frame, ev, ld); +	if (req == NULL) { +		result = TLDAP_NO_MEMORY; +		goto fail; +	} + +	if (!tevent_req_poll(req, ev)) { +		result = TLDAP_OPERATIONS_ERROR; +		goto fail; +	} + +	result = tldap_fetch_rootdse_recv(req); + fail: +	TALLOC_FREE(frame); +	return result; +} + +struct tldap_message *tldap_rootdse(struct tldap_context *ld) +{ +	return talloc_get_type(tldap_context_getattr(ld, "tldap:rootdse"), +			       struct tldap_message); +}  | 
