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