/* Copyright (c) 1998, 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1998. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* This file defines everything that client code should need to know to talk to the nscd daemon. */ #ifndef _NSCD_CLIENT_H #define _NSCD_CLIENT_H 1 #include #include #include #include #include #include /* Version number of the daemon interface */ #define NSCD_VERSION 2 /* Path of the file where the PID of the running system is stored. */ #define _PATH_NSCDPID "/var/run/nscd/nscd.pid" /* Path for the Unix domain socket. */ #define _PATH_NSCDSOCKET "/var/run/nscd/socket" /* Path for the configuration file. */ #define _PATH_NSCDCONF "/etc/nscd.conf" /* Maximu allowed length for the key. */ #define MAXKEYLEN 1024 /* Available services. */ typedef enum { GETPWBYNAME, GETPWBYUID, GETGRBYNAME, GETGRBYGID, GETHOSTBYNAME, GETHOSTBYNAMEv6, GETHOSTBYADDR, GETHOSTBYADDRv6, SHUTDOWN, /* Shut the server down. */ GETSTAT, /* Get the server statistic. */ INVALIDATE, /* Invalidate one special cache. */ GETFDPW, GETFDGR, GETFDHST, GETAI, INITGROUPS, GETSERVBYNAME, GETSERVBYPORT, GETFDSERV, LASTREQ } request_type; /* Header common to all requests */ typedef struct { int32_t version; /* Version number of the daemon interface. */ request_type type; /* Service requested. */ int32_t key_len; /* Key length. */ } request_header; /* Structure sent in reply to password query. Note that this struct is sent also if the service is disabled or there is no record found. */ typedef struct { int32_t version; int32_t found; nscd_ssize_t pw_name_len; nscd_ssize_t pw_passwd_len; uid_t pw_uid; gid_t pw_gid; nscd_ssize_t pw_gecos_len; nscd_ssize_t pw_dir_len; nscd_ssize_t pw_shell_len; } pw_response_header; /* Structure sent in reply to group query. Note that this struct is sent also if the service is disabled or there is no record found. */ typedef struct { int32_t version; int32_t found; nscd_ssize_t gr_name_len; nscd_ssize_t gr_passwd_len; gid_t gr_gid; nscd_ssize_t gr_mem_cnt; } gr_response_header; /* Structure sent in reply to host query. Note that this struct is sent also if the service is disabled or there is no record found. */ typedef struct { int32_t version; int32_t found; nscd_ssize_t h_name_len; nscd_ssize_t h_aliases_cnt; int32_t h_addrtype; int32_t h_length; nscd_ssize_t h_addr_list_cnt; int32_t error; } hst_response_header; /* Structure sent in reply to addrinfo query. Note that this struct is sent also if the service is disabled or there is no record found. */ typedef struct { int32_t version; int32_t found; nscd_ssize_t naddrs; nscd_ssize_t addrslen; nscd_ssize_t canonlen; int32_t error; } ai_response_header; /* Structure filled in by __nscd_getai. */ struct nscd_ai_result { int naddrs; char *canon; uint8_t *family; char *addrs; }; /* Structure sent in reply to initgroups query. Note that this struct is sent also if the service is disabled or there is no record found. */ typedef struct { int32_t version; int32_t found; nscd_ssize_t ngrps; } initgr_response_header; /* Structure sent in reply to services query. Note that this struct is sent also if the service is disabled or there is no record found. */ typedef struct { int32_t version; int32_t found; nscd_ssize_t s_name_len; nscd_ssize_t s_proto_len; nscd_ssize_t s_aliases_cnt; int32_t s_port; } serv_response_header; /* Type for offsets in data part of database. */ typedef uint32_t ref_t; /* Value for invalid/no reference. */ #define ENDREF UINT32_MAX /* Timestamp type. */ typedef uint64_t nscd_time_t; /* Alignment requirement of the beginning of the data region. */ #define ALIGN 16 /* Head of record in data part of database. */ struct datahead { nscd_ssize_t allocsize; /* Allocated Bytes. */ nscd_ssize_t recsize; /* Size of the record. */ nscd_time_t timeout; /* Time when this entry becomes invalid. */ uint8_t notfound; /* Nonzero if data has not been found. */ uint8_t nreloads; /* Reloads without use. */ uint8_t usable; /* False if the entry must be ignored. */ uint64_t :40; /* Alignment. */ /* We need to have the following element aligned for the response header data types and their use in the 'struct dataset' types defined in the XXXcache.c files. */ union { pw_response_header pwdata; gr_response_header grdata; hst_response_header hstdata; ai_response_header aidata; initgr_response_header initgrdata; serv_response_header servdata; nscd_ssize_t align1; nscd_time_t align2; } data[0]; }; /* Structure for one hash table entry. */ struct hashentry { request_type type:8; /* Which type of dataset. */ bool first; /* True if this was the original key. */ nscd_ssize_t len; /* Length of key. */ ref_t key; /* Pointer to key. */ int32_t owner; /* If secure table, this is the owner. */ ref_t next; /* Next entry in this hash bucket list. */ ref_t packet; /* Records for the result. */ union { struct hashentry *dellist; /* Next record to be deleted. This can be a pointer since only nscd uses this field. */ ref_t *prevp; /* Pointer to field containing forward reference. */ }; }; /* Current persistent database version. */ #define DB_VERSION 1 /* Maximum time allowed between updates of the timestamp. */ #define MAPPING_TIMEOUT (5 * 60) /* Header of persistent database file. */ struct database_pers_head { int32_t version; int32_t header_size; volatile int32_t gc_cycle; volatile int32_t nscd_certainly_running; volatile nscd_time_t timestamp; nscd_ssize_t module; nscd_ssize_t data_size; nscd_ssize_t first_free; /* Offset of first free byte in data area. */ nscd_ssize_t nentries; nscd_ssize_t maxnentries; nscd_ssize_t maxnsearched; uint64_t poshit; uint64_t neghit; uint64_t posmiss; uint64_t negmiss; uint64_t rdlockdelayed; uint64_t wrlockdelayed; uint64_t addfailed; ref_t array[0]; }; /* Mapped database record. */ struct mapped_database { const struct database_pers_head *head; const char *data; size_t mapsize; int counter; /* > 0 indicates it is usable. */ size_t datasize; }; #define NO_MAPPING ((struct mapped_database *) -1l) struct locked_map_ptr { int lock; struct mapped_database *mapped; }; #define libc_locked_map_ptr(class, name) class struct locked_map_ptr name /* Open socket connection to nscd server. */ extern int __nscd_open_socket (const char *key, size_t keylen, request_type type, void *response, size_t responselen) attribute_hidden; /* Get reference of mapping. */ extern struct mapped_database *__nscd_get_map_ref (request_type type, const char *name, volatile struct locked_map_ptr *mapptr, int *gc_cyclep); /* Unmap database. */ extern void __nscd_unmap (struct mapped_database *mapped); /* Drop reference of mapping. */ static inline int __nscd_drop_map_ref (struct mapped_database *map, int *gc_cycle) { if (map != NO_MAPPING) { int now_cycle = map->head->gc_cycle; if (__builtin_expect (now_cycle != *gc_cycle, 0)) { /* We might have read inconsistent data. */ *gc_cycle = now_cycle; return -1; } if (atomic_decrement_val (&map->counter) == 0) __nscd_unmap (map); } return 0; } /* Search the mapped database. */ extern struct datahead *__nscd_cache_search (request_type type, const char *key, size_t keylen, const struct mapped_database *mapped, size_t datalen); /* Wrappers around read, readv and write that only read/write less than LEN bytes on error or EOF. */ extern ssize_t __readall (int fd, void *buf, size_t len) attribute_hidden; extern ssize_t __readvall (int fd, const struct iovec *iov, int iovcnt) attribute_hidden; extern ssize_t writeall (int fd, const void *buf, size_t len) attribute_hidden; extern ssize_t sendfileall (int tofd, int fromfd, off_t off, size_t len) attribute_hidden; #endif /* nscd.h */