xref: /freebsd/usr.sbin/nscd/query.c (revision 12326285065ad11d22b4b72544cce3889bd1938e)
106a99fe3SHajimu UMEMOTO /*-
206a99fe3SHajimu UMEMOTO  * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
306a99fe3SHajimu UMEMOTO  * All rights reserved.
406a99fe3SHajimu UMEMOTO  *
506a99fe3SHajimu UMEMOTO  * Redistribution and use in source and binary forms, with or without
606a99fe3SHajimu UMEMOTO  * modification, are permitted provided that the following conditions
706a99fe3SHajimu UMEMOTO  * are met:
806a99fe3SHajimu UMEMOTO  * 1. Redistributions of source code must retain the above copyright
906a99fe3SHajimu UMEMOTO  *    notice, this list of conditions and the following disclaimer.
1006a99fe3SHajimu UMEMOTO  * 2. Redistributions in binary form must reproduce the above copyright
1106a99fe3SHajimu UMEMOTO  *    notice, this list of conditions and the following disclaimer in the
1206a99fe3SHajimu UMEMOTO  *    documentation and/or other materials provided with the distribution.
1306a99fe3SHajimu UMEMOTO  *
1406a99fe3SHajimu UMEMOTO  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1506a99fe3SHajimu UMEMOTO  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1606a99fe3SHajimu UMEMOTO  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1706a99fe3SHajimu UMEMOTO  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1806a99fe3SHajimu UMEMOTO  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1906a99fe3SHajimu UMEMOTO  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2006a99fe3SHajimu UMEMOTO  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2106a99fe3SHajimu UMEMOTO  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2206a99fe3SHajimu UMEMOTO  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2306a99fe3SHajimu UMEMOTO  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2406a99fe3SHajimu UMEMOTO  * SUCH DAMAGE.
2506a99fe3SHajimu UMEMOTO  *
2606a99fe3SHajimu UMEMOTO  */
2706a99fe3SHajimu UMEMOTO 
2806a99fe3SHajimu UMEMOTO #include <sys/cdefs.h>
2906a99fe3SHajimu UMEMOTO __FBSDID("$FreeBSD$");
3006a99fe3SHajimu UMEMOTO 
3106a99fe3SHajimu UMEMOTO #include <sys/types.h>
3228f805ceSDag-Erling Smørgrav #include <sys/event.h>
3306a99fe3SHajimu UMEMOTO #include <sys/socket.h>
3406a99fe3SHajimu UMEMOTO #include <sys/time.h>
3528f805ceSDag-Erling Smørgrav 
3606a99fe3SHajimu UMEMOTO #include <assert.h>
3706a99fe3SHajimu UMEMOTO #include <errno.h>
3806a99fe3SHajimu UMEMOTO #include <nsswitch.h>
3906a99fe3SHajimu UMEMOTO #include <stdio.h>
4006a99fe3SHajimu UMEMOTO #include <stdlib.h>
4106a99fe3SHajimu UMEMOTO #include <string.h>
4228f805ceSDag-Erling Smørgrav #include <unistd.h>
4328f805ceSDag-Erling Smørgrav 
4406a99fe3SHajimu UMEMOTO #include "config.h"
4506a99fe3SHajimu UMEMOTO #include "debug.h"
4606a99fe3SHajimu UMEMOTO #include "query.h"
4706a99fe3SHajimu UMEMOTO #include "log.h"
4806a99fe3SHajimu UMEMOTO #include "mp_ws_query.h"
4906a99fe3SHajimu UMEMOTO #include "mp_rs_query.h"
5006a99fe3SHajimu UMEMOTO #include "singletons.h"
5106a99fe3SHajimu UMEMOTO 
5206a99fe3SHajimu UMEMOTO static const char negative_data[1] = { 0 };
5306a99fe3SHajimu UMEMOTO 
5406a99fe3SHajimu UMEMOTO extern	void get_time_func(struct timeval *);
5506a99fe3SHajimu UMEMOTO 
5606a99fe3SHajimu UMEMOTO static 	void clear_config_entry(struct configuration_entry *);
5706a99fe3SHajimu UMEMOTO static 	void clear_config_entry_part(struct configuration_entry *,
5806a99fe3SHajimu UMEMOTO 	const char *, size_t);
5906a99fe3SHajimu UMEMOTO 
6006a99fe3SHajimu UMEMOTO static	int on_query_startup(struct query_state *);
6106a99fe3SHajimu UMEMOTO static	void on_query_destroy(struct query_state *);
6206a99fe3SHajimu UMEMOTO 
6306a99fe3SHajimu UMEMOTO static	int on_read_request_read1(struct query_state *);
6406a99fe3SHajimu UMEMOTO static	int on_read_request_read2(struct query_state *);
6506a99fe3SHajimu UMEMOTO static	int on_read_request_process(struct query_state *);
6606a99fe3SHajimu UMEMOTO static	int on_read_response_write1(struct query_state *);
6706a99fe3SHajimu UMEMOTO static	int on_read_response_write2(struct query_state *);
6806a99fe3SHajimu UMEMOTO 
6906a99fe3SHajimu UMEMOTO static	int on_rw_mapper(struct query_state *);
7006a99fe3SHajimu UMEMOTO 
7106a99fe3SHajimu UMEMOTO static	int on_transform_request_read1(struct query_state *);
7206a99fe3SHajimu UMEMOTO static	int on_transform_request_read2(struct query_state *);
7306a99fe3SHajimu UMEMOTO static	int on_transform_request_process(struct query_state *);
7406a99fe3SHajimu UMEMOTO static	int on_transform_response_write1(struct query_state *);
7506a99fe3SHajimu UMEMOTO 
7606a99fe3SHajimu UMEMOTO static	int on_write_request_read1(struct query_state *);
7706a99fe3SHajimu UMEMOTO static	int on_write_request_read2(struct query_state *);
7806a99fe3SHajimu UMEMOTO static	int on_negative_write_request_process(struct query_state *);
7906a99fe3SHajimu UMEMOTO static	int on_write_request_process(struct query_state *);
8006a99fe3SHajimu UMEMOTO static	int on_write_response_write1(struct query_state *);
8106a99fe3SHajimu UMEMOTO 
8206a99fe3SHajimu UMEMOTO /*
8306a99fe3SHajimu UMEMOTO  * Clears the specified configuration entry (clears the cache for positive and
8406a99fe3SHajimu UMEMOTO  * and negative entries) and also for all multipart entries.
8506a99fe3SHajimu UMEMOTO  */
8606a99fe3SHajimu UMEMOTO static void
8706a99fe3SHajimu UMEMOTO clear_config_entry(struct configuration_entry *config_entry)
8806a99fe3SHajimu UMEMOTO {
8906a99fe3SHajimu UMEMOTO 	size_t i;
9006a99fe3SHajimu UMEMOTO 
9106a99fe3SHajimu UMEMOTO 	TRACE_IN(clear_config_entry);
9206a99fe3SHajimu UMEMOTO 	configuration_lock_entry(config_entry, CELT_POSITIVE);
9306a99fe3SHajimu UMEMOTO 	if (config_entry->positive_cache_entry != NULL)
9406a99fe3SHajimu UMEMOTO 		transform_cache_entry(
9506a99fe3SHajimu UMEMOTO 			config_entry->positive_cache_entry,
9606a99fe3SHajimu UMEMOTO 			CTT_CLEAR);
9706a99fe3SHajimu UMEMOTO 	configuration_unlock_entry(config_entry, CELT_POSITIVE);
9806a99fe3SHajimu UMEMOTO 
9906a99fe3SHajimu UMEMOTO 	configuration_lock_entry(config_entry, CELT_NEGATIVE);
10006a99fe3SHajimu UMEMOTO 	if (config_entry->negative_cache_entry != NULL)
10106a99fe3SHajimu UMEMOTO 		transform_cache_entry(
10206a99fe3SHajimu UMEMOTO 			config_entry->negative_cache_entry,
10306a99fe3SHajimu UMEMOTO 			CTT_CLEAR);
10406a99fe3SHajimu UMEMOTO 	configuration_unlock_entry(config_entry, CELT_NEGATIVE);
10506a99fe3SHajimu UMEMOTO 
10606a99fe3SHajimu UMEMOTO 	configuration_lock_entry(config_entry, CELT_MULTIPART);
10706a99fe3SHajimu UMEMOTO 	for (i = 0; i < config_entry->mp_cache_entries_size; ++i)
10806a99fe3SHajimu UMEMOTO 		transform_cache_entry(
10906a99fe3SHajimu UMEMOTO 			config_entry->mp_cache_entries[i],
11006a99fe3SHajimu UMEMOTO 			CTT_CLEAR);
11106a99fe3SHajimu UMEMOTO 	configuration_unlock_entry(config_entry, CELT_MULTIPART);
11206a99fe3SHajimu UMEMOTO 
11306a99fe3SHajimu UMEMOTO 	TRACE_OUT(clear_config_entry);
11406a99fe3SHajimu UMEMOTO }
11506a99fe3SHajimu UMEMOTO 
11606a99fe3SHajimu UMEMOTO /*
11706a99fe3SHajimu UMEMOTO  * Clears the specified configuration entry by deleting only the elements,
11806a99fe3SHajimu UMEMOTO  * that are owned by the user with specified eid_str.
11906a99fe3SHajimu UMEMOTO  */
12006a99fe3SHajimu UMEMOTO static void
12106a99fe3SHajimu UMEMOTO clear_config_entry_part(struct configuration_entry *config_entry,
12206a99fe3SHajimu UMEMOTO 	const char *eid_str, size_t eid_str_length)
12306a99fe3SHajimu UMEMOTO {
12406a99fe3SHajimu UMEMOTO 	cache_entry *start, *finish, *mp_entry;
12506a99fe3SHajimu UMEMOTO 	TRACE_IN(clear_config_entry_part);
12606a99fe3SHajimu UMEMOTO 	configuration_lock_entry(config_entry, CELT_POSITIVE);
12706a99fe3SHajimu UMEMOTO 	if (config_entry->positive_cache_entry != NULL)
12806a99fe3SHajimu UMEMOTO 		transform_cache_entry_part(
12906a99fe3SHajimu UMEMOTO 			config_entry->positive_cache_entry,
13006a99fe3SHajimu UMEMOTO 			CTT_CLEAR, eid_str, eid_str_length, KPPT_LEFT);
13106a99fe3SHajimu UMEMOTO 	configuration_unlock_entry(config_entry, CELT_POSITIVE);
13206a99fe3SHajimu UMEMOTO 
13306a99fe3SHajimu UMEMOTO 	configuration_lock_entry(config_entry, CELT_NEGATIVE);
13406a99fe3SHajimu UMEMOTO 	if (config_entry->negative_cache_entry != NULL)
13506a99fe3SHajimu UMEMOTO 		transform_cache_entry_part(
13606a99fe3SHajimu UMEMOTO 			config_entry->negative_cache_entry,
13706a99fe3SHajimu UMEMOTO 			CTT_CLEAR, eid_str, eid_str_length, KPPT_LEFT);
13806a99fe3SHajimu UMEMOTO 	configuration_unlock_entry(config_entry, CELT_NEGATIVE);
13906a99fe3SHajimu UMEMOTO 
14006a99fe3SHajimu UMEMOTO 	configuration_lock_entry(config_entry, CELT_MULTIPART);
14106a99fe3SHajimu UMEMOTO 	if (configuration_entry_find_mp_cache_entries(config_entry,
14206a99fe3SHajimu UMEMOTO 		eid_str, &start, &finish) == 0) {
14306a99fe3SHajimu UMEMOTO 		for (mp_entry = start; mp_entry != finish; ++mp_entry)
14406a99fe3SHajimu UMEMOTO 			transform_cache_entry(*mp_entry, CTT_CLEAR);
14506a99fe3SHajimu UMEMOTO 	}
14606a99fe3SHajimu UMEMOTO 	configuration_unlock_entry(config_entry, CELT_MULTIPART);
14706a99fe3SHajimu UMEMOTO 
14806a99fe3SHajimu UMEMOTO 	TRACE_OUT(clear_config_entry_part);
14906a99fe3SHajimu UMEMOTO }
15006a99fe3SHajimu UMEMOTO 
15106a99fe3SHajimu UMEMOTO /*
15206a99fe3SHajimu UMEMOTO  * This function is assigned to the query_state structue on its creation.
15306a99fe3SHajimu UMEMOTO  * It's main purpose is to receive credentials from the client.
15406a99fe3SHajimu UMEMOTO  */
15506a99fe3SHajimu UMEMOTO static int
15606a99fe3SHajimu UMEMOTO on_query_startup(struct query_state *qstate)
15706a99fe3SHajimu UMEMOTO {
15806a99fe3SHajimu UMEMOTO 	struct msghdr	cred_hdr;
15906a99fe3SHajimu UMEMOTO 	struct iovec	iov;
160b947683cSHajimu UMEMOTO 	struct cmsgcred *cred;
16106a99fe3SHajimu UMEMOTO 	int elem_type;
16206a99fe3SHajimu UMEMOTO 
16306a99fe3SHajimu UMEMOTO 	struct {
16406a99fe3SHajimu UMEMOTO 		struct cmsghdr	hdr;
165b947683cSHajimu UMEMOTO 		char cred[CMSG_SPACE(sizeof(struct cmsgcred))];
16606a99fe3SHajimu UMEMOTO 	} cmsg;
16706a99fe3SHajimu UMEMOTO 
16806a99fe3SHajimu UMEMOTO 	TRACE_IN(on_query_startup);
16906a99fe3SHajimu UMEMOTO 	assert(qstate != NULL);
17006a99fe3SHajimu UMEMOTO 
17106a99fe3SHajimu UMEMOTO 	memset(&cred_hdr, 0, sizeof(struct msghdr));
17206a99fe3SHajimu UMEMOTO 	cred_hdr.msg_iov = &iov;
17306a99fe3SHajimu UMEMOTO 	cred_hdr.msg_iovlen = 1;
174b947683cSHajimu UMEMOTO 	cred_hdr.msg_control = (caddr_t)&cmsg;
175b947683cSHajimu UMEMOTO 	cred_hdr.msg_controllen = CMSG_LEN(sizeof(struct cmsgcred));
17606a99fe3SHajimu UMEMOTO 
17706a99fe3SHajimu UMEMOTO 	memset(&iov, 0, sizeof(struct iovec));
17806a99fe3SHajimu UMEMOTO 	iov.iov_base = &elem_type;
17906a99fe3SHajimu UMEMOTO 	iov.iov_len = sizeof(int);
18006a99fe3SHajimu UMEMOTO 
18106a99fe3SHajimu UMEMOTO 	if (recvmsg(qstate->sockfd, &cred_hdr, 0) == -1) {
18206a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_query_startup);
18306a99fe3SHajimu UMEMOTO 		return (-1);
18406a99fe3SHajimu UMEMOTO 	}
18506a99fe3SHajimu UMEMOTO 
186b947683cSHajimu UMEMOTO 	if (cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(struct cmsgcred))
18706a99fe3SHajimu UMEMOTO 		|| cmsg.hdr.cmsg_level != SOL_SOCKET
18806a99fe3SHajimu UMEMOTO 		|| cmsg.hdr.cmsg_type != SCM_CREDS) {
18906a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_query_startup);
19006a99fe3SHajimu UMEMOTO 		return (-1);
19106a99fe3SHajimu UMEMOTO 	}
19206a99fe3SHajimu UMEMOTO 
193b947683cSHajimu UMEMOTO 	cred = (struct cmsgcred *)CMSG_DATA(&cmsg);
194b947683cSHajimu UMEMOTO 	qstate->uid = cred->cmcred_uid;
195b947683cSHajimu UMEMOTO 	qstate->gid = cred->cmcred_gid;
19606a99fe3SHajimu UMEMOTO 
197db1bdf2bSMichael Bushkov #if defined(NS_NSCD_EID_CHECKING) || defined(NS_STRICT_NSCD_EID_CHECKING)
19806a99fe3SHajimu UMEMOTO /*
19906a99fe3SHajimu UMEMOTO  * This check is probably a bit redundant - per-user cache is always separated
20006a99fe3SHajimu UMEMOTO  * by the euid/egid pair
20106a99fe3SHajimu UMEMOTO  */
20206a99fe3SHajimu UMEMOTO 	if (check_query_eids(qstate) != 0) {
203db1bdf2bSMichael Bushkov #ifdef NS_STRICT_NSCD_EID_CHECKING
20406a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_query_startup);
20506a99fe3SHajimu UMEMOTO 		return (-1);
20606a99fe3SHajimu UMEMOTO #else
20706a99fe3SHajimu UMEMOTO 		if ((elem_type != CET_READ_REQUEST) &&
20806a99fe3SHajimu UMEMOTO 			(elem_type != CET_MP_READ_SESSION_REQUEST) &&
20906a99fe3SHajimu UMEMOTO 			(elem_type != CET_WRITE_REQUEST) &&
21006a99fe3SHajimu UMEMOTO 			(elem_type != CET_MP_WRITE_SESSION_REQUEST)) {
21106a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_query_startup);
21206a99fe3SHajimu UMEMOTO 			return (-1);
21306a99fe3SHajimu UMEMOTO 		}
21406a99fe3SHajimu UMEMOTO #endif
21506a99fe3SHajimu UMEMOTO 	}
21606a99fe3SHajimu UMEMOTO #endif
21706a99fe3SHajimu UMEMOTO 
21806a99fe3SHajimu UMEMOTO 	switch (elem_type) {
21906a99fe3SHajimu UMEMOTO 	case CET_WRITE_REQUEST:
22006a99fe3SHajimu UMEMOTO 		qstate->process_func = on_write_request_read1;
22106a99fe3SHajimu UMEMOTO 		break;
22206a99fe3SHajimu UMEMOTO 	case CET_READ_REQUEST:
22306a99fe3SHajimu UMEMOTO 		qstate->process_func = on_read_request_read1;
22406a99fe3SHajimu UMEMOTO 		break;
22506a99fe3SHajimu UMEMOTO 	case CET_TRANSFORM_REQUEST:
22606a99fe3SHajimu UMEMOTO 		qstate->process_func = on_transform_request_read1;
22706a99fe3SHajimu UMEMOTO 		break;
22806a99fe3SHajimu UMEMOTO 	case CET_MP_WRITE_SESSION_REQUEST:
22906a99fe3SHajimu UMEMOTO 		qstate->process_func = on_mp_write_session_request_read1;
23006a99fe3SHajimu UMEMOTO 		break;
23106a99fe3SHajimu UMEMOTO 	case CET_MP_READ_SESSION_REQUEST:
23206a99fe3SHajimu UMEMOTO 		qstate->process_func = on_mp_read_session_request_read1;
23306a99fe3SHajimu UMEMOTO 		break;
23406a99fe3SHajimu UMEMOTO 	default:
23506a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_query_startup);
23606a99fe3SHajimu UMEMOTO 		return (-1);
23706a99fe3SHajimu UMEMOTO 	}
23806a99fe3SHajimu UMEMOTO 
23906a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = 0;
24006a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_query_startup);
24106a99fe3SHajimu UMEMOTO 	return (0);
24206a99fe3SHajimu UMEMOTO }
24306a99fe3SHajimu UMEMOTO 
24406a99fe3SHajimu UMEMOTO /*
24506a99fe3SHajimu UMEMOTO  * on_rw_mapper is used to process multiple read/write requests during
24606a99fe3SHajimu UMEMOTO  * one connection session. It's never called in the beginning (on query_state
24706a99fe3SHajimu UMEMOTO  * creation) as it does not process the multipart requests and does not
24806a99fe3SHajimu UMEMOTO  * receive credentials
24906a99fe3SHajimu UMEMOTO  */
25006a99fe3SHajimu UMEMOTO static int
25106a99fe3SHajimu UMEMOTO on_rw_mapper(struct query_state *qstate)
25206a99fe3SHajimu UMEMOTO {
25306a99fe3SHajimu UMEMOTO 	ssize_t	result;
25406a99fe3SHajimu UMEMOTO 	int	elem_type;
25506a99fe3SHajimu UMEMOTO 
25606a99fe3SHajimu UMEMOTO 	TRACE_IN(on_rw_mapper);
25706a99fe3SHajimu UMEMOTO 	if (qstate->kevent_watermark == 0) {
25806a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = sizeof(int);
25906a99fe3SHajimu UMEMOTO 	} else {
26006a99fe3SHajimu UMEMOTO 		result = qstate->read_func(qstate, &elem_type, sizeof(int));
26106a99fe3SHajimu UMEMOTO 		if (result != sizeof(int)) {
26206a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_rw_mapper);
26306a99fe3SHajimu UMEMOTO 			return (-1);
26406a99fe3SHajimu UMEMOTO 		}
26506a99fe3SHajimu UMEMOTO 
26606a99fe3SHajimu UMEMOTO 		switch (elem_type) {
26706a99fe3SHajimu UMEMOTO 		case CET_WRITE_REQUEST:
26806a99fe3SHajimu UMEMOTO 			qstate->kevent_watermark = sizeof(size_t);
26906a99fe3SHajimu UMEMOTO 			qstate->process_func = on_write_request_read1;
27006a99fe3SHajimu UMEMOTO 		break;
27106a99fe3SHajimu UMEMOTO 		case CET_READ_REQUEST:
27206a99fe3SHajimu UMEMOTO 			qstate->kevent_watermark = sizeof(size_t);
27306a99fe3SHajimu UMEMOTO 			qstate->process_func = on_read_request_read1;
27406a99fe3SHajimu UMEMOTO 		break;
27506a99fe3SHajimu UMEMOTO 		default:
27606a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_rw_mapper);
27706a99fe3SHajimu UMEMOTO 			return (-1);
27806a99fe3SHajimu UMEMOTO 		break;
27906a99fe3SHajimu UMEMOTO 		}
28006a99fe3SHajimu UMEMOTO 	}
28106a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_rw_mapper);
28206a99fe3SHajimu UMEMOTO 	return (0);
28306a99fe3SHajimu UMEMOTO }
28406a99fe3SHajimu UMEMOTO 
28506a99fe3SHajimu UMEMOTO /*
28606a99fe3SHajimu UMEMOTO  * The default query_destroy function
28706a99fe3SHajimu UMEMOTO  */
28806a99fe3SHajimu UMEMOTO static void
28906a99fe3SHajimu UMEMOTO on_query_destroy(struct query_state *qstate)
29006a99fe3SHajimu UMEMOTO {
29106a99fe3SHajimu UMEMOTO 
29206a99fe3SHajimu UMEMOTO 	TRACE_IN(on_query_destroy);
29306a99fe3SHajimu UMEMOTO 	finalize_comm_element(&qstate->response);
29406a99fe3SHajimu UMEMOTO 	finalize_comm_element(&qstate->request);
29506a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_query_destroy);
29606a99fe3SHajimu UMEMOTO }
29706a99fe3SHajimu UMEMOTO 
29806a99fe3SHajimu UMEMOTO /*
29906a99fe3SHajimu UMEMOTO  * The functions below are used to process write requests.
30006a99fe3SHajimu UMEMOTO  * - on_write_request_read1 and on_write_request_read2 read the request itself
30106a99fe3SHajimu UMEMOTO  * - on_write_request_process processes it (if the client requests to
30206a99fe3SHajimu UMEMOTO  *    cache the negative result, the on_negative_write_request_process is used)
30306a99fe3SHajimu UMEMOTO  * - on_write_response_write1 sends the response
30406a99fe3SHajimu UMEMOTO  */
30506a99fe3SHajimu UMEMOTO static int
30606a99fe3SHajimu UMEMOTO on_write_request_read1(struct query_state *qstate)
30706a99fe3SHajimu UMEMOTO {
30806a99fe3SHajimu UMEMOTO 	struct cache_write_request	*write_request;
30906a99fe3SHajimu UMEMOTO 	ssize_t	result;
31006a99fe3SHajimu UMEMOTO 
31106a99fe3SHajimu UMEMOTO 	TRACE_IN(on_write_request_read1);
31206a99fe3SHajimu UMEMOTO 	if (qstate->kevent_watermark == 0)
31306a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = sizeof(size_t) * 3;
31406a99fe3SHajimu UMEMOTO 	else {
31506a99fe3SHajimu UMEMOTO 		init_comm_element(&qstate->request, CET_WRITE_REQUEST);
31606a99fe3SHajimu UMEMOTO 		write_request = get_cache_write_request(&qstate->request);
31706a99fe3SHajimu UMEMOTO 
31806a99fe3SHajimu UMEMOTO 		result = qstate->read_func(qstate, &write_request->entry_length,
31906a99fe3SHajimu UMEMOTO 	    		sizeof(size_t));
32006a99fe3SHajimu UMEMOTO 		result += qstate->read_func(qstate,
32106a99fe3SHajimu UMEMOTO 	    		&write_request->cache_key_size, sizeof(size_t));
32206a99fe3SHajimu UMEMOTO 		result += qstate->read_func(qstate,
32306a99fe3SHajimu UMEMOTO 	    		&write_request->data_size, sizeof(size_t));
32406a99fe3SHajimu UMEMOTO 
32506a99fe3SHajimu UMEMOTO 		if (result != sizeof(size_t) * 3) {
32606a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_write_request_read1);
32706a99fe3SHajimu UMEMOTO 			return (-1);
32806a99fe3SHajimu UMEMOTO 		}
32906a99fe3SHajimu UMEMOTO 
33006a99fe3SHajimu UMEMOTO 		if (BUFSIZE_INVALID(write_request->entry_length) ||
33106a99fe3SHajimu UMEMOTO 			BUFSIZE_INVALID(write_request->cache_key_size) ||
33206a99fe3SHajimu UMEMOTO 			(BUFSIZE_INVALID(write_request->data_size) &&
33306a99fe3SHajimu UMEMOTO 			(write_request->data_size != 0))) {
33406a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_write_request_read1);
33506a99fe3SHajimu UMEMOTO 			return (-1);
33606a99fe3SHajimu UMEMOTO 		}
33706a99fe3SHajimu UMEMOTO 
3388eeaaffaSDag-Erling Smørgrav 		write_request->entry = calloc(1,
33906a99fe3SHajimu UMEMOTO 			write_request->entry_length + 1);
34006a99fe3SHajimu UMEMOTO 		assert(write_request->entry != NULL);
34106a99fe3SHajimu UMEMOTO 
3428eeaaffaSDag-Erling Smørgrav 		write_request->cache_key = calloc(1,
34306a99fe3SHajimu UMEMOTO 			write_request->cache_key_size +
34406a99fe3SHajimu UMEMOTO 			qstate->eid_str_length);
34506a99fe3SHajimu UMEMOTO 		assert(write_request->cache_key != NULL);
34606a99fe3SHajimu UMEMOTO 		memcpy(write_request->cache_key, qstate->eid_str,
34706a99fe3SHajimu UMEMOTO 			qstate->eid_str_length);
34806a99fe3SHajimu UMEMOTO 
34906a99fe3SHajimu UMEMOTO 		if (write_request->data_size != 0) {
3508eeaaffaSDag-Erling Smørgrav 			write_request->data = calloc(1,
35106a99fe3SHajimu UMEMOTO 				write_request->data_size);
35206a99fe3SHajimu UMEMOTO 			assert(write_request->data != NULL);
35306a99fe3SHajimu UMEMOTO 		}
35406a99fe3SHajimu UMEMOTO 
35506a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = write_request->entry_length +
35606a99fe3SHajimu UMEMOTO 			write_request->cache_key_size +
35706a99fe3SHajimu UMEMOTO 			write_request->data_size;
35806a99fe3SHajimu UMEMOTO 		qstate->process_func = on_write_request_read2;
35906a99fe3SHajimu UMEMOTO 	}
36006a99fe3SHajimu UMEMOTO 
36106a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_write_request_read1);
36206a99fe3SHajimu UMEMOTO 	return (0);
36306a99fe3SHajimu UMEMOTO }
36406a99fe3SHajimu UMEMOTO 
36506a99fe3SHajimu UMEMOTO static int
36606a99fe3SHajimu UMEMOTO on_write_request_read2(struct query_state *qstate)
36706a99fe3SHajimu UMEMOTO {
36806a99fe3SHajimu UMEMOTO 	struct cache_write_request	*write_request;
36906a99fe3SHajimu UMEMOTO 	ssize_t	result;
37006a99fe3SHajimu UMEMOTO 
37106a99fe3SHajimu UMEMOTO 	TRACE_IN(on_write_request_read2);
37206a99fe3SHajimu UMEMOTO 	write_request = get_cache_write_request(&qstate->request);
37306a99fe3SHajimu UMEMOTO 
37406a99fe3SHajimu UMEMOTO 	result = qstate->read_func(qstate, write_request->entry,
37506a99fe3SHajimu UMEMOTO 		write_request->entry_length);
37606a99fe3SHajimu UMEMOTO 	result += qstate->read_func(qstate, write_request->cache_key +
37706a99fe3SHajimu UMEMOTO 		qstate->eid_str_length, write_request->cache_key_size);
37806a99fe3SHajimu UMEMOTO 	if (write_request->data_size != 0)
37906a99fe3SHajimu UMEMOTO 		result += qstate->read_func(qstate, write_request->data,
38006a99fe3SHajimu UMEMOTO 			write_request->data_size);
38106a99fe3SHajimu UMEMOTO 
38251d6ddb5SDag-Erling Smørgrav 	if (result != (ssize_t)qstate->kevent_watermark) {
38306a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_write_request_read2);
38406a99fe3SHajimu UMEMOTO 		return (-1);
38506a99fe3SHajimu UMEMOTO 	}
38606a99fe3SHajimu UMEMOTO 	write_request->cache_key_size += qstate->eid_str_length;
38706a99fe3SHajimu UMEMOTO 
38806a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = 0;
38906a99fe3SHajimu UMEMOTO 	if (write_request->data_size != 0)
39006a99fe3SHajimu UMEMOTO 		qstate->process_func = on_write_request_process;
39106a99fe3SHajimu UMEMOTO 	else
39206a99fe3SHajimu UMEMOTO 	    	qstate->process_func = on_negative_write_request_process;
39306a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_write_request_read2);
39406a99fe3SHajimu UMEMOTO 	return (0);
39506a99fe3SHajimu UMEMOTO }
39606a99fe3SHajimu UMEMOTO 
39706a99fe3SHajimu UMEMOTO static	int
39806a99fe3SHajimu UMEMOTO on_write_request_process(struct query_state *qstate)
39906a99fe3SHajimu UMEMOTO {
40006a99fe3SHajimu UMEMOTO 	struct cache_write_request	*write_request;
40106a99fe3SHajimu UMEMOTO 	struct cache_write_response	*write_response;
40206a99fe3SHajimu UMEMOTO 	cache_entry c_entry;
40306a99fe3SHajimu UMEMOTO 
40406a99fe3SHajimu UMEMOTO 	TRACE_IN(on_write_request_process);
40506a99fe3SHajimu UMEMOTO 	init_comm_element(&qstate->response, CET_WRITE_RESPONSE);
40606a99fe3SHajimu UMEMOTO 	write_response = get_cache_write_response(&qstate->response);
40706a99fe3SHajimu UMEMOTO 	write_request = get_cache_write_request(&qstate->request);
40806a99fe3SHajimu UMEMOTO 
40906a99fe3SHajimu UMEMOTO 	qstate->config_entry = configuration_find_entry(
41006a99fe3SHajimu UMEMOTO 		s_configuration, write_request->entry);
41106a99fe3SHajimu UMEMOTO 
41206a99fe3SHajimu UMEMOTO 	if (qstate->config_entry == NULL) {
41306a99fe3SHajimu UMEMOTO 		write_response->error_code = ENOENT;
41406a99fe3SHajimu UMEMOTO 
41506a99fe3SHajimu UMEMOTO 		LOG_ERR_2("write_request", "can't find configuration"
41606a99fe3SHajimu UMEMOTO 		    " entry '%s'. aborting request", write_request->entry);
41706a99fe3SHajimu UMEMOTO 		goto fin;
41806a99fe3SHajimu UMEMOTO 	}
41906a99fe3SHajimu UMEMOTO 
42006a99fe3SHajimu UMEMOTO 	if (qstate->config_entry->enabled == 0) {
42106a99fe3SHajimu UMEMOTO 		write_response->error_code = EACCES;
42206a99fe3SHajimu UMEMOTO 
42306a99fe3SHajimu UMEMOTO 		LOG_ERR_2("write_request",
42406a99fe3SHajimu UMEMOTO 			"configuration entry '%s' is disabled",
42506a99fe3SHajimu UMEMOTO 			write_request->entry);
42606a99fe3SHajimu UMEMOTO 		goto fin;
42706a99fe3SHajimu UMEMOTO 	}
42806a99fe3SHajimu UMEMOTO 
42906a99fe3SHajimu UMEMOTO 	if (qstate->config_entry->perform_actual_lookups != 0) {
43006a99fe3SHajimu UMEMOTO 		write_response->error_code = EOPNOTSUPP;
43106a99fe3SHajimu UMEMOTO 
43206a99fe3SHajimu UMEMOTO 		LOG_ERR_2("write_request",
43306a99fe3SHajimu UMEMOTO 			"entry '%s' performs lookups by itself: "
43406a99fe3SHajimu UMEMOTO 			"can't write to it", write_request->entry);
43506a99fe3SHajimu UMEMOTO 		goto fin;
43606a99fe3SHajimu UMEMOTO 	}
43706a99fe3SHajimu UMEMOTO 
43806a99fe3SHajimu UMEMOTO 	configuration_lock_rdlock(s_configuration);
43906a99fe3SHajimu UMEMOTO 	c_entry = find_cache_entry(s_cache,
44027f2bc9eSDag-Erling Smørgrav 		qstate->config_entry->positive_cache_params.cep.entry_name);
44106a99fe3SHajimu UMEMOTO 	configuration_unlock(s_configuration);
44206a99fe3SHajimu UMEMOTO 	if (c_entry != NULL) {
44306a99fe3SHajimu UMEMOTO 		configuration_lock_entry(qstate->config_entry, CELT_POSITIVE);
44406a99fe3SHajimu UMEMOTO 		qstate->config_entry->positive_cache_entry = c_entry;
44506a99fe3SHajimu UMEMOTO 		write_response->error_code = cache_write(c_entry,
44606a99fe3SHajimu UMEMOTO 			write_request->cache_key,
44706a99fe3SHajimu UMEMOTO 	    		write_request->cache_key_size,
44806a99fe3SHajimu UMEMOTO 	    		write_request->data,
44906a99fe3SHajimu UMEMOTO 			write_request->data_size);
45006a99fe3SHajimu UMEMOTO 		configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE);
45106a99fe3SHajimu UMEMOTO 
45206a99fe3SHajimu UMEMOTO 		if ((qstate->config_entry->common_query_timeout.tv_sec != 0) ||
45306a99fe3SHajimu UMEMOTO 		    (qstate->config_entry->common_query_timeout.tv_usec != 0))
45406a99fe3SHajimu UMEMOTO 			memcpy(&qstate->timeout,
45506a99fe3SHajimu UMEMOTO 				&qstate->config_entry->common_query_timeout,
45606a99fe3SHajimu UMEMOTO 				sizeof(struct timeval));
45706a99fe3SHajimu UMEMOTO 
45806a99fe3SHajimu UMEMOTO 	} else
45906a99fe3SHajimu UMEMOTO 		write_response->error_code = -1;
46006a99fe3SHajimu UMEMOTO 
46106a99fe3SHajimu UMEMOTO fin:
46206a99fe3SHajimu UMEMOTO 	qstate->kevent_filter = EVFILT_WRITE;
46306a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = sizeof(int);
46406a99fe3SHajimu UMEMOTO 	qstate->process_func = on_write_response_write1;
46506a99fe3SHajimu UMEMOTO 
46606a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_write_request_process);
46706a99fe3SHajimu UMEMOTO 	return (0);
46806a99fe3SHajimu UMEMOTO }
46906a99fe3SHajimu UMEMOTO 
47006a99fe3SHajimu UMEMOTO static int
47106a99fe3SHajimu UMEMOTO on_negative_write_request_process(struct query_state *qstate)
47206a99fe3SHajimu UMEMOTO {
47306a99fe3SHajimu UMEMOTO 	struct cache_write_request	*write_request;
47406a99fe3SHajimu UMEMOTO 	struct cache_write_response	*write_response;
47506a99fe3SHajimu UMEMOTO 	cache_entry c_entry;
47606a99fe3SHajimu UMEMOTO 
47706a99fe3SHajimu UMEMOTO 	TRACE_IN(on_negative_write_request_process);
47806a99fe3SHajimu UMEMOTO 	init_comm_element(&qstate->response, CET_WRITE_RESPONSE);
47906a99fe3SHajimu UMEMOTO 	write_response = get_cache_write_response(&qstate->response);
48006a99fe3SHajimu UMEMOTO 	write_request = get_cache_write_request(&qstate->request);
48106a99fe3SHajimu UMEMOTO 
48206a99fe3SHajimu UMEMOTO 	qstate->config_entry = configuration_find_entry	(
48306a99fe3SHajimu UMEMOTO 		s_configuration, write_request->entry);
48406a99fe3SHajimu UMEMOTO 
48506a99fe3SHajimu UMEMOTO 	if (qstate->config_entry == NULL) {
48606a99fe3SHajimu UMEMOTO 		write_response->error_code = ENOENT;
48706a99fe3SHajimu UMEMOTO 
48806a99fe3SHajimu UMEMOTO 		LOG_ERR_2("negative_write_request",
48906a99fe3SHajimu UMEMOTO 			"can't find configuration"
49006a99fe3SHajimu UMEMOTO 		   	" entry '%s'. aborting request", write_request->entry);
49106a99fe3SHajimu UMEMOTO 		goto fin;
49206a99fe3SHajimu UMEMOTO 	}
49306a99fe3SHajimu UMEMOTO 
49406a99fe3SHajimu UMEMOTO 	if (qstate->config_entry->enabled == 0) {
49506a99fe3SHajimu UMEMOTO 		write_response->error_code = EACCES;
49606a99fe3SHajimu UMEMOTO 
49706a99fe3SHajimu UMEMOTO 		LOG_ERR_2("negative_write_request",
49806a99fe3SHajimu UMEMOTO 			"configuration entry '%s' is disabled",
49906a99fe3SHajimu UMEMOTO 			write_request->entry);
50006a99fe3SHajimu UMEMOTO 		goto fin;
50106a99fe3SHajimu UMEMOTO 	}
50206a99fe3SHajimu UMEMOTO 
50306a99fe3SHajimu UMEMOTO 	if (qstate->config_entry->perform_actual_lookups != 0) {
50406a99fe3SHajimu UMEMOTO 		write_response->error_code = EOPNOTSUPP;
50506a99fe3SHajimu UMEMOTO 
50606a99fe3SHajimu UMEMOTO 		LOG_ERR_2("negative_write_request",
50706a99fe3SHajimu UMEMOTO 			"entry '%s' performs lookups by itself: "
50806a99fe3SHajimu UMEMOTO 			"can't write to it", write_request->entry);
50906a99fe3SHajimu UMEMOTO 		goto fin;
51006a99fe3SHajimu UMEMOTO 	} else {
511db1bdf2bSMichael Bushkov #ifdef NS_NSCD_EID_CHECKING
51206a99fe3SHajimu UMEMOTO 		if (check_query_eids(qstate) != 0) {
51306a99fe3SHajimu UMEMOTO 			write_response->error_code = EPERM;
51406a99fe3SHajimu UMEMOTO 			goto fin;
51506a99fe3SHajimu UMEMOTO 		}
51606a99fe3SHajimu UMEMOTO #endif
51706a99fe3SHajimu UMEMOTO 	}
51806a99fe3SHajimu UMEMOTO 
51906a99fe3SHajimu UMEMOTO 	configuration_lock_rdlock(s_configuration);
52006a99fe3SHajimu UMEMOTO 	c_entry = find_cache_entry(s_cache,
52127f2bc9eSDag-Erling Smørgrav 		qstate->config_entry->negative_cache_params.cep.entry_name);
52206a99fe3SHajimu UMEMOTO 	configuration_unlock(s_configuration);
52306a99fe3SHajimu UMEMOTO 	if (c_entry != NULL) {
52406a99fe3SHajimu UMEMOTO 		configuration_lock_entry(qstate->config_entry, CELT_NEGATIVE);
52506a99fe3SHajimu UMEMOTO 		qstate->config_entry->negative_cache_entry = c_entry;
52606a99fe3SHajimu UMEMOTO 		write_response->error_code = cache_write(c_entry,
52706a99fe3SHajimu UMEMOTO 			write_request->cache_key,
52806a99fe3SHajimu UMEMOTO 	    		write_request->cache_key_size,
52906a99fe3SHajimu UMEMOTO 	    		negative_data,
53006a99fe3SHajimu UMEMOTO 			sizeof(negative_data));
53106a99fe3SHajimu UMEMOTO 		configuration_unlock_entry(qstate->config_entry, CELT_NEGATIVE);
53206a99fe3SHajimu UMEMOTO 
53306a99fe3SHajimu UMEMOTO 		if ((qstate->config_entry->common_query_timeout.tv_sec != 0) ||
53406a99fe3SHajimu UMEMOTO 		    (qstate->config_entry->common_query_timeout.tv_usec != 0))
53506a99fe3SHajimu UMEMOTO 			memcpy(&qstate->timeout,
53606a99fe3SHajimu UMEMOTO 				&qstate->config_entry->common_query_timeout,
53706a99fe3SHajimu UMEMOTO 				sizeof(struct timeval));
53806a99fe3SHajimu UMEMOTO 	} else
53906a99fe3SHajimu UMEMOTO 		write_response->error_code = -1;
54006a99fe3SHajimu UMEMOTO 
54106a99fe3SHajimu UMEMOTO fin:
54206a99fe3SHajimu UMEMOTO 	qstate->kevent_filter = EVFILT_WRITE;
54306a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = sizeof(int);
54406a99fe3SHajimu UMEMOTO 	qstate->process_func = on_write_response_write1;
54506a99fe3SHajimu UMEMOTO 
54606a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_negative_write_request_process);
54706a99fe3SHajimu UMEMOTO 	return (0);
54806a99fe3SHajimu UMEMOTO }
54906a99fe3SHajimu UMEMOTO 
55006a99fe3SHajimu UMEMOTO static int
55106a99fe3SHajimu UMEMOTO on_write_response_write1(struct query_state *qstate)
55206a99fe3SHajimu UMEMOTO {
55306a99fe3SHajimu UMEMOTO 	struct cache_write_response	*write_response;
55406a99fe3SHajimu UMEMOTO 	ssize_t	result;
55506a99fe3SHajimu UMEMOTO 
55606a99fe3SHajimu UMEMOTO 	TRACE_IN(on_write_response_write1);
55706a99fe3SHajimu UMEMOTO 	write_response = get_cache_write_response(&qstate->response);
55806a99fe3SHajimu UMEMOTO 	result = qstate->write_func(qstate, &write_response->error_code,
55906a99fe3SHajimu UMEMOTO 		sizeof(int));
56006a99fe3SHajimu UMEMOTO 	if (result != sizeof(int)) {
56106a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_write_response_write1);
56206a99fe3SHajimu UMEMOTO 		return (-1);
56306a99fe3SHajimu UMEMOTO 	}
56406a99fe3SHajimu UMEMOTO 
56506a99fe3SHajimu UMEMOTO 	finalize_comm_element(&qstate->request);
56606a99fe3SHajimu UMEMOTO 	finalize_comm_element(&qstate->response);
56706a99fe3SHajimu UMEMOTO 
56806a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = sizeof(int);
56906a99fe3SHajimu UMEMOTO 	qstate->kevent_filter = EVFILT_READ;
57006a99fe3SHajimu UMEMOTO 	qstate->process_func = on_rw_mapper;
57106a99fe3SHajimu UMEMOTO 
57206a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_write_response_write1);
57306a99fe3SHajimu UMEMOTO 	return (0);
57406a99fe3SHajimu UMEMOTO }
57506a99fe3SHajimu UMEMOTO 
57606a99fe3SHajimu UMEMOTO /*
57706a99fe3SHajimu UMEMOTO  * The functions below are used to process read requests.
57806a99fe3SHajimu UMEMOTO  * - on_read_request_read1 and on_read_request_read2 read the request itself
57906a99fe3SHajimu UMEMOTO  * - on_read_request_process processes it
58006a99fe3SHajimu UMEMOTO  * - on_read_response_write1 and on_read_response_write2 send the response
58106a99fe3SHajimu UMEMOTO  */
58206a99fe3SHajimu UMEMOTO static int
58306a99fe3SHajimu UMEMOTO on_read_request_read1(struct query_state *qstate)
58406a99fe3SHajimu UMEMOTO {
58506a99fe3SHajimu UMEMOTO 	struct cache_read_request *read_request;
58606a99fe3SHajimu UMEMOTO 	ssize_t	result;
58706a99fe3SHajimu UMEMOTO 
58806a99fe3SHajimu UMEMOTO 	TRACE_IN(on_read_request_read1);
58906a99fe3SHajimu UMEMOTO 	if (qstate->kevent_watermark == 0)
59006a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = sizeof(size_t) * 2;
59106a99fe3SHajimu UMEMOTO 	else {
59206a99fe3SHajimu UMEMOTO 		init_comm_element(&qstate->request, CET_READ_REQUEST);
59306a99fe3SHajimu UMEMOTO 		read_request = get_cache_read_request(&qstate->request);
59406a99fe3SHajimu UMEMOTO 
59506a99fe3SHajimu UMEMOTO 		result = qstate->read_func(qstate,
59606a99fe3SHajimu UMEMOTO 	    		&read_request->entry_length, sizeof(size_t));
59706a99fe3SHajimu UMEMOTO 		result += qstate->read_func(qstate,
59806a99fe3SHajimu UMEMOTO 	    		&read_request->cache_key_size, sizeof(size_t));
59906a99fe3SHajimu UMEMOTO 
60006a99fe3SHajimu UMEMOTO 		if (result != sizeof(size_t) * 2) {
60106a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_read_request_read1);
60206a99fe3SHajimu UMEMOTO 			return (-1);
60306a99fe3SHajimu UMEMOTO 		}
60406a99fe3SHajimu UMEMOTO 
60506a99fe3SHajimu UMEMOTO 		if (BUFSIZE_INVALID(read_request->entry_length) ||
60606a99fe3SHajimu UMEMOTO 			BUFSIZE_INVALID(read_request->cache_key_size)) {
60706a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_read_request_read1);
60806a99fe3SHajimu UMEMOTO 			return (-1);
60906a99fe3SHajimu UMEMOTO 		}
61006a99fe3SHajimu UMEMOTO 
6118eeaaffaSDag-Erling Smørgrav 		read_request->entry = calloc(1,
61206a99fe3SHajimu UMEMOTO 			read_request->entry_length + 1);
61306a99fe3SHajimu UMEMOTO 		assert(read_request->entry != NULL);
61406a99fe3SHajimu UMEMOTO 
6158eeaaffaSDag-Erling Smørgrav 		read_request->cache_key = calloc(1,
61606a99fe3SHajimu UMEMOTO 			read_request->cache_key_size +
61706a99fe3SHajimu UMEMOTO 			qstate->eid_str_length);
61806a99fe3SHajimu UMEMOTO 		assert(read_request->cache_key != NULL);
61906a99fe3SHajimu UMEMOTO 		memcpy(read_request->cache_key, qstate->eid_str,
62006a99fe3SHajimu UMEMOTO 			qstate->eid_str_length);
62106a99fe3SHajimu UMEMOTO 
62206a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = read_request->entry_length +
62306a99fe3SHajimu UMEMOTO 			read_request->cache_key_size;
62406a99fe3SHajimu UMEMOTO 		qstate->process_func = on_read_request_read2;
62506a99fe3SHajimu UMEMOTO 	}
62606a99fe3SHajimu UMEMOTO 
62706a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_read_request_read1);
62806a99fe3SHajimu UMEMOTO 	return (0);
62906a99fe3SHajimu UMEMOTO }
63006a99fe3SHajimu UMEMOTO 
63106a99fe3SHajimu UMEMOTO static int
63206a99fe3SHajimu UMEMOTO on_read_request_read2(struct query_state *qstate)
63306a99fe3SHajimu UMEMOTO {
63406a99fe3SHajimu UMEMOTO 	struct cache_read_request	*read_request;
63506a99fe3SHajimu UMEMOTO 	ssize_t	result;
63606a99fe3SHajimu UMEMOTO 
63706a99fe3SHajimu UMEMOTO 	TRACE_IN(on_read_request_read2);
63806a99fe3SHajimu UMEMOTO 	read_request = get_cache_read_request(&qstate->request);
63906a99fe3SHajimu UMEMOTO 
64006a99fe3SHajimu UMEMOTO 	result = qstate->read_func(qstate, read_request->entry,
64106a99fe3SHajimu UMEMOTO 		read_request->entry_length);
64206a99fe3SHajimu UMEMOTO 	result += qstate->read_func(qstate,
64306a99fe3SHajimu UMEMOTO 		read_request->cache_key + qstate->eid_str_length,
64406a99fe3SHajimu UMEMOTO 		read_request->cache_key_size);
64506a99fe3SHajimu UMEMOTO 
64651d6ddb5SDag-Erling Smørgrav 	if (result != (ssize_t)qstate->kevent_watermark) {
64706a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_read_request_read2);
64806a99fe3SHajimu UMEMOTO 		return (-1);
64906a99fe3SHajimu UMEMOTO 	}
65006a99fe3SHajimu UMEMOTO 	read_request->cache_key_size += qstate->eid_str_length;
65106a99fe3SHajimu UMEMOTO 
65206a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = 0;
65306a99fe3SHajimu UMEMOTO 	qstate->process_func = on_read_request_process;
65406a99fe3SHajimu UMEMOTO 
65506a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_read_request_read2);
65606a99fe3SHajimu UMEMOTO 	return (0);
65706a99fe3SHajimu UMEMOTO }
65806a99fe3SHajimu UMEMOTO 
65906a99fe3SHajimu UMEMOTO static int
66006a99fe3SHajimu UMEMOTO on_read_request_process(struct query_state *qstate)
66106a99fe3SHajimu UMEMOTO {
66206a99fe3SHajimu UMEMOTO 	struct cache_read_request *read_request;
66306a99fe3SHajimu UMEMOTO 	struct cache_read_response *read_response;
66406a99fe3SHajimu UMEMOTO 	cache_entry	c_entry, neg_c_entry;
66506a99fe3SHajimu UMEMOTO 
66606a99fe3SHajimu UMEMOTO 	struct agent	*lookup_agent;
66706a99fe3SHajimu UMEMOTO 	struct common_agent *c_agent;
66806a99fe3SHajimu UMEMOTO 	int res;
66906a99fe3SHajimu UMEMOTO 
67006a99fe3SHajimu UMEMOTO 	TRACE_IN(on_read_request_process);
67106a99fe3SHajimu UMEMOTO 	init_comm_element(&qstate->response, CET_READ_RESPONSE);
67206a99fe3SHajimu UMEMOTO 	read_response = get_cache_read_response(&qstate->response);
67306a99fe3SHajimu UMEMOTO 	read_request = get_cache_read_request(&qstate->request);
67406a99fe3SHajimu UMEMOTO 
67506a99fe3SHajimu UMEMOTO 	qstate->config_entry = configuration_find_entry(
67606a99fe3SHajimu UMEMOTO 		s_configuration, read_request->entry);
67706a99fe3SHajimu UMEMOTO 	if (qstate->config_entry == NULL) {
67806a99fe3SHajimu UMEMOTO 		read_response->error_code = ENOENT;
67906a99fe3SHajimu UMEMOTO 
68006a99fe3SHajimu UMEMOTO 		LOG_ERR_2("read_request",
68106a99fe3SHajimu UMEMOTO 			"can't find configuration "
68206a99fe3SHajimu UMEMOTO 	    		"entry '%s'. aborting request", read_request->entry);
68306a99fe3SHajimu UMEMOTO 	    	goto fin;
68406a99fe3SHajimu UMEMOTO 	}
68506a99fe3SHajimu UMEMOTO 
68606a99fe3SHajimu UMEMOTO 	if (qstate->config_entry->enabled == 0) {
68706a99fe3SHajimu UMEMOTO 		read_response->error_code = EACCES;
68806a99fe3SHajimu UMEMOTO 
68906a99fe3SHajimu UMEMOTO 		LOG_ERR_2("read_request",
69006a99fe3SHajimu UMEMOTO 			"configuration entry '%s' is disabled",
69106a99fe3SHajimu UMEMOTO 			read_request->entry);
69206a99fe3SHajimu UMEMOTO 		goto fin;
69306a99fe3SHajimu UMEMOTO 	}
69406a99fe3SHajimu UMEMOTO 
69506a99fe3SHajimu UMEMOTO 	/*
69606a99fe3SHajimu UMEMOTO 	 * if we perform lookups by ourselves, then we don't need to separate
69706a99fe3SHajimu UMEMOTO 	 * cache entries by euid and egid
69806a99fe3SHajimu UMEMOTO 	 */
69906a99fe3SHajimu UMEMOTO 	if (qstate->config_entry->perform_actual_lookups != 0)
70006a99fe3SHajimu UMEMOTO 		memset(read_request->cache_key, 0, qstate->eid_str_length);
70106a99fe3SHajimu UMEMOTO 	else {
702db1bdf2bSMichael Bushkov #ifdef NS_NSCD_EID_CHECKING
70306a99fe3SHajimu UMEMOTO 		if (check_query_eids(qstate) != 0) {
70406a99fe3SHajimu UMEMOTO 		/* if the lookup is not self-performing, we check for clients euid/egid */
70506a99fe3SHajimu UMEMOTO 			read_response->error_code = EPERM;
70606a99fe3SHajimu UMEMOTO 			goto fin;
70706a99fe3SHajimu UMEMOTO 		}
70806a99fe3SHajimu UMEMOTO #endif
70906a99fe3SHajimu UMEMOTO 	}
71006a99fe3SHajimu UMEMOTO 
71106a99fe3SHajimu UMEMOTO 	configuration_lock_rdlock(s_configuration);
71206a99fe3SHajimu UMEMOTO 	c_entry = find_cache_entry(s_cache,
71327f2bc9eSDag-Erling Smørgrav 		qstate->config_entry->positive_cache_params.cep.entry_name);
71406a99fe3SHajimu UMEMOTO 	neg_c_entry = find_cache_entry(s_cache,
71527f2bc9eSDag-Erling Smørgrav 		qstate->config_entry->negative_cache_params.cep.entry_name);
71606a99fe3SHajimu UMEMOTO 	configuration_unlock(s_configuration);
71706a99fe3SHajimu UMEMOTO 	if ((c_entry != NULL) && (neg_c_entry != NULL)) {
71806a99fe3SHajimu UMEMOTO 		configuration_lock_entry(qstate->config_entry, CELT_POSITIVE);
71906a99fe3SHajimu UMEMOTO 		qstate->config_entry->positive_cache_entry = c_entry;
72006a99fe3SHajimu UMEMOTO 		read_response->error_code = cache_read(c_entry,
72106a99fe3SHajimu UMEMOTO 	    		read_request->cache_key,
72206a99fe3SHajimu UMEMOTO 	    		read_request->cache_key_size, NULL,
72306a99fe3SHajimu UMEMOTO 	    		&read_response->data_size);
72406a99fe3SHajimu UMEMOTO 
72506a99fe3SHajimu UMEMOTO 		if (read_response->error_code == -2) {
7268eeaaffaSDag-Erling Smørgrav 			read_response->data = malloc(
72706a99fe3SHajimu UMEMOTO 				read_response->data_size);
728*12326285SCy Schubert 			assert(read_response->data != NULL);
72906a99fe3SHajimu UMEMOTO 			read_response->error_code = cache_read(c_entry,
73006a99fe3SHajimu UMEMOTO 				read_request->cache_key,
73106a99fe3SHajimu UMEMOTO 		    		read_request->cache_key_size,
73206a99fe3SHajimu UMEMOTO 		    		read_response->data,
73306a99fe3SHajimu UMEMOTO 		    		&read_response->data_size);
73406a99fe3SHajimu UMEMOTO 		}
73506a99fe3SHajimu UMEMOTO 		configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE);
73606a99fe3SHajimu UMEMOTO 
73706a99fe3SHajimu UMEMOTO 		configuration_lock_entry(qstate->config_entry, CELT_NEGATIVE);
73806a99fe3SHajimu UMEMOTO 		qstate->config_entry->negative_cache_entry = neg_c_entry;
73906a99fe3SHajimu UMEMOTO 		if (read_response->error_code == -1) {
74006a99fe3SHajimu UMEMOTO 			read_response->error_code = cache_read(neg_c_entry,
74106a99fe3SHajimu UMEMOTO 				read_request->cache_key,
74206a99fe3SHajimu UMEMOTO 				read_request->cache_key_size, NULL,
74306a99fe3SHajimu UMEMOTO 				&read_response->data_size);
74406a99fe3SHajimu UMEMOTO 
74506a99fe3SHajimu UMEMOTO 			if (read_response->error_code == -2) {
7468af0c00bSCy Schubert 				read_response->data = malloc(
7478af0c00bSCy Schubert 					read_response->data_size);
748*12326285SCy Schubert 				assert(read_response->data != NULL);
7498af0c00bSCy Schubert 				read_response->error_code = cache_read(neg_c_entry,
7508af0c00bSCy Schubert 					read_request->cache_key,
7518af0c00bSCy Schubert 		    			read_request->cache_key_size,
7528af0c00bSCy Schubert 		    			read_response->data,
7538af0c00bSCy Schubert 		    			&read_response->data_size);
75406a99fe3SHajimu UMEMOTO 			}
75506a99fe3SHajimu UMEMOTO 		}
75606a99fe3SHajimu UMEMOTO 		configuration_unlock_entry(qstate->config_entry, CELT_NEGATIVE);
75706a99fe3SHajimu UMEMOTO 
75806a99fe3SHajimu UMEMOTO 		if ((read_response->error_code == -1) &&
75906a99fe3SHajimu UMEMOTO 			(qstate->config_entry->perform_actual_lookups != 0)) {
76006a99fe3SHajimu UMEMOTO 			free(read_response->data);
76106a99fe3SHajimu UMEMOTO 			read_response->data = NULL;
76206a99fe3SHajimu UMEMOTO 			read_response->data_size = 0;
76306a99fe3SHajimu UMEMOTO 
76406a99fe3SHajimu UMEMOTO 			lookup_agent = find_agent(s_agent_table,
76506a99fe3SHajimu UMEMOTO 				read_request->entry, COMMON_AGENT);
76606a99fe3SHajimu UMEMOTO 
76706a99fe3SHajimu UMEMOTO 			if ((lookup_agent != NULL) &&
76806a99fe3SHajimu UMEMOTO 			(lookup_agent->type == COMMON_AGENT)) {
76906a99fe3SHajimu UMEMOTO 				c_agent = (struct common_agent *)lookup_agent;
77006a99fe3SHajimu UMEMOTO 				res = c_agent->lookup_func(
77106a99fe3SHajimu UMEMOTO 					read_request->cache_key +
77206a99fe3SHajimu UMEMOTO 						qstate->eid_str_length,
77306a99fe3SHajimu UMEMOTO 					read_request->cache_key_size -
77406a99fe3SHajimu UMEMOTO 						qstate->eid_str_length,
77506a99fe3SHajimu UMEMOTO 					&read_response->data,
77606a99fe3SHajimu UMEMOTO 					&read_response->data_size);
77706a99fe3SHajimu UMEMOTO 
77806a99fe3SHajimu UMEMOTO 				if (res == NS_SUCCESS) {
77906a99fe3SHajimu UMEMOTO 					read_response->error_code = 0;
78006a99fe3SHajimu UMEMOTO 					configuration_lock_entry(
78106a99fe3SHajimu UMEMOTO 						qstate->config_entry,
78206a99fe3SHajimu UMEMOTO 						CELT_POSITIVE);
78306a99fe3SHajimu UMEMOTO 					cache_write(c_entry,
78406a99fe3SHajimu UMEMOTO 						read_request->cache_key,
78506a99fe3SHajimu UMEMOTO 	    					read_request->cache_key_size,
78606a99fe3SHajimu UMEMOTO 	    					read_response->data,
78706a99fe3SHajimu UMEMOTO 						read_response->data_size);
78806a99fe3SHajimu UMEMOTO 					configuration_unlock_entry(
78906a99fe3SHajimu UMEMOTO 						qstate->config_entry,
79006a99fe3SHajimu UMEMOTO 						CELT_POSITIVE);
79106a99fe3SHajimu UMEMOTO 				} else if ((res == NS_NOTFOUND) ||
79206a99fe3SHajimu UMEMOTO 					  (res == NS_RETURN)) {
79306a99fe3SHajimu UMEMOTO 					configuration_lock_entry(
79406a99fe3SHajimu UMEMOTO 						  qstate->config_entry,
79506a99fe3SHajimu UMEMOTO 						  CELT_NEGATIVE);
79606a99fe3SHajimu UMEMOTO 					cache_write(neg_c_entry,
79706a99fe3SHajimu UMEMOTO 						read_request->cache_key,
79806a99fe3SHajimu UMEMOTO 						read_request->cache_key_size,
79906a99fe3SHajimu UMEMOTO 						negative_data,
80006a99fe3SHajimu UMEMOTO 						sizeof(negative_data));
80106a99fe3SHajimu UMEMOTO 					configuration_unlock_entry(
80206a99fe3SHajimu UMEMOTO 						  qstate->config_entry,
80306a99fe3SHajimu UMEMOTO 						  CELT_NEGATIVE);
80406a99fe3SHajimu UMEMOTO 
80506a99fe3SHajimu UMEMOTO 					read_response->error_code = 0;
80606a99fe3SHajimu UMEMOTO 					read_response->data = NULL;
80706a99fe3SHajimu UMEMOTO 					read_response->data_size = 0;
80806a99fe3SHajimu UMEMOTO 				}
80906a99fe3SHajimu UMEMOTO 			}
81006a99fe3SHajimu UMEMOTO 		}
81106a99fe3SHajimu UMEMOTO 
81206a99fe3SHajimu UMEMOTO 		if ((qstate->config_entry->common_query_timeout.tv_sec != 0) ||
81306a99fe3SHajimu UMEMOTO 		    (qstate->config_entry->common_query_timeout.tv_usec != 0))
81406a99fe3SHajimu UMEMOTO 			memcpy(&qstate->timeout,
81506a99fe3SHajimu UMEMOTO 				&qstate->config_entry->common_query_timeout,
81606a99fe3SHajimu UMEMOTO 				sizeof(struct timeval));
81706a99fe3SHajimu UMEMOTO 	} else
81806a99fe3SHajimu UMEMOTO 		read_response->error_code = -1;
81906a99fe3SHajimu UMEMOTO 
82006a99fe3SHajimu UMEMOTO fin:
82106a99fe3SHajimu UMEMOTO 	qstate->kevent_filter = EVFILT_WRITE;
82206a99fe3SHajimu UMEMOTO 	if (read_response->error_code == 0)
82306a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = sizeof(int) + sizeof(size_t);
82406a99fe3SHajimu UMEMOTO 	else
82506a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = sizeof(int);
82606a99fe3SHajimu UMEMOTO 	qstate->process_func = on_read_response_write1;
82706a99fe3SHajimu UMEMOTO 
82806a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_read_request_process);
82906a99fe3SHajimu UMEMOTO 	return (0);
83006a99fe3SHajimu UMEMOTO }
83106a99fe3SHajimu UMEMOTO 
83206a99fe3SHajimu UMEMOTO static int
83306a99fe3SHajimu UMEMOTO on_read_response_write1(struct query_state *qstate)
83406a99fe3SHajimu UMEMOTO {
83506a99fe3SHajimu UMEMOTO 	struct cache_read_response	*read_response;
83606a99fe3SHajimu UMEMOTO 	ssize_t	result;
83706a99fe3SHajimu UMEMOTO 
83806a99fe3SHajimu UMEMOTO 	TRACE_IN(on_read_response_write1);
83906a99fe3SHajimu UMEMOTO 	read_response = get_cache_read_response(&qstate->response);
84006a99fe3SHajimu UMEMOTO 
84106a99fe3SHajimu UMEMOTO 	result = qstate->write_func(qstate, &read_response->error_code,
84206a99fe3SHajimu UMEMOTO 		sizeof(int));
84306a99fe3SHajimu UMEMOTO 
84406a99fe3SHajimu UMEMOTO 	if (read_response->error_code == 0) {
84506a99fe3SHajimu UMEMOTO 		result += qstate->write_func(qstate, &read_response->data_size,
84606a99fe3SHajimu UMEMOTO 			sizeof(size_t));
84751d6ddb5SDag-Erling Smørgrav 		if (result != (ssize_t)qstate->kevent_watermark) {
84806a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_read_response_write1);
84906a99fe3SHajimu UMEMOTO 			return (-1);
85006a99fe3SHajimu UMEMOTO 		}
85106a99fe3SHajimu UMEMOTO 
85206a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = read_response->data_size;
85306a99fe3SHajimu UMEMOTO 		qstate->process_func = on_read_response_write2;
85406a99fe3SHajimu UMEMOTO 	} else {
85551d6ddb5SDag-Erling Smørgrav 		if (result != (ssize_t)qstate->kevent_watermark) {
85606a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_read_response_write1);
85706a99fe3SHajimu UMEMOTO 			return (-1);
85806a99fe3SHajimu UMEMOTO 		}
85906a99fe3SHajimu UMEMOTO 
86006a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = 0;
86106a99fe3SHajimu UMEMOTO 		qstate->process_func = NULL;
86206a99fe3SHajimu UMEMOTO 	}
86306a99fe3SHajimu UMEMOTO 
86406a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_read_response_write1);
86506a99fe3SHajimu UMEMOTO 	return (0);
86606a99fe3SHajimu UMEMOTO }
86706a99fe3SHajimu UMEMOTO 
86806a99fe3SHajimu UMEMOTO static int
86906a99fe3SHajimu UMEMOTO on_read_response_write2(struct query_state *qstate)
87006a99fe3SHajimu UMEMOTO {
87106a99fe3SHajimu UMEMOTO 	struct cache_read_response	*read_response;
87206a99fe3SHajimu UMEMOTO 	ssize_t	result;
87306a99fe3SHajimu UMEMOTO 
87406a99fe3SHajimu UMEMOTO 	TRACE_IN(on_read_response_write2);
87506a99fe3SHajimu UMEMOTO 	read_response = get_cache_read_response(&qstate->response);
87606a99fe3SHajimu UMEMOTO 	if (read_response->data_size > 0) {
87706a99fe3SHajimu UMEMOTO 		result = qstate->write_func(qstate, read_response->data,
87806a99fe3SHajimu UMEMOTO 			read_response->data_size);
87951d6ddb5SDag-Erling Smørgrav 		if (result != (ssize_t)qstate->kevent_watermark) {
88006a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_read_response_write2);
88106a99fe3SHajimu UMEMOTO 			return (-1);
88206a99fe3SHajimu UMEMOTO 		}
88306a99fe3SHajimu UMEMOTO 	}
88406a99fe3SHajimu UMEMOTO 
88506a99fe3SHajimu UMEMOTO 	finalize_comm_element(&qstate->request);
88606a99fe3SHajimu UMEMOTO 	finalize_comm_element(&qstate->response);
88706a99fe3SHajimu UMEMOTO 
88806a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = sizeof(int);
88906a99fe3SHajimu UMEMOTO 	qstate->kevent_filter = EVFILT_READ;
89006a99fe3SHajimu UMEMOTO 	qstate->process_func = on_rw_mapper;
89106a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_read_response_write2);
89206a99fe3SHajimu UMEMOTO 	return (0);
89306a99fe3SHajimu UMEMOTO }
89406a99fe3SHajimu UMEMOTO 
89506a99fe3SHajimu UMEMOTO /*
89606a99fe3SHajimu UMEMOTO  * The functions below are used to process write requests.
89706a99fe3SHajimu UMEMOTO  * - on_transform_request_read1 and on_transform_request_read2 read the
89806a99fe3SHajimu UMEMOTO  *   request itself
89906a99fe3SHajimu UMEMOTO  * - on_transform_request_process processes it
90006a99fe3SHajimu UMEMOTO  * - on_transform_response_write1 sends the response
90106a99fe3SHajimu UMEMOTO  */
90206a99fe3SHajimu UMEMOTO static int
90306a99fe3SHajimu UMEMOTO on_transform_request_read1(struct query_state *qstate)
90406a99fe3SHajimu UMEMOTO {
90506a99fe3SHajimu UMEMOTO 	struct cache_transform_request *transform_request;
90606a99fe3SHajimu UMEMOTO 	ssize_t	result;
90706a99fe3SHajimu UMEMOTO 
90806a99fe3SHajimu UMEMOTO 	TRACE_IN(on_transform_request_read1);
90906a99fe3SHajimu UMEMOTO 	if (qstate->kevent_watermark == 0)
91006a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = sizeof(size_t) + sizeof(int);
91106a99fe3SHajimu UMEMOTO 	else {
91206a99fe3SHajimu UMEMOTO 		init_comm_element(&qstate->request, CET_TRANSFORM_REQUEST);
91306a99fe3SHajimu UMEMOTO 		transform_request =
91406a99fe3SHajimu UMEMOTO 			get_cache_transform_request(&qstate->request);
91506a99fe3SHajimu UMEMOTO 
91606a99fe3SHajimu UMEMOTO 		result = qstate->read_func(qstate,
91706a99fe3SHajimu UMEMOTO 	    		&transform_request->entry_length, sizeof(size_t));
91806a99fe3SHajimu UMEMOTO 		result += qstate->read_func(qstate,
91906a99fe3SHajimu UMEMOTO 	    		&transform_request->transformation_type, sizeof(int));
92006a99fe3SHajimu UMEMOTO 
92106a99fe3SHajimu UMEMOTO 		if (result != sizeof(size_t) + sizeof(int)) {
92206a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_transform_request_read1);
92306a99fe3SHajimu UMEMOTO 			return (-1);
92406a99fe3SHajimu UMEMOTO 		}
92506a99fe3SHajimu UMEMOTO 
92606a99fe3SHajimu UMEMOTO 		if ((transform_request->transformation_type != TT_USER) &&
92706a99fe3SHajimu UMEMOTO 		    (transform_request->transformation_type != TT_ALL)) {
92806a99fe3SHajimu UMEMOTO 			TRACE_OUT(on_transform_request_read1);
92906a99fe3SHajimu UMEMOTO 			return (-1);
93006a99fe3SHajimu UMEMOTO 		}
93106a99fe3SHajimu UMEMOTO 
93206a99fe3SHajimu UMEMOTO 		if (transform_request->entry_length != 0) {
93306a99fe3SHajimu UMEMOTO 			if (BUFSIZE_INVALID(transform_request->entry_length)) {
93406a99fe3SHajimu UMEMOTO 				TRACE_OUT(on_transform_request_read1);
93506a99fe3SHajimu UMEMOTO 				return (-1);
93606a99fe3SHajimu UMEMOTO 			}
93706a99fe3SHajimu UMEMOTO 
9388eeaaffaSDag-Erling Smørgrav 			transform_request->entry = calloc(1,
93906a99fe3SHajimu UMEMOTO 				transform_request->entry_length + 1);
94006a99fe3SHajimu UMEMOTO 			assert(transform_request->entry != NULL);
94106a99fe3SHajimu UMEMOTO 
94206a99fe3SHajimu UMEMOTO 			qstate->process_func = on_transform_request_read2;
94306a99fe3SHajimu UMEMOTO 		} else
94406a99fe3SHajimu UMEMOTO 			qstate->process_func = on_transform_request_process;
94506a99fe3SHajimu UMEMOTO 
94606a99fe3SHajimu UMEMOTO 		qstate->kevent_watermark = transform_request->entry_length;
94706a99fe3SHajimu UMEMOTO 	}
94806a99fe3SHajimu UMEMOTO 
94906a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_transform_request_read1);
95006a99fe3SHajimu UMEMOTO 	return (0);
95106a99fe3SHajimu UMEMOTO }
95206a99fe3SHajimu UMEMOTO 
95306a99fe3SHajimu UMEMOTO static int
95406a99fe3SHajimu UMEMOTO on_transform_request_read2(struct query_state *qstate)
95506a99fe3SHajimu UMEMOTO {
95606a99fe3SHajimu UMEMOTO 	struct cache_transform_request	*transform_request;
95706a99fe3SHajimu UMEMOTO 	ssize_t	result;
95806a99fe3SHajimu UMEMOTO 
95906a99fe3SHajimu UMEMOTO 	TRACE_IN(on_transform_request_read2);
96006a99fe3SHajimu UMEMOTO 	transform_request = get_cache_transform_request(&qstate->request);
96106a99fe3SHajimu UMEMOTO 
96206a99fe3SHajimu UMEMOTO 	result = qstate->read_func(qstate, transform_request->entry,
96306a99fe3SHajimu UMEMOTO 		transform_request->entry_length);
96406a99fe3SHajimu UMEMOTO 
96551d6ddb5SDag-Erling Smørgrav 	if (result != (ssize_t)qstate->kevent_watermark) {
96606a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_transform_request_read2);
96706a99fe3SHajimu UMEMOTO 		return (-1);
96806a99fe3SHajimu UMEMOTO 	}
96906a99fe3SHajimu UMEMOTO 
97006a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = 0;
97106a99fe3SHajimu UMEMOTO 	qstate->process_func = on_transform_request_process;
97206a99fe3SHajimu UMEMOTO 
97306a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_transform_request_read2);
97406a99fe3SHajimu UMEMOTO 	return (0);
97506a99fe3SHajimu UMEMOTO }
97606a99fe3SHajimu UMEMOTO 
97706a99fe3SHajimu UMEMOTO static int
97806a99fe3SHajimu UMEMOTO on_transform_request_process(struct query_state *qstate)
97906a99fe3SHajimu UMEMOTO {
98006a99fe3SHajimu UMEMOTO 	struct cache_transform_request *transform_request;
98106a99fe3SHajimu UMEMOTO 	struct cache_transform_response *transform_response;
98206a99fe3SHajimu UMEMOTO 	struct configuration_entry *config_entry;
98306a99fe3SHajimu UMEMOTO 	size_t	i, size;
98406a99fe3SHajimu UMEMOTO 
98506a99fe3SHajimu UMEMOTO 	TRACE_IN(on_transform_request_process);
98606a99fe3SHajimu UMEMOTO 	init_comm_element(&qstate->response, CET_TRANSFORM_RESPONSE);
98706a99fe3SHajimu UMEMOTO 	transform_response = get_cache_transform_response(&qstate->response);
98806a99fe3SHajimu UMEMOTO 	transform_request = get_cache_transform_request(&qstate->request);
98906a99fe3SHajimu UMEMOTO 
99006a99fe3SHajimu UMEMOTO 	switch (transform_request->transformation_type) {
99106a99fe3SHajimu UMEMOTO 	case TT_USER:
99206a99fe3SHajimu UMEMOTO 		if (transform_request->entry == NULL) {
99306a99fe3SHajimu UMEMOTO 			size = configuration_get_entries_size(s_configuration);
99406a99fe3SHajimu UMEMOTO 			for (i = 0; i < size; ++i) {
99506a99fe3SHajimu UMEMOTO 			    config_entry = configuration_get_entry(
99606a99fe3SHajimu UMEMOTO 				s_configuration, i);
99706a99fe3SHajimu UMEMOTO 
99806a99fe3SHajimu UMEMOTO 			    if (config_entry->perform_actual_lookups == 0)
99906a99fe3SHajimu UMEMOTO 			    	clear_config_entry_part(config_entry,
100006a99fe3SHajimu UMEMOTO 				    qstate->eid_str, qstate->eid_str_length);
100106a99fe3SHajimu UMEMOTO 			}
100206a99fe3SHajimu UMEMOTO 		} else {
100306a99fe3SHajimu UMEMOTO 			qstate->config_entry = configuration_find_entry(
100406a99fe3SHajimu UMEMOTO 				s_configuration, transform_request->entry);
100506a99fe3SHajimu UMEMOTO 
100606a99fe3SHajimu UMEMOTO 			if (qstate->config_entry == NULL) {
100706a99fe3SHajimu UMEMOTO 				LOG_ERR_2("transform_request",
100806a99fe3SHajimu UMEMOTO 					"can't find configuration"
100906a99fe3SHajimu UMEMOTO 		   			" entry '%s'. aborting request",
101006a99fe3SHajimu UMEMOTO 					transform_request->entry);
101106a99fe3SHajimu UMEMOTO 				transform_response->error_code = -1;
101206a99fe3SHajimu UMEMOTO 				goto fin;
101306a99fe3SHajimu UMEMOTO 			}
101406a99fe3SHajimu UMEMOTO 
101506a99fe3SHajimu UMEMOTO 			if (qstate->config_entry->perform_actual_lookups != 0) {
101606a99fe3SHajimu UMEMOTO 				LOG_ERR_2("transform_request",
101706a99fe3SHajimu UMEMOTO 					"can't transform the cache entry %s"
101806a99fe3SHajimu UMEMOTO 					", because it ised for actual lookups",
101906a99fe3SHajimu UMEMOTO 					transform_request->entry);
102006a99fe3SHajimu UMEMOTO 				transform_response->error_code = -1;
102106a99fe3SHajimu UMEMOTO 				goto fin;
102206a99fe3SHajimu UMEMOTO 			}
102306a99fe3SHajimu UMEMOTO 
102406a99fe3SHajimu UMEMOTO 			clear_config_entry_part(qstate->config_entry,
102506a99fe3SHajimu UMEMOTO 				qstate->eid_str, qstate->eid_str_length);
102606a99fe3SHajimu UMEMOTO 		}
102706a99fe3SHajimu UMEMOTO 		break;
102806a99fe3SHajimu UMEMOTO 	case TT_ALL:
102906a99fe3SHajimu UMEMOTO 		if (qstate->euid != 0)
103006a99fe3SHajimu UMEMOTO 			transform_response->error_code = -1;
103106a99fe3SHajimu UMEMOTO 		else {
103206a99fe3SHajimu UMEMOTO 			if (transform_request->entry == NULL) {
103306a99fe3SHajimu UMEMOTO 				size = configuration_get_entries_size(
103406a99fe3SHajimu UMEMOTO 					s_configuration);
103506a99fe3SHajimu UMEMOTO 				for (i = 0; i < size; ++i) {
103606a99fe3SHajimu UMEMOTO 				    clear_config_entry(
103706a99fe3SHajimu UMEMOTO 					configuration_get_entry(
103806a99fe3SHajimu UMEMOTO 						s_configuration, i));
103906a99fe3SHajimu UMEMOTO 				}
104006a99fe3SHajimu UMEMOTO 			} else {
104106a99fe3SHajimu UMEMOTO 				qstate->config_entry = configuration_find_entry(
104206a99fe3SHajimu UMEMOTO 					s_configuration,
104306a99fe3SHajimu UMEMOTO 					transform_request->entry);
104406a99fe3SHajimu UMEMOTO 
104506a99fe3SHajimu UMEMOTO 				if (qstate->config_entry == NULL) {
104606a99fe3SHajimu UMEMOTO 					LOG_ERR_2("transform_request",
104706a99fe3SHajimu UMEMOTO 						"can't find configuration"
104806a99fe3SHajimu UMEMOTO 		   				" entry '%s'. aborting request",
104906a99fe3SHajimu UMEMOTO 						transform_request->entry);
105006a99fe3SHajimu UMEMOTO 					transform_response->error_code = -1;
105106a99fe3SHajimu UMEMOTO 					goto fin;
105206a99fe3SHajimu UMEMOTO 				}
105306a99fe3SHajimu UMEMOTO 
105406a99fe3SHajimu UMEMOTO 				clear_config_entry(qstate->config_entry);
105506a99fe3SHajimu UMEMOTO 			}
105606a99fe3SHajimu UMEMOTO 		}
105706a99fe3SHajimu UMEMOTO 		break;
105806a99fe3SHajimu UMEMOTO 	default:
105906a99fe3SHajimu UMEMOTO 		transform_response->error_code = -1;
106006a99fe3SHajimu UMEMOTO 	}
106106a99fe3SHajimu UMEMOTO 
106206a99fe3SHajimu UMEMOTO fin:
106306a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = 0;
106406a99fe3SHajimu UMEMOTO 	qstate->process_func = on_transform_response_write1;
106506a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_transform_request_process);
106606a99fe3SHajimu UMEMOTO 	return (0);
106706a99fe3SHajimu UMEMOTO }
106806a99fe3SHajimu UMEMOTO 
106906a99fe3SHajimu UMEMOTO static int
107006a99fe3SHajimu UMEMOTO on_transform_response_write1(struct query_state *qstate)
107106a99fe3SHajimu UMEMOTO {
107206a99fe3SHajimu UMEMOTO 	struct cache_transform_response	*transform_response;
107306a99fe3SHajimu UMEMOTO 	ssize_t	result;
107406a99fe3SHajimu UMEMOTO 
107506a99fe3SHajimu UMEMOTO 	TRACE_IN(on_transform_response_write1);
107606a99fe3SHajimu UMEMOTO 	transform_response = get_cache_transform_response(&qstate->response);
107706a99fe3SHajimu UMEMOTO 	result = qstate->write_func(qstate, &transform_response->error_code,
107806a99fe3SHajimu UMEMOTO 		sizeof(int));
107906a99fe3SHajimu UMEMOTO 	if (result != sizeof(int)) {
108006a99fe3SHajimu UMEMOTO 		TRACE_OUT(on_transform_response_write1);
108106a99fe3SHajimu UMEMOTO 		return (-1);
108206a99fe3SHajimu UMEMOTO 	}
108306a99fe3SHajimu UMEMOTO 
108406a99fe3SHajimu UMEMOTO 	finalize_comm_element(&qstate->request);
108506a99fe3SHajimu UMEMOTO 	finalize_comm_element(&qstate->response);
108606a99fe3SHajimu UMEMOTO 
108706a99fe3SHajimu UMEMOTO 	qstate->kevent_watermark = 0;
108806a99fe3SHajimu UMEMOTO 	qstate->process_func = NULL;
108906a99fe3SHajimu UMEMOTO 	TRACE_OUT(on_transform_response_write1);
109006a99fe3SHajimu UMEMOTO 	return (0);
109106a99fe3SHajimu UMEMOTO }
109206a99fe3SHajimu UMEMOTO 
109306a99fe3SHajimu UMEMOTO /*
109406a99fe3SHajimu UMEMOTO  * Checks if the client's euid and egid do not differ from its uid and gid.
109506a99fe3SHajimu UMEMOTO  * Returns 0 on success.
109606a99fe3SHajimu UMEMOTO  */
109706a99fe3SHajimu UMEMOTO int
109806a99fe3SHajimu UMEMOTO check_query_eids(struct query_state *qstate)
109906a99fe3SHajimu UMEMOTO {
110006a99fe3SHajimu UMEMOTO 
110106a99fe3SHajimu UMEMOTO 	return ((qstate->uid != qstate->euid) || (qstate->gid != qstate->egid) ? -1 : 0);
110206a99fe3SHajimu UMEMOTO }
110306a99fe3SHajimu UMEMOTO 
110406a99fe3SHajimu UMEMOTO /*
110506a99fe3SHajimu UMEMOTO  * Uses the qstate fields to process an "alternate" read - when the buffer is
110606a99fe3SHajimu UMEMOTO  * too large to be received during one socket read operation
110706a99fe3SHajimu UMEMOTO  */
110806a99fe3SHajimu UMEMOTO ssize_t
110906a99fe3SHajimu UMEMOTO query_io_buffer_read(struct query_state *qstate, void *buf, size_t nbytes)
111006a99fe3SHajimu UMEMOTO {
111151d6ddb5SDag-Erling Smørgrav 	size_t remaining;
111206a99fe3SHajimu UMEMOTO 	ssize_t	result;
111306a99fe3SHajimu UMEMOTO 
111406a99fe3SHajimu UMEMOTO 	TRACE_IN(query_io_buffer_read);
111506a99fe3SHajimu UMEMOTO 	if ((qstate->io_buffer_size == 0) || (qstate->io_buffer == NULL))
111606a99fe3SHajimu UMEMOTO 		return (-1);
111706a99fe3SHajimu UMEMOTO 
111851d6ddb5SDag-Erling Smørgrav 	assert(qstate->io_buffer_p <=
111951d6ddb5SDag-Erling Smørgrav 		qstate->io_buffer + qstate->io_buffer_size);
112051d6ddb5SDag-Erling Smørgrav 	remaining = qstate->io_buffer + qstate->io_buffer_size -
112151d6ddb5SDag-Erling Smørgrav 		qstate->io_buffer_p;
112251d6ddb5SDag-Erling Smørgrav 	if (nbytes < remaining)
112306a99fe3SHajimu UMEMOTO 		result = nbytes;
112406a99fe3SHajimu UMEMOTO 	else
112551d6ddb5SDag-Erling Smørgrav 		result = remaining;
112606a99fe3SHajimu UMEMOTO 
112706a99fe3SHajimu UMEMOTO 	memcpy(buf, qstate->io_buffer_p, result);
112806a99fe3SHajimu UMEMOTO 	qstate->io_buffer_p += result;
112906a99fe3SHajimu UMEMOTO 
113051d6ddb5SDag-Erling Smørgrav 	if (remaining == 0) {
113106a99fe3SHajimu UMEMOTO 		free(qstate->io_buffer);
113206a99fe3SHajimu UMEMOTO 		qstate->io_buffer = NULL;
113306a99fe3SHajimu UMEMOTO 
113406a99fe3SHajimu UMEMOTO 		qstate->write_func = query_socket_write;
113506a99fe3SHajimu UMEMOTO 		qstate->read_func = query_socket_read;
113606a99fe3SHajimu UMEMOTO 	}
113706a99fe3SHajimu UMEMOTO 
113806a99fe3SHajimu UMEMOTO 	TRACE_OUT(query_io_buffer_read);
113906a99fe3SHajimu UMEMOTO 	return (result);
114006a99fe3SHajimu UMEMOTO }
114106a99fe3SHajimu UMEMOTO 
114206a99fe3SHajimu UMEMOTO /*
114306a99fe3SHajimu UMEMOTO  * Uses the qstate fields to process an "alternate" write - when the buffer is
114406a99fe3SHajimu UMEMOTO  * too large to be sent during one socket write operation
114506a99fe3SHajimu UMEMOTO  */
114606a99fe3SHajimu UMEMOTO ssize_t
114706a99fe3SHajimu UMEMOTO query_io_buffer_write(struct query_state *qstate, const void *buf,
114806a99fe3SHajimu UMEMOTO 	size_t nbytes)
114906a99fe3SHajimu UMEMOTO {
115051d6ddb5SDag-Erling Smørgrav 	size_t remaining;
115106a99fe3SHajimu UMEMOTO 	ssize_t	result;
115206a99fe3SHajimu UMEMOTO 
115306a99fe3SHajimu UMEMOTO 	TRACE_IN(query_io_buffer_write);
115406a99fe3SHajimu UMEMOTO 	if ((qstate->io_buffer_size == 0) || (qstate->io_buffer == NULL))
115506a99fe3SHajimu UMEMOTO 		return (-1);
115606a99fe3SHajimu UMEMOTO 
115751d6ddb5SDag-Erling Smørgrav 	assert(qstate->io_buffer_p <=
115851d6ddb5SDag-Erling Smørgrav 		qstate->io_buffer + qstate->io_buffer_size);
115951d6ddb5SDag-Erling Smørgrav 	remaining = qstate->io_buffer + qstate->io_buffer_size -
116051d6ddb5SDag-Erling Smørgrav 		qstate->io_buffer_p;
116151d6ddb5SDag-Erling Smørgrav 	if (nbytes < remaining)
116206a99fe3SHajimu UMEMOTO 		result = nbytes;
116306a99fe3SHajimu UMEMOTO 	else
116451d6ddb5SDag-Erling Smørgrav 		result = remaining;
116506a99fe3SHajimu UMEMOTO 
116606a99fe3SHajimu UMEMOTO 	memcpy(qstate->io_buffer_p, buf, result);
116706a99fe3SHajimu UMEMOTO 	qstate->io_buffer_p += result;
116806a99fe3SHajimu UMEMOTO 
116951d6ddb5SDag-Erling Smørgrav 	if (remaining == 0) {
117006a99fe3SHajimu UMEMOTO 		qstate->use_alternate_io = 1;
117106a99fe3SHajimu UMEMOTO 		qstate->io_buffer_p = qstate->io_buffer;
117206a99fe3SHajimu UMEMOTO 
117306a99fe3SHajimu UMEMOTO 		qstate->write_func = query_socket_write;
117406a99fe3SHajimu UMEMOTO 		qstate->read_func = query_socket_read;
117506a99fe3SHajimu UMEMOTO 	}
117606a99fe3SHajimu UMEMOTO 
117706a99fe3SHajimu UMEMOTO 	TRACE_OUT(query_io_buffer_write);
117806a99fe3SHajimu UMEMOTO 	return (result);
117906a99fe3SHajimu UMEMOTO }
118006a99fe3SHajimu UMEMOTO 
118106a99fe3SHajimu UMEMOTO /*
118206a99fe3SHajimu UMEMOTO  * The default "read" function, which reads data directly from socket
118306a99fe3SHajimu UMEMOTO  */
118406a99fe3SHajimu UMEMOTO ssize_t
118506a99fe3SHajimu UMEMOTO query_socket_read(struct query_state *qstate, void *buf, size_t nbytes)
118606a99fe3SHajimu UMEMOTO {
118706a99fe3SHajimu UMEMOTO 	ssize_t	result;
118806a99fe3SHajimu UMEMOTO 
118906a99fe3SHajimu UMEMOTO 	TRACE_IN(query_socket_read);
119006a99fe3SHajimu UMEMOTO 	if (qstate->socket_failed != 0) {
119106a99fe3SHajimu UMEMOTO 		TRACE_OUT(query_socket_read);
119206a99fe3SHajimu UMEMOTO 		return (-1);
119306a99fe3SHajimu UMEMOTO 	}
119406a99fe3SHajimu UMEMOTO 
119506a99fe3SHajimu UMEMOTO 	result = read(qstate->sockfd, buf, nbytes);
119651d6ddb5SDag-Erling Smørgrav 	if (result < 0 || (size_t)result < nbytes)
119706a99fe3SHajimu UMEMOTO 		qstate->socket_failed = 1;
119806a99fe3SHajimu UMEMOTO 
119906a99fe3SHajimu UMEMOTO 	TRACE_OUT(query_socket_read);
120006a99fe3SHajimu UMEMOTO 	return (result);
120106a99fe3SHajimu UMEMOTO }
120206a99fe3SHajimu UMEMOTO 
120306a99fe3SHajimu UMEMOTO /*
120406a99fe3SHajimu UMEMOTO  * The default "write" function, which writes data directly to socket
120506a99fe3SHajimu UMEMOTO  */
120606a99fe3SHajimu UMEMOTO ssize_t
120706a99fe3SHajimu UMEMOTO query_socket_write(struct query_state *qstate, const void *buf, size_t nbytes)
120806a99fe3SHajimu UMEMOTO {
120906a99fe3SHajimu UMEMOTO 	ssize_t	result;
121006a99fe3SHajimu UMEMOTO 
121106a99fe3SHajimu UMEMOTO 	TRACE_IN(query_socket_write);
121206a99fe3SHajimu UMEMOTO 	if (qstate->socket_failed != 0) {
121306a99fe3SHajimu UMEMOTO 		TRACE_OUT(query_socket_write);
121406a99fe3SHajimu UMEMOTO 		return (-1);
121506a99fe3SHajimu UMEMOTO 	}
121606a99fe3SHajimu UMEMOTO 
121706a99fe3SHajimu UMEMOTO 	result = write(qstate->sockfd, buf, nbytes);
121851d6ddb5SDag-Erling Smørgrav 	if (result < 0 || (size_t)result < nbytes)
121906a99fe3SHajimu UMEMOTO 		qstate->socket_failed = 1;
122006a99fe3SHajimu UMEMOTO 
122106a99fe3SHajimu UMEMOTO 	TRACE_OUT(query_socket_write);
122206a99fe3SHajimu UMEMOTO 	return (result);
122306a99fe3SHajimu UMEMOTO }
122406a99fe3SHajimu UMEMOTO 
122506a99fe3SHajimu UMEMOTO /*
122606a99fe3SHajimu UMEMOTO  * Initializes the query_state structure by filling it with the default values.
122706a99fe3SHajimu UMEMOTO  */
122806a99fe3SHajimu UMEMOTO struct query_state *
122906a99fe3SHajimu UMEMOTO init_query_state(int sockfd, size_t kevent_watermark, uid_t euid, gid_t egid)
123006a99fe3SHajimu UMEMOTO {
123106a99fe3SHajimu UMEMOTO 	struct query_state	*retval;
123206a99fe3SHajimu UMEMOTO 
123306a99fe3SHajimu UMEMOTO 	TRACE_IN(init_query_state);
12348eeaaffaSDag-Erling Smørgrav 	retval = calloc(1, sizeof(*retval));
123506a99fe3SHajimu UMEMOTO 	assert(retval != NULL);
123606a99fe3SHajimu UMEMOTO 
123706a99fe3SHajimu UMEMOTO 	retval->sockfd = sockfd;
123806a99fe3SHajimu UMEMOTO 	retval->kevent_filter = EVFILT_READ;
123906a99fe3SHajimu UMEMOTO 	retval->kevent_watermark = kevent_watermark;
124006a99fe3SHajimu UMEMOTO 
124106a99fe3SHajimu UMEMOTO 	retval->euid = euid;
124206a99fe3SHajimu UMEMOTO 	retval->egid = egid;
124306a99fe3SHajimu UMEMOTO 	retval->uid = retval->gid = -1;
124406a99fe3SHajimu UMEMOTO 
124506a99fe3SHajimu UMEMOTO 	if (asprintf(&retval->eid_str, "%d_%d_", retval->euid,
124606a99fe3SHajimu UMEMOTO 		retval->egid) == -1) {
124706a99fe3SHajimu UMEMOTO 		free(retval);
124806a99fe3SHajimu UMEMOTO 		return (NULL);
124906a99fe3SHajimu UMEMOTO 	}
125006a99fe3SHajimu UMEMOTO 	retval->eid_str_length = strlen(retval->eid_str);
125106a99fe3SHajimu UMEMOTO 
125206a99fe3SHajimu UMEMOTO 	init_comm_element(&retval->request, CET_UNDEFINED);
125306a99fe3SHajimu UMEMOTO 	init_comm_element(&retval->response, CET_UNDEFINED);
125406a99fe3SHajimu UMEMOTO 	retval->process_func = on_query_startup;
125506a99fe3SHajimu UMEMOTO 	retval->destroy_func = on_query_destroy;
125606a99fe3SHajimu UMEMOTO 
125706a99fe3SHajimu UMEMOTO 	retval->write_func = query_socket_write;
125806a99fe3SHajimu UMEMOTO 	retval->read_func = query_socket_read;
125906a99fe3SHajimu UMEMOTO 
126006a99fe3SHajimu UMEMOTO 	get_time_func(&retval->creation_time);
126123c7e79aSJohn Baldwin 	retval->timeout.tv_sec = s_configuration->query_timeout;
126223c7e79aSJohn Baldwin 	retval->timeout.tv_usec = 0;
126306a99fe3SHajimu UMEMOTO 
126406a99fe3SHajimu UMEMOTO 	TRACE_OUT(init_query_state);
126506a99fe3SHajimu UMEMOTO 	return (retval);
126606a99fe3SHajimu UMEMOTO }
126706a99fe3SHajimu UMEMOTO 
126806a99fe3SHajimu UMEMOTO void
126906a99fe3SHajimu UMEMOTO destroy_query_state(struct query_state *qstate)
127006a99fe3SHajimu UMEMOTO {
127106a99fe3SHajimu UMEMOTO 
127206a99fe3SHajimu UMEMOTO 	TRACE_IN(destroy_query_state);
127306a99fe3SHajimu UMEMOTO 	if (qstate->eid_str != NULL)
127406a99fe3SHajimu UMEMOTO 	    free(qstate->eid_str);
127506a99fe3SHajimu UMEMOTO 
127606a99fe3SHajimu UMEMOTO 	if (qstate->io_buffer != NULL)
127706a99fe3SHajimu UMEMOTO 		free(qstate->io_buffer);
127806a99fe3SHajimu UMEMOTO 
127906a99fe3SHajimu UMEMOTO 	qstate->destroy_func(qstate);
128006a99fe3SHajimu UMEMOTO 	free(qstate);
128106a99fe3SHajimu UMEMOTO 	TRACE_OUT(destroy_query_state);
128206a99fe3SHajimu UMEMOTO }
1283