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