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