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/types.h> 2928f805ceSDag-Erling Smørgrav #include <sys/event.h> 3006a99fe3SHajimu UMEMOTO #include <sys/socket.h> 3106a99fe3SHajimu UMEMOTO #include <sys/time.h> 3228f805ceSDag-Erling Smørgrav 3306a99fe3SHajimu UMEMOTO #include <assert.h> 3406a99fe3SHajimu UMEMOTO #include <errno.h> 3506a99fe3SHajimu UMEMOTO #include <nsswitch.h> 3606a99fe3SHajimu UMEMOTO #include <stdio.h> 3706a99fe3SHajimu UMEMOTO #include <stdlib.h> 3806a99fe3SHajimu UMEMOTO #include <string.h> 3928f805ceSDag-Erling Smørgrav #include <unistd.h> 4028f805ceSDag-Erling Smørgrav 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 81*ec8a394dSElyes Haouas * 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 { 155e86caa0bSDag-Erling Smørgrav union { 156e86caa0bSDag-Erling Smørgrav struct cmsghdr hdr; 157e86caa0bSDag-Erling Smørgrav char pad[CMSG_SPACE(sizeof(struct cmsgcred))]; 158e86caa0bSDag-Erling Smørgrav } cmsg; 159e86caa0bSDag-Erling Smørgrav struct msghdr mhdr; 16006a99fe3SHajimu UMEMOTO struct iovec iov; 161b947683cSHajimu UMEMOTO struct cmsgcred *cred; 16206a99fe3SHajimu UMEMOTO int elem_type; 16306a99fe3SHajimu UMEMOTO 16406a99fe3SHajimu UMEMOTO TRACE_IN(on_query_startup); 16506a99fe3SHajimu UMEMOTO assert(qstate != NULL); 16606a99fe3SHajimu UMEMOTO 167e86caa0bSDag-Erling Smørgrav memset(&mhdr, 0, sizeof(mhdr)); 168e86caa0bSDag-Erling Smørgrav mhdr.msg_iov = &iov; 169e86caa0bSDag-Erling Smørgrav mhdr.msg_iovlen = 1; 170e86caa0bSDag-Erling Smørgrav mhdr.msg_control = &cmsg; 171e86caa0bSDag-Erling Smørgrav mhdr.msg_controllen = sizeof(cmsg); 17206a99fe3SHajimu UMEMOTO 173e86caa0bSDag-Erling Smørgrav memset(&iov, 0, sizeof(iov)); 17406a99fe3SHajimu UMEMOTO iov.iov_base = &elem_type; 175e86caa0bSDag-Erling Smørgrav iov.iov_len = sizeof(elem_type); 17606a99fe3SHajimu UMEMOTO 177e86caa0bSDag-Erling Smørgrav if (recvmsg(qstate->sockfd, &mhdr, 0) == -1) { 17806a99fe3SHajimu UMEMOTO TRACE_OUT(on_query_startup); 17906a99fe3SHajimu UMEMOTO return (-1); 18006a99fe3SHajimu UMEMOTO } 18106a99fe3SHajimu UMEMOTO 182e86caa0bSDag-Erling Smørgrav if (mhdr.msg_controllen != CMSG_SPACE(sizeof(struct cmsgcred)) || 183e86caa0bSDag-Erling Smørgrav cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(struct cmsgcred)) || 184e86caa0bSDag-Erling Smørgrav cmsg.hdr.cmsg_level != SOL_SOCKET || 185e86caa0bSDag-Erling Smørgrav 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 3358eeaaffaSDag-Erling Smørgrav write_request->entry = calloc(1, 33606a99fe3SHajimu UMEMOTO write_request->entry_length + 1); 33706a99fe3SHajimu UMEMOTO assert(write_request->entry != NULL); 33806a99fe3SHajimu UMEMOTO 3398eeaaffaSDag-Erling Smørgrav write_request->cache_key = calloc(1, 34006a99fe3SHajimu UMEMOTO write_request->cache_key_size + 34106a99fe3SHajimu UMEMOTO qstate->eid_str_length); 34206a99fe3SHajimu UMEMOTO assert(write_request->cache_key != NULL); 34306a99fe3SHajimu UMEMOTO memcpy(write_request->cache_key, qstate->eid_str, 34406a99fe3SHajimu UMEMOTO qstate->eid_str_length); 34506a99fe3SHajimu UMEMOTO 34606a99fe3SHajimu UMEMOTO if (write_request->data_size != 0) { 3478eeaaffaSDag-Erling Smørgrav write_request->data = calloc(1, 34806a99fe3SHajimu UMEMOTO write_request->data_size); 34906a99fe3SHajimu UMEMOTO assert(write_request->data != NULL); 35006a99fe3SHajimu UMEMOTO } 35106a99fe3SHajimu UMEMOTO 35206a99fe3SHajimu UMEMOTO qstate->kevent_watermark = write_request->entry_length + 35306a99fe3SHajimu UMEMOTO write_request->cache_key_size + 35406a99fe3SHajimu UMEMOTO write_request->data_size; 35506a99fe3SHajimu UMEMOTO qstate->process_func = on_write_request_read2; 35606a99fe3SHajimu UMEMOTO } 35706a99fe3SHajimu UMEMOTO 35806a99fe3SHajimu UMEMOTO TRACE_OUT(on_write_request_read1); 35906a99fe3SHajimu UMEMOTO return (0); 36006a99fe3SHajimu UMEMOTO } 36106a99fe3SHajimu UMEMOTO 36206a99fe3SHajimu UMEMOTO static int 36306a99fe3SHajimu UMEMOTO on_write_request_read2(struct query_state *qstate) 36406a99fe3SHajimu UMEMOTO { 36506a99fe3SHajimu UMEMOTO struct cache_write_request *write_request; 36606a99fe3SHajimu UMEMOTO ssize_t result; 36706a99fe3SHajimu UMEMOTO 36806a99fe3SHajimu UMEMOTO TRACE_IN(on_write_request_read2); 36906a99fe3SHajimu UMEMOTO write_request = get_cache_write_request(&qstate->request); 37006a99fe3SHajimu UMEMOTO 37106a99fe3SHajimu UMEMOTO result = qstate->read_func(qstate, write_request->entry, 37206a99fe3SHajimu UMEMOTO write_request->entry_length); 37306a99fe3SHajimu UMEMOTO result += qstate->read_func(qstate, write_request->cache_key + 37406a99fe3SHajimu UMEMOTO qstate->eid_str_length, write_request->cache_key_size); 37506a99fe3SHajimu UMEMOTO if (write_request->data_size != 0) 37606a99fe3SHajimu UMEMOTO result += qstate->read_func(qstate, write_request->data, 37706a99fe3SHajimu UMEMOTO write_request->data_size); 37806a99fe3SHajimu UMEMOTO 37951d6ddb5SDag-Erling Smørgrav if (result != (ssize_t)qstate->kevent_watermark) { 38006a99fe3SHajimu UMEMOTO TRACE_OUT(on_write_request_read2); 38106a99fe3SHajimu UMEMOTO return (-1); 38206a99fe3SHajimu UMEMOTO } 38306a99fe3SHajimu UMEMOTO write_request->cache_key_size += qstate->eid_str_length; 38406a99fe3SHajimu UMEMOTO 38506a99fe3SHajimu UMEMOTO qstate->kevent_watermark = 0; 38606a99fe3SHajimu UMEMOTO if (write_request->data_size != 0) 38706a99fe3SHajimu UMEMOTO qstate->process_func = on_write_request_process; 38806a99fe3SHajimu UMEMOTO else 38906a99fe3SHajimu UMEMOTO qstate->process_func = on_negative_write_request_process; 39006a99fe3SHajimu UMEMOTO TRACE_OUT(on_write_request_read2); 39106a99fe3SHajimu UMEMOTO return (0); 39206a99fe3SHajimu UMEMOTO } 39306a99fe3SHajimu UMEMOTO 39406a99fe3SHajimu UMEMOTO static int 39506a99fe3SHajimu UMEMOTO on_write_request_process(struct query_state *qstate) 39606a99fe3SHajimu UMEMOTO { 39706a99fe3SHajimu UMEMOTO struct cache_write_request *write_request; 39806a99fe3SHajimu UMEMOTO struct cache_write_response *write_response; 39906a99fe3SHajimu UMEMOTO cache_entry c_entry; 40006a99fe3SHajimu UMEMOTO 40106a99fe3SHajimu UMEMOTO TRACE_IN(on_write_request_process); 40206a99fe3SHajimu UMEMOTO init_comm_element(&qstate->response, CET_WRITE_RESPONSE); 40306a99fe3SHajimu UMEMOTO write_response = get_cache_write_response(&qstate->response); 40406a99fe3SHajimu UMEMOTO write_request = get_cache_write_request(&qstate->request); 40506a99fe3SHajimu UMEMOTO 40606a99fe3SHajimu UMEMOTO qstate->config_entry = configuration_find_entry( 40706a99fe3SHajimu UMEMOTO s_configuration, write_request->entry); 40806a99fe3SHajimu UMEMOTO 40906a99fe3SHajimu UMEMOTO if (qstate->config_entry == NULL) { 41006a99fe3SHajimu UMEMOTO write_response->error_code = ENOENT; 41106a99fe3SHajimu UMEMOTO 41206a99fe3SHajimu UMEMOTO LOG_ERR_2("write_request", "can't find configuration" 41306a99fe3SHajimu UMEMOTO " entry '%s'. aborting request", write_request->entry); 41406a99fe3SHajimu UMEMOTO goto fin; 41506a99fe3SHajimu UMEMOTO } 41606a99fe3SHajimu UMEMOTO 41706a99fe3SHajimu UMEMOTO if (qstate->config_entry->enabled == 0) { 41806a99fe3SHajimu UMEMOTO write_response->error_code = EACCES; 41906a99fe3SHajimu UMEMOTO 42006a99fe3SHajimu UMEMOTO LOG_ERR_2("write_request", 42106a99fe3SHajimu UMEMOTO "configuration entry '%s' is disabled", 42206a99fe3SHajimu UMEMOTO write_request->entry); 42306a99fe3SHajimu UMEMOTO goto fin; 42406a99fe3SHajimu UMEMOTO } 42506a99fe3SHajimu UMEMOTO 42606a99fe3SHajimu UMEMOTO if (qstate->config_entry->perform_actual_lookups != 0) { 42706a99fe3SHajimu UMEMOTO write_response->error_code = EOPNOTSUPP; 42806a99fe3SHajimu UMEMOTO 42906a99fe3SHajimu UMEMOTO LOG_ERR_2("write_request", 43006a99fe3SHajimu UMEMOTO "entry '%s' performs lookups by itself: " 43106a99fe3SHajimu UMEMOTO "can't write to it", write_request->entry); 43206a99fe3SHajimu UMEMOTO goto fin; 43306a99fe3SHajimu UMEMOTO } 43406a99fe3SHajimu UMEMOTO 43506a99fe3SHajimu UMEMOTO configuration_lock_rdlock(s_configuration); 43606a99fe3SHajimu UMEMOTO c_entry = find_cache_entry(s_cache, 43727f2bc9eSDag-Erling Smørgrav qstate->config_entry->positive_cache_params.cep.entry_name); 43806a99fe3SHajimu UMEMOTO configuration_unlock(s_configuration); 43906a99fe3SHajimu UMEMOTO if (c_entry != NULL) { 44006a99fe3SHajimu UMEMOTO configuration_lock_entry(qstate->config_entry, CELT_POSITIVE); 44106a99fe3SHajimu UMEMOTO qstate->config_entry->positive_cache_entry = c_entry; 44206a99fe3SHajimu UMEMOTO write_response->error_code = cache_write(c_entry, 44306a99fe3SHajimu UMEMOTO write_request->cache_key, 44406a99fe3SHajimu UMEMOTO write_request->cache_key_size, 44506a99fe3SHajimu UMEMOTO write_request->data, 44606a99fe3SHajimu UMEMOTO write_request->data_size); 44706a99fe3SHajimu UMEMOTO configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE); 44806a99fe3SHajimu UMEMOTO 44906a99fe3SHajimu UMEMOTO if ((qstate->config_entry->common_query_timeout.tv_sec != 0) || 45006a99fe3SHajimu UMEMOTO (qstate->config_entry->common_query_timeout.tv_usec != 0)) 45106a99fe3SHajimu UMEMOTO memcpy(&qstate->timeout, 45206a99fe3SHajimu UMEMOTO &qstate->config_entry->common_query_timeout, 45306a99fe3SHajimu UMEMOTO sizeof(struct timeval)); 45406a99fe3SHajimu UMEMOTO 45506a99fe3SHajimu UMEMOTO } else 45606a99fe3SHajimu UMEMOTO write_response->error_code = -1; 45706a99fe3SHajimu UMEMOTO 45806a99fe3SHajimu UMEMOTO fin: 45906a99fe3SHajimu UMEMOTO qstate->kevent_filter = EVFILT_WRITE; 46006a99fe3SHajimu UMEMOTO qstate->kevent_watermark = sizeof(int); 46106a99fe3SHajimu UMEMOTO qstate->process_func = on_write_response_write1; 46206a99fe3SHajimu UMEMOTO 46306a99fe3SHajimu UMEMOTO TRACE_OUT(on_write_request_process); 46406a99fe3SHajimu UMEMOTO return (0); 46506a99fe3SHajimu UMEMOTO } 46606a99fe3SHajimu UMEMOTO 46706a99fe3SHajimu UMEMOTO static int 46806a99fe3SHajimu UMEMOTO on_negative_write_request_process(struct query_state *qstate) 46906a99fe3SHajimu UMEMOTO { 47006a99fe3SHajimu UMEMOTO struct cache_write_request *write_request; 47106a99fe3SHajimu UMEMOTO struct cache_write_response *write_response; 47206a99fe3SHajimu UMEMOTO cache_entry c_entry; 47306a99fe3SHajimu UMEMOTO 47406a99fe3SHajimu UMEMOTO TRACE_IN(on_negative_write_request_process); 47506a99fe3SHajimu UMEMOTO init_comm_element(&qstate->response, CET_WRITE_RESPONSE); 47606a99fe3SHajimu UMEMOTO write_response = get_cache_write_response(&qstate->response); 47706a99fe3SHajimu UMEMOTO write_request = get_cache_write_request(&qstate->request); 47806a99fe3SHajimu UMEMOTO 47906a99fe3SHajimu UMEMOTO qstate->config_entry = configuration_find_entry ( 48006a99fe3SHajimu UMEMOTO s_configuration, write_request->entry); 48106a99fe3SHajimu UMEMOTO 48206a99fe3SHajimu UMEMOTO if (qstate->config_entry == NULL) { 48306a99fe3SHajimu UMEMOTO write_response->error_code = ENOENT; 48406a99fe3SHajimu UMEMOTO 48506a99fe3SHajimu UMEMOTO LOG_ERR_2("negative_write_request", 48606a99fe3SHajimu UMEMOTO "can't find configuration" 48706a99fe3SHajimu UMEMOTO " entry '%s'. aborting request", write_request->entry); 48806a99fe3SHajimu UMEMOTO goto fin; 48906a99fe3SHajimu UMEMOTO } 49006a99fe3SHajimu UMEMOTO 49106a99fe3SHajimu UMEMOTO if (qstate->config_entry->enabled == 0) { 49206a99fe3SHajimu UMEMOTO write_response->error_code = EACCES; 49306a99fe3SHajimu UMEMOTO 49406a99fe3SHajimu UMEMOTO LOG_ERR_2("negative_write_request", 49506a99fe3SHajimu UMEMOTO "configuration entry '%s' is disabled", 49606a99fe3SHajimu UMEMOTO write_request->entry); 49706a99fe3SHajimu UMEMOTO goto fin; 49806a99fe3SHajimu UMEMOTO } 49906a99fe3SHajimu UMEMOTO 50006a99fe3SHajimu UMEMOTO if (qstate->config_entry->perform_actual_lookups != 0) { 50106a99fe3SHajimu UMEMOTO write_response->error_code = EOPNOTSUPP; 50206a99fe3SHajimu UMEMOTO 50306a99fe3SHajimu UMEMOTO LOG_ERR_2("negative_write_request", 50406a99fe3SHajimu UMEMOTO "entry '%s' performs lookups by itself: " 50506a99fe3SHajimu UMEMOTO "can't write to it", write_request->entry); 50606a99fe3SHajimu UMEMOTO goto fin; 50706a99fe3SHajimu UMEMOTO } else { 508db1bdf2bSMichael Bushkov #ifdef NS_NSCD_EID_CHECKING 50906a99fe3SHajimu UMEMOTO if (check_query_eids(qstate) != 0) { 51006a99fe3SHajimu UMEMOTO write_response->error_code = EPERM; 51106a99fe3SHajimu UMEMOTO goto fin; 51206a99fe3SHajimu UMEMOTO } 51306a99fe3SHajimu UMEMOTO #endif 51406a99fe3SHajimu UMEMOTO } 51506a99fe3SHajimu UMEMOTO 51606a99fe3SHajimu UMEMOTO configuration_lock_rdlock(s_configuration); 51706a99fe3SHajimu UMEMOTO c_entry = find_cache_entry(s_cache, 51827f2bc9eSDag-Erling Smørgrav qstate->config_entry->negative_cache_params.cep.entry_name); 51906a99fe3SHajimu UMEMOTO configuration_unlock(s_configuration); 52006a99fe3SHajimu UMEMOTO if (c_entry != NULL) { 52106a99fe3SHajimu UMEMOTO configuration_lock_entry(qstate->config_entry, CELT_NEGATIVE); 52206a99fe3SHajimu UMEMOTO qstate->config_entry->negative_cache_entry = c_entry; 52306a99fe3SHajimu UMEMOTO write_response->error_code = cache_write(c_entry, 52406a99fe3SHajimu UMEMOTO write_request->cache_key, 52506a99fe3SHajimu UMEMOTO write_request->cache_key_size, 52606a99fe3SHajimu UMEMOTO negative_data, 52706a99fe3SHajimu UMEMOTO sizeof(negative_data)); 52806a99fe3SHajimu UMEMOTO configuration_unlock_entry(qstate->config_entry, CELT_NEGATIVE); 52906a99fe3SHajimu UMEMOTO 53006a99fe3SHajimu UMEMOTO if ((qstate->config_entry->common_query_timeout.tv_sec != 0) || 53106a99fe3SHajimu UMEMOTO (qstate->config_entry->common_query_timeout.tv_usec != 0)) 53206a99fe3SHajimu UMEMOTO memcpy(&qstate->timeout, 53306a99fe3SHajimu UMEMOTO &qstate->config_entry->common_query_timeout, 53406a99fe3SHajimu UMEMOTO sizeof(struct timeval)); 53506a99fe3SHajimu UMEMOTO } else 53606a99fe3SHajimu UMEMOTO write_response->error_code = -1; 53706a99fe3SHajimu UMEMOTO 53806a99fe3SHajimu UMEMOTO fin: 53906a99fe3SHajimu UMEMOTO qstate->kevent_filter = EVFILT_WRITE; 54006a99fe3SHajimu UMEMOTO qstate->kevent_watermark = sizeof(int); 54106a99fe3SHajimu UMEMOTO qstate->process_func = on_write_response_write1; 54206a99fe3SHajimu UMEMOTO 54306a99fe3SHajimu UMEMOTO TRACE_OUT(on_negative_write_request_process); 54406a99fe3SHajimu UMEMOTO return (0); 54506a99fe3SHajimu UMEMOTO } 54606a99fe3SHajimu UMEMOTO 54706a99fe3SHajimu UMEMOTO static int 54806a99fe3SHajimu UMEMOTO on_write_response_write1(struct query_state *qstate) 54906a99fe3SHajimu UMEMOTO { 55006a99fe3SHajimu UMEMOTO struct cache_write_response *write_response; 55106a99fe3SHajimu UMEMOTO ssize_t result; 55206a99fe3SHajimu UMEMOTO 55306a99fe3SHajimu UMEMOTO TRACE_IN(on_write_response_write1); 55406a99fe3SHajimu UMEMOTO write_response = get_cache_write_response(&qstate->response); 55506a99fe3SHajimu UMEMOTO result = qstate->write_func(qstate, &write_response->error_code, 55606a99fe3SHajimu UMEMOTO sizeof(int)); 55706a99fe3SHajimu UMEMOTO if (result != sizeof(int)) { 55806a99fe3SHajimu UMEMOTO TRACE_OUT(on_write_response_write1); 55906a99fe3SHajimu UMEMOTO return (-1); 56006a99fe3SHajimu UMEMOTO } 56106a99fe3SHajimu UMEMOTO 56206a99fe3SHajimu UMEMOTO finalize_comm_element(&qstate->request); 56306a99fe3SHajimu UMEMOTO finalize_comm_element(&qstate->response); 56406a99fe3SHajimu UMEMOTO 56506a99fe3SHajimu UMEMOTO qstate->kevent_watermark = sizeof(int); 56606a99fe3SHajimu UMEMOTO qstate->kevent_filter = EVFILT_READ; 56706a99fe3SHajimu UMEMOTO qstate->process_func = on_rw_mapper; 56806a99fe3SHajimu UMEMOTO 56906a99fe3SHajimu UMEMOTO TRACE_OUT(on_write_response_write1); 57006a99fe3SHajimu UMEMOTO return (0); 57106a99fe3SHajimu UMEMOTO } 57206a99fe3SHajimu UMEMOTO 57306a99fe3SHajimu UMEMOTO /* 57406a99fe3SHajimu UMEMOTO * The functions below are used to process read requests. 57506a99fe3SHajimu UMEMOTO * - on_read_request_read1 and on_read_request_read2 read the request itself 57606a99fe3SHajimu UMEMOTO * - on_read_request_process processes it 57706a99fe3SHajimu UMEMOTO * - on_read_response_write1 and on_read_response_write2 send the response 57806a99fe3SHajimu UMEMOTO */ 57906a99fe3SHajimu UMEMOTO static int 58006a99fe3SHajimu UMEMOTO on_read_request_read1(struct query_state *qstate) 58106a99fe3SHajimu UMEMOTO { 58206a99fe3SHajimu UMEMOTO struct cache_read_request *read_request; 58306a99fe3SHajimu UMEMOTO ssize_t result; 58406a99fe3SHajimu UMEMOTO 58506a99fe3SHajimu UMEMOTO TRACE_IN(on_read_request_read1); 58606a99fe3SHajimu UMEMOTO if (qstate->kevent_watermark == 0) 58706a99fe3SHajimu UMEMOTO qstate->kevent_watermark = sizeof(size_t) * 2; 58806a99fe3SHajimu UMEMOTO else { 58906a99fe3SHajimu UMEMOTO init_comm_element(&qstate->request, CET_READ_REQUEST); 59006a99fe3SHajimu UMEMOTO read_request = get_cache_read_request(&qstate->request); 59106a99fe3SHajimu UMEMOTO 59206a99fe3SHajimu UMEMOTO result = qstate->read_func(qstate, 59306a99fe3SHajimu UMEMOTO &read_request->entry_length, sizeof(size_t)); 59406a99fe3SHajimu UMEMOTO result += qstate->read_func(qstate, 59506a99fe3SHajimu UMEMOTO &read_request->cache_key_size, sizeof(size_t)); 59606a99fe3SHajimu UMEMOTO 59706a99fe3SHajimu UMEMOTO if (result != sizeof(size_t) * 2) { 59806a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_request_read1); 59906a99fe3SHajimu UMEMOTO return (-1); 60006a99fe3SHajimu UMEMOTO } 60106a99fe3SHajimu UMEMOTO 60206a99fe3SHajimu UMEMOTO if (BUFSIZE_INVALID(read_request->entry_length) || 60306a99fe3SHajimu UMEMOTO BUFSIZE_INVALID(read_request->cache_key_size)) { 60406a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_request_read1); 60506a99fe3SHajimu UMEMOTO return (-1); 60606a99fe3SHajimu UMEMOTO } 60706a99fe3SHajimu UMEMOTO 6088eeaaffaSDag-Erling Smørgrav read_request->entry = calloc(1, 60906a99fe3SHajimu UMEMOTO read_request->entry_length + 1); 61006a99fe3SHajimu UMEMOTO assert(read_request->entry != NULL); 61106a99fe3SHajimu UMEMOTO 6128eeaaffaSDag-Erling Smørgrav read_request->cache_key = calloc(1, 61306a99fe3SHajimu UMEMOTO read_request->cache_key_size + 61406a99fe3SHajimu UMEMOTO qstate->eid_str_length); 61506a99fe3SHajimu UMEMOTO assert(read_request->cache_key != NULL); 61606a99fe3SHajimu UMEMOTO memcpy(read_request->cache_key, qstate->eid_str, 61706a99fe3SHajimu UMEMOTO qstate->eid_str_length); 61806a99fe3SHajimu UMEMOTO 61906a99fe3SHajimu UMEMOTO qstate->kevent_watermark = read_request->entry_length + 62006a99fe3SHajimu UMEMOTO read_request->cache_key_size; 62106a99fe3SHajimu UMEMOTO qstate->process_func = on_read_request_read2; 62206a99fe3SHajimu UMEMOTO } 62306a99fe3SHajimu UMEMOTO 62406a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_request_read1); 62506a99fe3SHajimu UMEMOTO return (0); 62606a99fe3SHajimu UMEMOTO } 62706a99fe3SHajimu UMEMOTO 62806a99fe3SHajimu UMEMOTO static int 62906a99fe3SHajimu UMEMOTO on_read_request_read2(struct query_state *qstate) 63006a99fe3SHajimu UMEMOTO { 63106a99fe3SHajimu UMEMOTO struct cache_read_request *read_request; 63206a99fe3SHajimu UMEMOTO ssize_t result; 63306a99fe3SHajimu UMEMOTO 63406a99fe3SHajimu UMEMOTO TRACE_IN(on_read_request_read2); 63506a99fe3SHajimu UMEMOTO read_request = get_cache_read_request(&qstate->request); 63606a99fe3SHajimu UMEMOTO 63706a99fe3SHajimu UMEMOTO result = qstate->read_func(qstate, read_request->entry, 63806a99fe3SHajimu UMEMOTO read_request->entry_length); 63906a99fe3SHajimu UMEMOTO result += qstate->read_func(qstate, 64006a99fe3SHajimu UMEMOTO read_request->cache_key + qstate->eid_str_length, 64106a99fe3SHajimu UMEMOTO read_request->cache_key_size); 64206a99fe3SHajimu UMEMOTO 64351d6ddb5SDag-Erling Smørgrav if (result != (ssize_t)qstate->kevent_watermark) { 64406a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_request_read2); 64506a99fe3SHajimu UMEMOTO return (-1); 64606a99fe3SHajimu UMEMOTO } 64706a99fe3SHajimu UMEMOTO read_request->cache_key_size += qstate->eid_str_length; 64806a99fe3SHajimu UMEMOTO 64906a99fe3SHajimu UMEMOTO qstate->kevent_watermark = 0; 65006a99fe3SHajimu UMEMOTO qstate->process_func = on_read_request_process; 65106a99fe3SHajimu UMEMOTO 65206a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_request_read2); 65306a99fe3SHajimu UMEMOTO return (0); 65406a99fe3SHajimu UMEMOTO } 65506a99fe3SHajimu UMEMOTO 65606a99fe3SHajimu UMEMOTO static int 65706a99fe3SHajimu UMEMOTO on_read_request_process(struct query_state *qstate) 65806a99fe3SHajimu UMEMOTO { 65906a99fe3SHajimu UMEMOTO struct cache_read_request *read_request; 66006a99fe3SHajimu UMEMOTO struct cache_read_response *read_response; 66106a99fe3SHajimu UMEMOTO cache_entry c_entry, neg_c_entry; 66206a99fe3SHajimu UMEMOTO 66306a99fe3SHajimu UMEMOTO struct agent *lookup_agent; 66406a99fe3SHajimu UMEMOTO struct common_agent *c_agent; 66506a99fe3SHajimu UMEMOTO int res; 66606a99fe3SHajimu UMEMOTO 66706a99fe3SHajimu UMEMOTO TRACE_IN(on_read_request_process); 66806a99fe3SHajimu UMEMOTO init_comm_element(&qstate->response, CET_READ_RESPONSE); 66906a99fe3SHajimu UMEMOTO read_response = get_cache_read_response(&qstate->response); 67006a99fe3SHajimu UMEMOTO read_request = get_cache_read_request(&qstate->request); 67106a99fe3SHajimu UMEMOTO 67206a99fe3SHajimu UMEMOTO qstate->config_entry = configuration_find_entry( 67306a99fe3SHajimu UMEMOTO s_configuration, read_request->entry); 67406a99fe3SHajimu UMEMOTO if (qstate->config_entry == NULL) { 67506a99fe3SHajimu UMEMOTO read_response->error_code = ENOENT; 67606a99fe3SHajimu UMEMOTO 67706a99fe3SHajimu UMEMOTO LOG_ERR_2("read_request", 67806a99fe3SHajimu UMEMOTO "can't find configuration " 67906a99fe3SHajimu UMEMOTO "entry '%s'. aborting request", read_request->entry); 68006a99fe3SHajimu UMEMOTO goto fin; 68106a99fe3SHajimu UMEMOTO } 68206a99fe3SHajimu UMEMOTO 68306a99fe3SHajimu UMEMOTO if (qstate->config_entry->enabled == 0) { 68406a99fe3SHajimu UMEMOTO read_response->error_code = EACCES; 68506a99fe3SHajimu UMEMOTO 68606a99fe3SHajimu UMEMOTO LOG_ERR_2("read_request", 68706a99fe3SHajimu UMEMOTO "configuration entry '%s' is disabled", 68806a99fe3SHajimu UMEMOTO read_request->entry); 68906a99fe3SHajimu UMEMOTO goto fin; 69006a99fe3SHajimu UMEMOTO } 69106a99fe3SHajimu UMEMOTO 69206a99fe3SHajimu UMEMOTO /* 69306a99fe3SHajimu UMEMOTO * if we perform lookups by ourselves, then we don't need to separate 69406a99fe3SHajimu UMEMOTO * cache entries by euid and egid 69506a99fe3SHajimu UMEMOTO */ 69606a99fe3SHajimu UMEMOTO if (qstate->config_entry->perform_actual_lookups != 0) 69706a99fe3SHajimu UMEMOTO memset(read_request->cache_key, 0, qstate->eid_str_length); 69806a99fe3SHajimu UMEMOTO else { 699db1bdf2bSMichael Bushkov #ifdef NS_NSCD_EID_CHECKING 70006a99fe3SHajimu UMEMOTO if (check_query_eids(qstate) != 0) { 70106a99fe3SHajimu UMEMOTO /* if the lookup is not self-performing, we check for clients euid/egid */ 70206a99fe3SHajimu UMEMOTO read_response->error_code = EPERM; 70306a99fe3SHajimu UMEMOTO goto fin; 70406a99fe3SHajimu UMEMOTO } 70506a99fe3SHajimu UMEMOTO #endif 70606a99fe3SHajimu UMEMOTO } 70706a99fe3SHajimu UMEMOTO 70806a99fe3SHajimu UMEMOTO configuration_lock_rdlock(s_configuration); 70906a99fe3SHajimu UMEMOTO c_entry = find_cache_entry(s_cache, 71027f2bc9eSDag-Erling Smørgrav qstate->config_entry->positive_cache_params.cep.entry_name); 71106a99fe3SHajimu UMEMOTO neg_c_entry = find_cache_entry(s_cache, 71227f2bc9eSDag-Erling Smørgrav qstate->config_entry->negative_cache_params.cep.entry_name); 71306a99fe3SHajimu UMEMOTO configuration_unlock(s_configuration); 71406a99fe3SHajimu UMEMOTO if ((c_entry != NULL) && (neg_c_entry != NULL)) { 71506a99fe3SHajimu UMEMOTO configuration_lock_entry(qstate->config_entry, CELT_POSITIVE); 71606a99fe3SHajimu UMEMOTO qstate->config_entry->positive_cache_entry = c_entry; 71706a99fe3SHajimu UMEMOTO read_response->error_code = cache_read(c_entry, 71806a99fe3SHajimu UMEMOTO read_request->cache_key, 71906a99fe3SHajimu UMEMOTO read_request->cache_key_size, NULL, 72006a99fe3SHajimu UMEMOTO &read_response->data_size); 72106a99fe3SHajimu UMEMOTO 72206a99fe3SHajimu UMEMOTO if (read_response->error_code == -2) { 7238eeaaffaSDag-Erling Smørgrav read_response->data = malloc( 72406a99fe3SHajimu UMEMOTO read_response->data_size); 72512326285SCy Schubert assert(read_response->data != NULL); 72606a99fe3SHajimu UMEMOTO read_response->error_code = cache_read(c_entry, 72706a99fe3SHajimu UMEMOTO read_request->cache_key, 72806a99fe3SHajimu UMEMOTO read_request->cache_key_size, 72906a99fe3SHajimu UMEMOTO read_response->data, 73006a99fe3SHajimu UMEMOTO &read_response->data_size); 73106a99fe3SHajimu UMEMOTO } 73206a99fe3SHajimu UMEMOTO configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE); 73306a99fe3SHajimu UMEMOTO 73406a99fe3SHajimu UMEMOTO configuration_lock_entry(qstate->config_entry, CELT_NEGATIVE); 73506a99fe3SHajimu UMEMOTO qstate->config_entry->negative_cache_entry = neg_c_entry; 73606a99fe3SHajimu UMEMOTO if (read_response->error_code == -1) { 73706a99fe3SHajimu UMEMOTO read_response->error_code = cache_read(neg_c_entry, 73806a99fe3SHajimu UMEMOTO read_request->cache_key, 73906a99fe3SHajimu UMEMOTO read_request->cache_key_size, NULL, 74006a99fe3SHajimu UMEMOTO &read_response->data_size); 74106a99fe3SHajimu UMEMOTO 74206a99fe3SHajimu UMEMOTO if (read_response->error_code == -2) { 7438af0c00bSCy Schubert read_response->data = malloc( 7448af0c00bSCy Schubert read_response->data_size); 74512326285SCy Schubert assert(read_response->data != NULL); 7468af0c00bSCy Schubert read_response->error_code = cache_read(neg_c_entry, 7478af0c00bSCy Schubert read_request->cache_key, 7488af0c00bSCy Schubert read_request->cache_key_size, 7498af0c00bSCy Schubert read_response->data, 7508af0c00bSCy Schubert &read_response->data_size); 75106a99fe3SHajimu UMEMOTO } 75206a99fe3SHajimu UMEMOTO } 75306a99fe3SHajimu UMEMOTO configuration_unlock_entry(qstate->config_entry, CELT_NEGATIVE); 75406a99fe3SHajimu UMEMOTO 75506a99fe3SHajimu UMEMOTO if ((read_response->error_code == -1) && 75606a99fe3SHajimu UMEMOTO (qstate->config_entry->perform_actual_lookups != 0)) { 75706a99fe3SHajimu UMEMOTO free(read_response->data); 75806a99fe3SHajimu UMEMOTO read_response->data = NULL; 75906a99fe3SHajimu UMEMOTO read_response->data_size = 0; 76006a99fe3SHajimu UMEMOTO 76106a99fe3SHajimu UMEMOTO lookup_agent = find_agent(s_agent_table, 76206a99fe3SHajimu UMEMOTO read_request->entry, COMMON_AGENT); 76306a99fe3SHajimu UMEMOTO 76406a99fe3SHajimu UMEMOTO if ((lookup_agent != NULL) && 76506a99fe3SHajimu UMEMOTO (lookup_agent->type == COMMON_AGENT)) { 76606a99fe3SHajimu UMEMOTO c_agent = (struct common_agent *)lookup_agent; 76706a99fe3SHajimu UMEMOTO res = c_agent->lookup_func( 76806a99fe3SHajimu UMEMOTO read_request->cache_key + 76906a99fe3SHajimu UMEMOTO qstate->eid_str_length, 77006a99fe3SHajimu UMEMOTO read_request->cache_key_size - 77106a99fe3SHajimu UMEMOTO qstate->eid_str_length, 77206a99fe3SHajimu UMEMOTO &read_response->data, 77306a99fe3SHajimu UMEMOTO &read_response->data_size); 77406a99fe3SHajimu UMEMOTO 77506a99fe3SHajimu UMEMOTO if (res == NS_SUCCESS) { 77606a99fe3SHajimu UMEMOTO read_response->error_code = 0; 77706a99fe3SHajimu UMEMOTO configuration_lock_entry( 77806a99fe3SHajimu UMEMOTO qstate->config_entry, 77906a99fe3SHajimu UMEMOTO CELT_POSITIVE); 78006a99fe3SHajimu UMEMOTO cache_write(c_entry, 78106a99fe3SHajimu UMEMOTO read_request->cache_key, 78206a99fe3SHajimu UMEMOTO read_request->cache_key_size, 78306a99fe3SHajimu UMEMOTO read_response->data, 78406a99fe3SHajimu UMEMOTO read_response->data_size); 78506a99fe3SHajimu UMEMOTO configuration_unlock_entry( 78606a99fe3SHajimu UMEMOTO qstate->config_entry, 78706a99fe3SHajimu UMEMOTO CELT_POSITIVE); 78806a99fe3SHajimu UMEMOTO } else if ((res == NS_NOTFOUND) || 78906a99fe3SHajimu UMEMOTO (res == NS_RETURN)) { 79006a99fe3SHajimu UMEMOTO configuration_lock_entry( 79106a99fe3SHajimu UMEMOTO qstate->config_entry, 79206a99fe3SHajimu UMEMOTO CELT_NEGATIVE); 79306a99fe3SHajimu UMEMOTO cache_write(neg_c_entry, 79406a99fe3SHajimu UMEMOTO read_request->cache_key, 79506a99fe3SHajimu UMEMOTO read_request->cache_key_size, 79606a99fe3SHajimu UMEMOTO negative_data, 79706a99fe3SHajimu UMEMOTO sizeof(negative_data)); 79806a99fe3SHajimu UMEMOTO configuration_unlock_entry( 79906a99fe3SHajimu UMEMOTO qstate->config_entry, 80006a99fe3SHajimu UMEMOTO CELT_NEGATIVE); 80106a99fe3SHajimu UMEMOTO 80206a99fe3SHajimu UMEMOTO read_response->error_code = 0; 80306a99fe3SHajimu UMEMOTO read_response->data = NULL; 80406a99fe3SHajimu UMEMOTO read_response->data_size = 0; 80506a99fe3SHajimu UMEMOTO } 80606a99fe3SHajimu UMEMOTO } 80706a99fe3SHajimu UMEMOTO } 80806a99fe3SHajimu UMEMOTO 80906a99fe3SHajimu UMEMOTO if ((qstate->config_entry->common_query_timeout.tv_sec != 0) || 81006a99fe3SHajimu UMEMOTO (qstate->config_entry->common_query_timeout.tv_usec != 0)) 81106a99fe3SHajimu UMEMOTO memcpy(&qstate->timeout, 81206a99fe3SHajimu UMEMOTO &qstate->config_entry->common_query_timeout, 81306a99fe3SHajimu UMEMOTO sizeof(struct timeval)); 81406a99fe3SHajimu UMEMOTO } else 81506a99fe3SHajimu UMEMOTO read_response->error_code = -1; 81606a99fe3SHajimu UMEMOTO 81706a99fe3SHajimu UMEMOTO fin: 81806a99fe3SHajimu UMEMOTO qstate->kevent_filter = EVFILT_WRITE; 81906a99fe3SHajimu UMEMOTO if (read_response->error_code == 0) 82006a99fe3SHajimu UMEMOTO qstate->kevent_watermark = sizeof(int) + sizeof(size_t); 82106a99fe3SHajimu UMEMOTO else 82206a99fe3SHajimu UMEMOTO qstate->kevent_watermark = sizeof(int); 82306a99fe3SHajimu UMEMOTO qstate->process_func = on_read_response_write1; 82406a99fe3SHajimu UMEMOTO 82506a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_request_process); 82606a99fe3SHajimu UMEMOTO return (0); 82706a99fe3SHajimu UMEMOTO } 82806a99fe3SHajimu UMEMOTO 82906a99fe3SHajimu UMEMOTO static int 83006a99fe3SHajimu UMEMOTO on_read_response_write1(struct query_state *qstate) 83106a99fe3SHajimu UMEMOTO { 83206a99fe3SHajimu UMEMOTO struct cache_read_response *read_response; 83306a99fe3SHajimu UMEMOTO ssize_t result; 83406a99fe3SHajimu UMEMOTO 83506a99fe3SHajimu UMEMOTO TRACE_IN(on_read_response_write1); 83606a99fe3SHajimu UMEMOTO read_response = get_cache_read_response(&qstate->response); 83706a99fe3SHajimu UMEMOTO 83806a99fe3SHajimu UMEMOTO result = qstate->write_func(qstate, &read_response->error_code, 83906a99fe3SHajimu UMEMOTO sizeof(int)); 84006a99fe3SHajimu UMEMOTO 84106a99fe3SHajimu UMEMOTO if (read_response->error_code == 0) { 84206a99fe3SHajimu UMEMOTO result += qstate->write_func(qstate, &read_response->data_size, 84306a99fe3SHajimu UMEMOTO sizeof(size_t)); 84451d6ddb5SDag-Erling Smørgrav if (result != (ssize_t)qstate->kevent_watermark) { 84506a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_response_write1); 84606a99fe3SHajimu UMEMOTO return (-1); 84706a99fe3SHajimu UMEMOTO } 84806a99fe3SHajimu UMEMOTO 84906a99fe3SHajimu UMEMOTO qstate->kevent_watermark = read_response->data_size; 85006a99fe3SHajimu UMEMOTO qstate->process_func = on_read_response_write2; 85106a99fe3SHajimu UMEMOTO } else { 85251d6ddb5SDag-Erling Smørgrav if (result != (ssize_t)qstate->kevent_watermark) { 85306a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_response_write1); 85406a99fe3SHajimu UMEMOTO return (-1); 85506a99fe3SHajimu UMEMOTO } 85606a99fe3SHajimu UMEMOTO 85706a99fe3SHajimu UMEMOTO qstate->kevent_watermark = 0; 85806a99fe3SHajimu UMEMOTO qstate->process_func = NULL; 85906a99fe3SHajimu UMEMOTO } 86006a99fe3SHajimu UMEMOTO 86106a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_response_write1); 86206a99fe3SHajimu UMEMOTO return (0); 86306a99fe3SHajimu UMEMOTO } 86406a99fe3SHajimu UMEMOTO 86506a99fe3SHajimu UMEMOTO static int 86606a99fe3SHajimu UMEMOTO on_read_response_write2(struct query_state *qstate) 86706a99fe3SHajimu UMEMOTO { 86806a99fe3SHajimu UMEMOTO struct cache_read_response *read_response; 86906a99fe3SHajimu UMEMOTO ssize_t result; 87006a99fe3SHajimu UMEMOTO 87106a99fe3SHajimu UMEMOTO TRACE_IN(on_read_response_write2); 87206a99fe3SHajimu UMEMOTO read_response = get_cache_read_response(&qstate->response); 87306a99fe3SHajimu UMEMOTO if (read_response->data_size > 0) { 87406a99fe3SHajimu UMEMOTO result = qstate->write_func(qstate, read_response->data, 87506a99fe3SHajimu UMEMOTO read_response->data_size); 87651d6ddb5SDag-Erling Smørgrav if (result != (ssize_t)qstate->kevent_watermark) { 87706a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_response_write2); 87806a99fe3SHajimu UMEMOTO return (-1); 87906a99fe3SHajimu UMEMOTO } 88006a99fe3SHajimu UMEMOTO } 88106a99fe3SHajimu UMEMOTO 88206a99fe3SHajimu UMEMOTO finalize_comm_element(&qstate->request); 88306a99fe3SHajimu UMEMOTO finalize_comm_element(&qstate->response); 88406a99fe3SHajimu UMEMOTO 88506a99fe3SHajimu UMEMOTO qstate->kevent_watermark = sizeof(int); 88606a99fe3SHajimu UMEMOTO qstate->kevent_filter = EVFILT_READ; 88706a99fe3SHajimu UMEMOTO qstate->process_func = on_rw_mapper; 88806a99fe3SHajimu UMEMOTO TRACE_OUT(on_read_response_write2); 88906a99fe3SHajimu UMEMOTO return (0); 89006a99fe3SHajimu UMEMOTO } 89106a99fe3SHajimu UMEMOTO 89206a99fe3SHajimu UMEMOTO /* 89306a99fe3SHajimu UMEMOTO * The functions below are used to process write requests. 89406a99fe3SHajimu UMEMOTO * - on_transform_request_read1 and on_transform_request_read2 read the 89506a99fe3SHajimu UMEMOTO * request itself 89606a99fe3SHajimu UMEMOTO * - on_transform_request_process processes it 89706a99fe3SHajimu UMEMOTO * - on_transform_response_write1 sends the response 89806a99fe3SHajimu UMEMOTO */ 89906a99fe3SHajimu UMEMOTO static int 90006a99fe3SHajimu UMEMOTO on_transform_request_read1(struct query_state *qstate) 90106a99fe3SHajimu UMEMOTO { 90206a99fe3SHajimu UMEMOTO struct cache_transform_request *transform_request; 90306a99fe3SHajimu UMEMOTO ssize_t result; 90406a99fe3SHajimu UMEMOTO 90506a99fe3SHajimu UMEMOTO TRACE_IN(on_transform_request_read1); 90606a99fe3SHajimu UMEMOTO if (qstate->kevent_watermark == 0) 90706a99fe3SHajimu UMEMOTO qstate->kevent_watermark = sizeof(size_t) + sizeof(int); 90806a99fe3SHajimu UMEMOTO else { 90906a99fe3SHajimu UMEMOTO init_comm_element(&qstate->request, CET_TRANSFORM_REQUEST); 91006a99fe3SHajimu UMEMOTO transform_request = 91106a99fe3SHajimu UMEMOTO get_cache_transform_request(&qstate->request); 91206a99fe3SHajimu UMEMOTO 91306a99fe3SHajimu UMEMOTO result = qstate->read_func(qstate, 91406a99fe3SHajimu UMEMOTO &transform_request->entry_length, sizeof(size_t)); 91506a99fe3SHajimu UMEMOTO result += qstate->read_func(qstate, 91606a99fe3SHajimu UMEMOTO &transform_request->transformation_type, sizeof(int)); 91706a99fe3SHajimu UMEMOTO 91806a99fe3SHajimu UMEMOTO if (result != sizeof(size_t) + sizeof(int)) { 91906a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_request_read1); 92006a99fe3SHajimu UMEMOTO return (-1); 92106a99fe3SHajimu UMEMOTO } 92206a99fe3SHajimu UMEMOTO 92306a99fe3SHajimu UMEMOTO if ((transform_request->transformation_type != TT_USER) && 92406a99fe3SHajimu UMEMOTO (transform_request->transformation_type != TT_ALL)) { 92506a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_request_read1); 92606a99fe3SHajimu UMEMOTO return (-1); 92706a99fe3SHajimu UMEMOTO } 92806a99fe3SHajimu UMEMOTO 92906a99fe3SHajimu UMEMOTO if (transform_request->entry_length != 0) { 93006a99fe3SHajimu UMEMOTO if (BUFSIZE_INVALID(transform_request->entry_length)) { 93106a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_request_read1); 93206a99fe3SHajimu UMEMOTO return (-1); 93306a99fe3SHajimu UMEMOTO } 93406a99fe3SHajimu UMEMOTO 9358eeaaffaSDag-Erling Smørgrav transform_request->entry = calloc(1, 93606a99fe3SHajimu UMEMOTO transform_request->entry_length + 1); 93706a99fe3SHajimu UMEMOTO assert(transform_request->entry != NULL); 93806a99fe3SHajimu UMEMOTO 93906a99fe3SHajimu UMEMOTO qstate->process_func = on_transform_request_read2; 94006a99fe3SHajimu UMEMOTO } else 94106a99fe3SHajimu UMEMOTO qstate->process_func = on_transform_request_process; 94206a99fe3SHajimu UMEMOTO 94306a99fe3SHajimu UMEMOTO qstate->kevent_watermark = transform_request->entry_length; 94406a99fe3SHajimu UMEMOTO } 94506a99fe3SHajimu UMEMOTO 94606a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_request_read1); 94706a99fe3SHajimu UMEMOTO return (0); 94806a99fe3SHajimu UMEMOTO } 94906a99fe3SHajimu UMEMOTO 95006a99fe3SHajimu UMEMOTO static int 95106a99fe3SHajimu UMEMOTO on_transform_request_read2(struct query_state *qstate) 95206a99fe3SHajimu UMEMOTO { 95306a99fe3SHajimu UMEMOTO struct cache_transform_request *transform_request; 95406a99fe3SHajimu UMEMOTO ssize_t result; 95506a99fe3SHajimu UMEMOTO 95606a99fe3SHajimu UMEMOTO TRACE_IN(on_transform_request_read2); 95706a99fe3SHajimu UMEMOTO transform_request = get_cache_transform_request(&qstate->request); 95806a99fe3SHajimu UMEMOTO 95906a99fe3SHajimu UMEMOTO result = qstate->read_func(qstate, transform_request->entry, 96006a99fe3SHajimu UMEMOTO transform_request->entry_length); 96106a99fe3SHajimu UMEMOTO 96251d6ddb5SDag-Erling Smørgrav if (result != (ssize_t)qstate->kevent_watermark) { 96306a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_request_read2); 96406a99fe3SHajimu UMEMOTO return (-1); 96506a99fe3SHajimu UMEMOTO } 96606a99fe3SHajimu UMEMOTO 96706a99fe3SHajimu UMEMOTO qstate->kevent_watermark = 0; 96806a99fe3SHajimu UMEMOTO qstate->process_func = on_transform_request_process; 96906a99fe3SHajimu UMEMOTO 97006a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_request_read2); 97106a99fe3SHajimu UMEMOTO return (0); 97206a99fe3SHajimu UMEMOTO } 97306a99fe3SHajimu UMEMOTO 97406a99fe3SHajimu UMEMOTO static int 97506a99fe3SHajimu UMEMOTO on_transform_request_process(struct query_state *qstate) 97606a99fe3SHajimu UMEMOTO { 97706a99fe3SHajimu UMEMOTO struct cache_transform_request *transform_request; 97806a99fe3SHajimu UMEMOTO struct cache_transform_response *transform_response; 97906a99fe3SHajimu UMEMOTO struct configuration_entry *config_entry; 98006a99fe3SHajimu UMEMOTO size_t i, size; 98106a99fe3SHajimu UMEMOTO 98206a99fe3SHajimu UMEMOTO TRACE_IN(on_transform_request_process); 98306a99fe3SHajimu UMEMOTO init_comm_element(&qstate->response, CET_TRANSFORM_RESPONSE); 98406a99fe3SHajimu UMEMOTO transform_response = get_cache_transform_response(&qstate->response); 98506a99fe3SHajimu UMEMOTO transform_request = get_cache_transform_request(&qstate->request); 98606a99fe3SHajimu UMEMOTO 98706a99fe3SHajimu UMEMOTO switch (transform_request->transformation_type) { 98806a99fe3SHajimu UMEMOTO case TT_USER: 98906a99fe3SHajimu UMEMOTO if (transform_request->entry == NULL) { 99006a99fe3SHajimu UMEMOTO size = configuration_get_entries_size(s_configuration); 99106a99fe3SHajimu UMEMOTO for (i = 0; i < size; ++i) { 99206a99fe3SHajimu UMEMOTO config_entry = configuration_get_entry( 99306a99fe3SHajimu UMEMOTO s_configuration, i); 99406a99fe3SHajimu UMEMOTO 99506a99fe3SHajimu UMEMOTO if (config_entry->perform_actual_lookups == 0) 99606a99fe3SHajimu UMEMOTO clear_config_entry_part(config_entry, 99706a99fe3SHajimu UMEMOTO qstate->eid_str, qstate->eid_str_length); 99806a99fe3SHajimu UMEMOTO } 99906a99fe3SHajimu UMEMOTO } else { 100006a99fe3SHajimu UMEMOTO qstate->config_entry = configuration_find_entry( 100106a99fe3SHajimu UMEMOTO s_configuration, transform_request->entry); 100206a99fe3SHajimu UMEMOTO 100306a99fe3SHajimu UMEMOTO if (qstate->config_entry == NULL) { 100406a99fe3SHajimu UMEMOTO LOG_ERR_2("transform_request", 100506a99fe3SHajimu UMEMOTO "can't find configuration" 100606a99fe3SHajimu UMEMOTO " entry '%s'. aborting request", 100706a99fe3SHajimu UMEMOTO transform_request->entry); 100806a99fe3SHajimu UMEMOTO transform_response->error_code = -1; 100906a99fe3SHajimu UMEMOTO goto fin; 101006a99fe3SHajimu UMEMOTO } 101106a99fe3SHajimu UMEMOTO 101206a99fe3SHajimu UMEMOTO if (qstate->config_entry->perform_actual_lookups != 0) { 101306a99fe3SHajimu UMEMOTO LOG_ERR_2("transform_request", 101406a99fe3SHajimu UMEMOTO "can't transform the cache entry %s" 101506a99fe3SHajimu UMEMOTO ", because it ised for actual lookups", 101606a99fe3SHajimu UMEMOTO transform_request->entry); 101706a99fe3SHajimu UMEMOTO transform_response->error_code = -1; 101806a99fe3SHajimu UMEMOTO goto fin; 101906a99fe3SHajimu UMEMOTO } 102006a99fe3SHajimu UMEMOTO 102106a99fe3SHajimu UMEMOTO clear_config_entry_part(qstate->config_entry, 102206a99fe3SHajimu UMEMOTO qstate->eid_str, qstate->eid_str_length); 102306a99fe3SHajimu UMEMOTO } 102406a99fe3SHajimu UMEMOTO break; 102506a99fe3SHajimu UMEMOTO case TT_ALL: 102606a99fe3SHajimu UMEMOTO if (qstate->euid != 0) 102706a99fe3SHajimu UMEMOTO transform_response->error_code = -1; 102806a99fe3SHajimu UMEMOTO else { 102906a99fe3SHajimu UMEMOTO if (transform_request->entry == NULL) { 103006a99fe3SHajimu UMEMOTO size = configuration_get_entries_size( 103106a99fe3SHajimu UMEMOTO s_configuration); 103206a99fe3SHajimu UMEMOTO for (i = 0; i < size; ++i) { 103306a99fe3SHajimu UMEMOTO clear_config_entry( 103406a99fe3SHajimu UMEMOTO configuration_get_entry( 103506a99fe3SHajimu UMEMOTO s_configuration, i)); 103606a99fe3SHajimu UMEMOTO } 103706a99fe3SHajimu UMEMOTO } else { 103806a99fe3SHajimu UMEMOTO qstate->config_entry = configuration_find_entry( 103906a99fe3SHajimu UMEMOTO s_configuration, 104006a99fe3SHajimu UMEMOTO transform_request->entry); 104106a99fe3SHajimu UMEMOTO 104206a99fe3SHajimu UMEMOTO if (qstate->config_entry == NULL) { 104306a99fe3SHajimu UMEMOTO LOG_ERR_2("transform_request", 104406a99fe3SHajimu UMEMOTO "can't find configuration" 104506a99fe3SHajimu UMEMOTO " entry '%s'. aborting request", 104606a99fe3SHajimu UMEMOTO transform_request->entry); 104706a99fe3SHajimu UMEMOTO transform_response->error_code = -1; 104806a99fe3SHajimu UMEMOTO goto fin; 104906a99fe3SHajimu UMEMOTO } 105006a99fe3SHajimu UMEMOTO 105106a99fe3SHajimu UMEMOTO clear_config_entry(qstate->config_entry); 105206a99fe3SHajimu UMEMOTO } 105306a99fe3SHajimu UMEMOTO } 105406a99fe3SHajimu UMEMOTO break; 105506a99fe3SHajimu UMEMOTO default: 105606a99fe3SHajimu UMEMOTO transform_response->error_code = -1; 105706a99fe3SHajimu UMEMOTO } 105806a99fe3SHajimu UMEMOTO 105906a99fe3SHajimu UMEMOTO fin: 106006a99fe3SHajimu UMEMOTO qstate->kevent_watermark = 0; 106106a99fe3SHajimu UMEMOTO qstate->process_func = on_transform_response_write1; 106206a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_request_process); 106306a99fe3SHajimu UMEMOTO return (0); 106406a99fe3SHajimu UMEMOTO } 106506a99fe3SHajimu UMEMOTO 106606a99fe3SHajimu UMEMOTO static int 106706a99fe3SHajimu UMEMOTO on_transform_response_write1(struct query_state *qstate) 106806a99fe3SHajimu UMEMOTO { 106906a99fe3SHajimu UMEMOTO struct cache_transform_response *transform_response; 107006a99fe3SHajimu UMEMOTO ssize_t result; 107106a99fe3SHajimu UMEMOTO 107206a99fe3SHajimu UMEMOTO TRACE_IN(on_transform_response_write1); 107306a99fe3SHajimu UMEMOTO transform_response = get_cache_transform_response(&qstate->response); 107406a99fe3SHajimu UMEMOTO result = qstate->write_func(qstate, &transform_response->error_code, 107506a99fe3SHajimu UMEMOTO sizeof(int)); 107606a99fe3SHajimu UMEMOTO if (result != sizeof(int)) { 107706a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_response_write1); 107806a99fe3SHajimu UMEMOTO return (-1); 107906a99fe3SHajimu UMEMOTO } 108006a99fe3SHajimu UMEMOTO 108106a99fe3SHajimu UMEMOTO finalize_comm_element(&qstate->request); 108206a99fe3SHajimu UMEMOTO finalize_comm_element(&qstate->response); 108306a99fe3SHajimu UMEMOTO 108406a99fe3SHajimu UMEMOTO qstate->kevent_watermark = 0; 108506a99fe3SHajimu UMEMOTO qstate->process_func = NULL; 108606a99fe3SHajimu UMEMOTO TRACE_OUT(on_transform_response_write1); 108706a99fe3SHajimu UMEMOTO return (0); 108806a99fe3SHajimu UMEMOTO } 108906a99fe3SHajimu UMEMOTO 109006a99fe3SHajimu UMEMOTO /* 109106a99fe3SHajimu UMEMOTO * Checks if the client's euid and egid do not differ from its uid and gid. 109206a99fe3SHajimu UMEMOTO * Returns 0 on success. 109306a99fe3SHajimu UMEMOTO */ 109406a99fe3SHajimu UMEMOTO int 109506a99fe3SHajimu UMEMOTO check_query_eids(struct query_state *qstate) 109606a99fe3SHajimu UMEMOTO { 109706a99fe3SHajimu UMEMOTO 109806a99fe3SHajimu UMEMOTO return ((qstate->uid != qstate->euid) || (qstate->gid != qstate->egid) ? -1 : 0); 109906a99fe3SHajimu UMEMOTO } 110006a99fe3SHajimu UMEMOTO 110106a99fe3SHajimu UMEMOTO /* 110206a99fe3SHajimu UMEMOTO * Uses the qstate fields to process an "alternate" read - when the buffer is 110306a99fe3SHajimu UMEMOTO * too large to be received during one socket read operation 110406a99fe3SHajimu UMEMOTO */ 110506a99fe3SHajimu UMEMOTO ssize_t 110606a99fe3SHajimu UMEMOTO query_io_buffer_read(struct query_state *qstate, void *buf, size_t nbytes) 110706a99fe3SHajimu UMEMOTO { 110851d6ddb5SDag-Erling Smørgrav size_t remaining; 110906a99fe3SHajimu UMEMOTO ssize_t result; 111006a99fe3SHajimu UMEMOTO 111106a99fe3SHajimu UMEMOTO TRACE_IN(query_io_buffer_read); 111206a99fe3SHajimu UMEMOTO if ((qstate->io_buffer_size == 0) || (qstate->io_buffer == NULL)) 111306a99fe3SHajimu UMEMOTO return (-1); 111406a99fe3SHajimu UMEMOTO 111551d6ddb5SDag-Erling Smørgrav assert(qstate->io_buffer_p <= 111651d6ddb5SDag-Erling Smørgrav qstate->io_buffer + qstate->io_buffer_size); 111751d6ddb5SDag-Erling Smørgrav remaining = qstate->io_buffer + qstate->io_buffer_size - 111851d6ddb5SDag-Erling Smørgrav qstate->io_buffer_p; 111951d6ddb5SDag-Erling Smørgrav if (nbytes < remaining) 112006a99fe3SHajimu UMEMOTO result = nbytes; 112106a99fe3SHajimu UMEMOTO else 112251d6ddb5SDag-Erling Smørgrav result = remaining; 112306a99fe3SHajimu UMEMOTO 112406a99fe3SHajimu UMEMOTO memcpy(buf, qstate->io_buffer_p, result); 112506a99fe3SHajimu UMEMOTO qstate->io_buffer_p += result; 112606a99fe3SHajimu UMEMOTO 112751d6ddb5SDag-Erling Smørgrav if (remaining == 0) { 112806a99fe3SHajimu UMEMOTO free(qstate->io_buffer); 112906a99fe3SHajimu UMEMOTO qstate->io_buffer = NULL; 113006a99fe3SHajimu UMEMOTO 113106a99fe3SHajimu UMEMOTO qstate->write_func = query_socket_write; 113206a99fe3SHajimu UMEMOTO qstate->read_func = query_socket_read; 113306a99fe3SHajimu UMEMOTO } 113406a99fe3SHajimu UMEMOTO 113506a99fe3SHajimu UMEMOTO TRACE_OUT(query_io_buffer_read); 113606a99fe3SHajimu UMEMOTO return (result); 113706a99fe3SHajimu UMEMOTO } 113806a99fe3SHajimu UMEMOTO 113906a99fe3SHajimu UMEMOTO /* 114006a99fe3SHajimu UMEMOTO * Uses the qstate fields to process an "alternate" write - when the buffer is 114106a99fe3SHajimu UMEMOTO * too large to be sent during one socket write operation 114206a99fe3SHajimu UMEMOTO */ 114306a99fe3SHajimu UMEMOTO ssize_t 114406a99fe3SHajimu UMEMOTO query_io_buffer_write(struct query_state *qstate, const void *buf, 114506a99fe3SHajimu UMEMOTO size_t nbytes) 114606a99fe3SHajimu UMEMOTO { 114751d6ddb5SDag-Erling Smørgrav size_t remaining; 114806a99fe3SHajimu UMEMOTO ssize_t result; 114906a99fe3SHajimu UMEMOTO 115006a99fe3SHajimu UMEMOTO TRACE_IN(query_io_buffer_write); 115106a99fe3SHajimu UMEMOTO if ((qstate->io_buffer_size == 0) || (qstate->io_buffer == NULL)) 115206a99fe3SHajimu UMEMOTO return (-1); 115306a99fe3SHajimu UMEMOTO 115451d6ddb5SDag-Erling Smørgrav assert(qstate->io_buffer_p <= 115551d6ddb5SDag-Erling Smørgrav qstate->io_buffer + qstate->io_buffer_size); 115651d6ddb5SDag-Erling Smørgrav remaining = qstate->io_buffer + qstate->io_buffer_size - 115751d6ddb5SDag-Erling Smørgrav qstate->io_buffer_p; 115851d6ddb5SDag-Erling Smørgrav if (nbytes < remaining) 115906a99fe3SHajimu UMEMOTO result = nbytes; 116006a99fe3SHajimu UMEMOTO else 116151d6ddb5SDag-Erling Smørgrav result = remaining; 116206a99fe3SHajimu UMEMOTO 116306a99fe3SHajimu UMEMOTO memcpy(qstate->io_buffer_p, buf, result); 116406a99fe3SHajimu UMEMOTO qstate->io_buffer_p += result; 116506a99fe3SHajimu UMEMOTO 116651d6ddb5SDag-Erling Smørgrav if (remaining == 0) { 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); 119351d6ddb5SDag-Erling Smørgrav if (result < 0 || (size_t)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); 121551d6ddb5SDag-Erling Smørgrav if (result < 0 || (size_t)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); 12318eeaaffaSDag-Erling Smørgrav retval = calloc(1, sizeof(*retval)); 123206a99fe3SHajimu UMEMOTO assert(retval != NULL); 123306a99fe3SHajimu UMEMOTO 123406a99fe3SHajimu UMEMOTO retval->sockfd = sockfd; 123506a99fe3SHajimu UMEMOTO retval->kevent_filter = EVFILT_READ; 123606a99fe3SHajimu UMEMOTO retval->kevent_watermark = kevent_watermark; 123706a99fe3SHajimu UMEMOTO 123806a99fe3SHajimu UMEMOTO retval->euid = euid; 123906a99fe3SHajimu UMEMOTO retval->egid = egid; 124006a99fe3SHajimu UMEMOTO retval->uid = retval->gid = -1; 124106a99fe3SHajimu UMEMOTO 124206a99fe3SHajimu UMEMOTO if (asprintf(&retval->eid_str, "%d_%d_", retval->euid, 124306a99fe3SHajimu UMEMOTO retval->egid) == -1) { 124406a99fe3SHajimu UMEMOTO free(retval); 124506a99fe3SHajimu UMEMOTO return (NULL); 124606a99fe3SHajimu UMEMOTO } 124706a99fe3SHajimu UMEMOTO retval->eid_str_length = strlen(retval->eid_str); 124806a99fe3SHajimu UMEMOTO 124906a99fe3SHajimu UMEMOTO init_comm_element(&retval->request, CET_UNDEFINED); 125006a99fe3SHajimu UMEMOTO init_comm_element(&retval->response, CET_UNDEFINED); 125106a99fe3SHajimu UMEMOTO retval->process_func = on_query_startup; 125206a99fe3SHajimu UMEMOTO retval->destroy_func = on_query_destroy; 125306a99fe3SHajimu UMEMOTO 125406a99fe3SHajimu UMEMOTO retval->write_func = query_socket_write; 125506a99fe3SHajimu UMEMOTO retval->read_func = query_socket_read; 125606a99fe3SHajimu UMEMOTO 125706a99fe3SHajimu UMEMOTO get_time_func(&retval->creation_time); 125823c7e79aSJohn Baldwin retval->timeout.tv_sec = s_configuration->query_timeout; 125923c7e79aSJohn Baldwin retval->timeout.tv_usec = 0; 126006a99fe3SHajimu UMEMOTO 126106a99fe3SHajimu UMEMOTO TRACE_OUT(init_query_state); 126206a99fe3SHajimu UMEMOTO return (retval); 126306a99fe3SHajimu UMEMOTO } 126406a99fe3SHajimu UMEMOTO 126506a99fe3SHajimu UMEMOTO void 126606a99fe3SHajimu UMEMOTO destroy_query_state(struct query_state *qstate) 126706a99fe3SHajimu UMEMOTO { 126806a99fe3SHajimu UMEMOTO 126906a99fe3SHajimu UMEMOTO TRACE_IN(destroy_query_state); 127006a99fe3SHajimu UMEMOTO if (qstate->eid_str != NULL) 127106a99fe3SHajimu UMEMOTO free(qstate->eid_str); 127206a99fe3SHajimu UMEMOTO 127306a99fe3SHajimu UMEMOTO if (qstate->io_buffer != NULL) 127406a99fe3SHajimu UMEMOTO free(qstate->io_buffer); 127506a99fe3SHajimu UMEMOTO 127606a99fe3SHajimu UMEMOTO qstate->destroy_func(qstate); 127706a99fe3SHajimu UMEMOTO free(qstate); 127806a99fe3SHajimu UMEMOTO TRACE_OUT(destroy_query_state); 127906a99fe3SHajimu UMEMOTO } 1280