/* Copyright (c) 1998, 1999, 2000, 2003, 2004 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 /* 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" /* Available services. */ typedef enum { GETPWBYNAME, GETPWBYUID, GETGRBYNAME, GETGRBYGID, GETHOSTBYNAME, GETHOSTBYNAMEv6, GETHOSTBYADDR, GETHOSTBYADDRv6, LASTDBREQ = GETHOSTBYADDRv6, SHUTDOWN, /* Shut the server down. */ GETSTAT, /* Get the server statistic. */ INVALIDATE, /* Invalidate one special cache. */ GETFDPW, GETFDGR, GETFDHST, 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; /* Type for offsets in data part of database. */ typedef uint32_t ref_t; /* Value for invalid/no reference. */ #define ENDREF UINT32_MAX /* Alignment requirement of the beginning of the data region. */ #define ALIGN 16 /* Head of record in data part of database. */ struct datahead { size_t allocsize; /* Allocated Bytes. */ size_t recsize; /* Size of the record. */ time_t timeout; /* Time when this entry becomes invalid. */ bool notfound; /* Nonzero if data for key has not been found. */ uint8_t nreloads; /* Reloads without use. */ bool usable; /* False if the entry must be ignored. */ /* 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; ssize_t align1; 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. */ size_t len; /* Length of key. */ ref_t key; /* Pointer to key. */ uid_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 { int version; int header_size; int gc_cycle; int nscd_certainly_running; volatile time_t timestamp; size_t module; size_t data_size; size_t first_free; /* Offset of first free byte in data area. */ size_t nentries; size_t maxnentries; size_t maxnsearched; uintmax_t poshit; uintmax_t neghit; uintmax_t posmiss; uintmax_t negmiss; uintmax_t rdlockdelayed; uintmax_t wrlockdelayed; uintmax_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 isusable. */ }; #define NO_MAPPING ((struct mapped_database *) -1l) struct locked_map_ptr { int lock; struct mapped_database *mapped; }; #define libc_locked_map_ptr(name) static 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, 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) { if (__builtin_expect (map->head->gc_cycle != gc_cycle, 0)) /* We might have read inconsistent data. */ return -1; if (atomic_decrement_val (&map->counter) == 0) __nscd_unmap (map); } return 0; } /* Search the mapped database. */ extern const struct datahead * __nscd_cache_search (request_type type, const char *key, size_t keylen, const struct mapped_database *mapped); #endif /* nscd.h */