| /* 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 <kukuk@suse.de>, 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 <stdbool.h> |
| #include <stdint.h> |
| #include <sys/types.h> |
| #include <atomic.h> |
| #include <nscd-types.h> |
| #include <sys/uio.h> |
| |
| |
| /* 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" |
| |
| /* Maximum 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 */ |