]> git.ipfire.org Git - thirdparty/glibc.git/blame - nscd/nscd-client.h
malloc: Various cleanups for malloc/tst-mxfast
[thirdparty/glibc.git] / nscd / nscd-client.h
CommitLineData
688903eb 1/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
4f6bfa80 2 This file is part of the GNU C Library.
756409c4 3 Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
4f6bfa80
RM
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
4f6bfa80
RM
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
4f6bfa80 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
4f6bfa80
RM
18
19/* This file defines everything that client code should need to
20 know to talk to the nscd daemon. */
21
22#ifndef _NSCD_CLIENT_H
23#define _NSCD_CLIENT_H 1
24
cf6f93d4
UD
25#include <stdbool.h>
26#include <stdint.h>
a849e800 27#include <string.h>
868df0f9 28#include <time.h>
cf6f93d4 29#include <sys/types.h>
c207f23b 30#include <atomic.h>
ed099f02 31#include <nscd-types.h>
804bb90a 32#include <sys/uio.h>
ed099f02 33
cf6f93d4 34
4f6bfa80 35/* Version number of the daemon interface */
ed099f02 36#define NSCD_VERSION 2
4f6bfa80
RM
37
38/* Path of the file where the PID of the running system is stored. */
520ec963 39#define _PATH_NSCDPID "/var/run/nscd/nscd.pid"
4f6bfa80
RM
40
41/* Path for the Unix domain socket. */
520ec963 42#define _PATH_NSCDSOCKET "/var/run/nscd/socket"
4f6bfa80
RM
43
44/* Path for the configuration file. */
45#define _PATH_NSCDCONF "/etc/nscd.conf"
46
831a4049 47/* Maximum allowed length for the key. */
8f9bf732
UD
48#define MAXKEYLEN 1024
49
4f6bfa80
RM
50
51/* Available services. */
52typedef enum
53{
54 GETPWBYNAME,
55 GETPWBYUID,
56 GETGRBYNAME,
57 GETGRBYGID,
58 GETHOSTBYNAME,
59 GETHOSTBYNAMEv6,
60 GETHOSTBYADDR,
61 GETHOSTBYADDRv6,
4f6bfa80
RM
62 SHUTDOWN, /* Shut the server down. */
63 GETSTAT, /* Get the server statistic. */
756409c4 64 INVALIDATE, /* Invalidate one special cache. */
c207f23b
UD
65 GETFDPW,
66 GETFDGR,
67 GETFDHST,
d19687d6 68 GETAI,
f7e7a396 69 INITGROUPS,
b21fa963
UD
70 GETSERVBYNAME,
71 GETSERVBYPORT,
72 GETFDSERV,
684ae515
UD
73 GETNETGRENT,
74 INNETGR,
75 GETFDNETGR,
756409c4 76 LASTREQ
4f6bfa80
RM
77} request_type;
78
79
80/* Header common to all requests */
81typedef struct
82{
ed099f02 83 int32_t version; /* Version number of the daemon interface. */
4f6bfa80 84 request_type type; /* Service requested. */
3107c0c5 85 int32_t key_len; /* Key length. */
4f6bfa80
RM
86} request_header;
87
88
89/* Structure sent in reply to password query. Note that this struct is
90 sent also if the service is disabled or there is no record found. */
91typedef struct
92{
3107c0c5
UD
93 int32_t version;
94 int32_t found;
ed099f02
UD
95 nscd_ssize_t pw_name_len;
96 nscd_ssize_t pw_passwd_len;
4f6bfa80
RM
97 uid_t pw_uid;
98 gid_t pw_gid;
ed099f02
UD
99 nscd_ssize_t pw_gecos_len;
100 nscd_ssize_t pw_dir_len;
101 nscd_ssize_t pw_shell_len;
4f6bfa80
RM
102} pw_response_header;
103
104
105/* Structure sent in reply to group query. Note that this struct is
106 sent also if the service is disabled or there is no record found. */
107typedef struct
108{
3107c0c5
UD
109 int32_t version;
110 int32_t found;
ed099f02
UD
111 nscd_ssize_t gr_name_len;
112 nscd_ssize_t gr_passwd_len;
4f6bfa80 113 gid_t gr_gid;
ed099f02 114 nscd_ssize_t gr_mem_cnt;
4f6bfa80
RM
115} gr_response_header;
116
117
118/* Structure sent in reply to host query. Note that this struct is
119 sent also if the service is disabled or there is no record found. */
120typedef struct
121{
3107c0c5
UD
122 int32_t version;
123 int32_t found;
ed099f02
UD
124 nscd_ssize_t h_name_len;
125 nscd_ssize_t h_aliases_cnt;
3107c0c5
UD
126 int32_t h_addrtype;
127 int32_t h_length;
ed099f02 128 nscd_ssize_t h_addr_list_cnt;
3107c0c5 129 int32_t error;
4f6bfa80
RM
130} hst_response_header;
131
132
d19687d6
UD
133/* Structure sent in reply to addrinfo query. Note that this struct is
134 sent also if the service is disabled or there is no record found. */
135typedef struct
136{
137 int32_t version;
138 int32_t found;
139 nscd_ssize_t naddrs;
140 nscd_ssize_t addrslen;
141 nscd_ssize_t canonlen;
142 int32_t error;
143} ai_response_header;
144
145/* Structure filled in by __nscd_getai. */
146struct nscd_ai_result
147{
148 int naddrs;
149 char *canon;
150 uint8_t *family;
151 char *addrs;
152};
153
f7e7a396
UD
154/* Structure sent in reply to initgroups query. Note that this struct is
155 sent also if the service is disabled or there is no record found. */
156typedef struct
157{
158 int32_t version;
159 int32_t found;
160 nscd_ssize_t ngrps;
161} initgr_response_header;
162
d19687d6 163
b21fa963
UD
164/* Structure sent in reply to services query. Note that this struct is
165 sent also if the service is disabled or there is no record found. */
166typedef struct
167{
168 int32_t version;
169 int32_t found;
170 nscd_ssize_t s_name_len;
171 nscd_ssize_t s_proto_len;
172 nscd_ssize_t s_aliases_cnt;
173 int32_t s_port;
174} serv_response_header;
175
176
684ae515
UD
177/* Structure send in reply to netgroup query. Note that this struct is
178 sent also if the service is disabled or there is no record found. */
179typedef struct
180{
181 int32_t version;
182 int32_t found;
183 nscd_ssize_t nresults;
184 nscd_ssize_t result_len;
185} netgroup_response_header;
186
187typedef struct
188{
189 int32_t version;
190 int32_t found;
191 int32_t result;
192} innetgroup_response_header;
193
194
c207f23b
UD
195/* Type for offsets in data part of database. */
196typedef uint32_t ref_t;
197/* Value for invalid/no reference. */
198#define ENDREF UINT32_MAX
199
404db64a
UD
200/* Timestamp type. */
201typedef uint64_t nscd_time_t;
202
a4c7ea7b
UD
203/* Maximum timestamp. */
204#define MAX_TIMEOUT_VALUE \
205 (sizeof (time_t) == sizeof (long int) ? LONG_MAX : INT_MAX)
206
c207f23b
UD
207/* Alignment requirement of the beginning of the data region. */
208#define ALIGN 16
209
210
211/* Head of record in data part of database. */
212struct datahead
213{
404db64a
UD
214 nscd_ssize_t allocsize; /* Allocated Bytes. */
215 nscd_ssize_t recsize; /* Size of the record. */
216 nscd_time_t timeout; /* Time when this entry becomes invalid. */
d19687d6 217 uint8_t notfound; /* Nonzero if data has not been found. */
404db64a 218 uint8_t nreloads; /* Reloads without use. */
d19687d6 219 uint8_t usable; /* False if the entry must be ignored. */
a4c7ea7b
UD
220 uint8_t unused; /* Unused. */
221 uint32_t ttl; /* TTL value used. */
c207f23b
UD
222
223 /* We need to have the following element aligned for the response
224 header data types and their use in the 'struct dataset' types
225 defined in the XXXcache.c files. */
226 union
227 {
228 pw_response_header pwdata;
229 gr_response_header grdata;
230 hst_response_header hstdata;
d19687d6 231 ai_response_header aidata;
f7e7a396 232 initgr_response_header initgrdata;
b21fa963 233 serv_response_header servdata;
684ae515
UD
234 netgroup_response_header netgroupdata;
235 innetgroup_response_header innetgroupdata;
404db64a
UD
236 nscd_ssize_t align1;
237 nscd_time_t align2;
c207f23b
UD
238 } data[0];
239};
240
1cdeb237
SP
241static inline time_t
242datahead_init_common (struct datahead *head, nscd_ssize_t allocsize,
243 nscd_ssize_t recsize, uint32_t ttl)
244{
bc8f194c
SP
245 /* Initialize so that we don't write out junk in uninitialized data to the
246 cache. */
247 memset (head, 0, sizeof (*head));
248
1cdeb237
SP
249 head->allocsize = allocsize;
250 head->recsize = recsize;
251 head->usable = true;
252
253 head->ttl = ttl;
bc8f194c
SP
254
255 /* Compute and return the timeout time. */
1cdeb237
SP
256 return head->timeout = time (NULL) + ttl;
257}
258
259static inline time_t
260datahead_init_pos (struct datahead *head, nscd_ssize_t allocsize,
261 nscd_ssize_t recsize, uint8_t nreloads, uint32_t ttl)
262{
bc8f194c
SP
263 time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
264
1cdeb237
SP
265 head->notfound = false;
266 head->nreloads = nreloads;
bc8f194c
SP
267
268 return ret;
1cdeb237
SP
269}
270
271static inline time_t
272datahead_init_neg (struct datahead *head, nscd_ssize_t allocsize,
273 nscd_ssize_t recsize, uint32_t ttl)
274{
bc8f194c
SP
275 time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
276
277 /* We don't need to touch nreloads here since it is set to our desired value
278 (0) when we clear the structure. */
1cdeb237 279 head->notfound = true;
bc8f194c
SP
280
281 return ret;
1cdeb237 282}
c207f23b
UD
283
284/* Structure for one hash table entry. */
285struct hashentry
286{
287 request_type type:8; /* Which type of dataset. */
288 bool first; /* True if this was the original key. */
404db64a 289 nscd_ssize_t len; /* Length of key. */
c207f23b 290 ref_t key; /* Pointer to key. */
404db64a 291 int32_t owner; /* If secure table, this is the owner. */
c207f23b
UD
292 ref_t next; /* Next entry in this hash bucket list. */
293 ref_t packet; /* Records for the result. */
294 union
295 {
296 struct hashentry *dellist; /* Next record to be deleted. This can be a
297 pointer since only nscd uses this field. */
298 ref_t *prevp; /* Pointer to field containing forward
299 reference. */
300 };
301};
302
303
304/* Current persistent database version. */
3a2c0242 305#define DB_VERSION 2
c207f23b
UD
306
307/* Maximum time allowed between updates of the timestamp. */
308#define MAPPING_TIMEOUT (5 * 60)
309
310
3a2c0242
UD
311/* Used indices for the EXTRA_DATA element of 'database_pers_head'.
312 Each database has its own indices. */
313#define NSCD_HST_IDX_CONF_TIMESTAMP 0
314
315
c207f23b
UD
316/* Header of persistent database file. */
317struct database_pers_head
318{
404db64a
UD
319 int32_t version;
320 int32_t header_size;
321 volatile int32_t gc_cycle;
322 volatile int32_t nscd_certainly_running;
323 volatile nscd_time_t timestamp;
3a2c0242
UD
324 /* Room for extensions. */
325 volatile uint32_t extra_data[4];
c207f23b 326
404db64a
UD
327 nscd_ssize_t module;
328 nscd_ssize_t data_size;
c207f23b 329
404db64a 330 nscd_ssize_t first_free; /* Offset of first free byte in data area. */
c207f23b 331
404db64a
UD
332 nscd_ssize_t nentries;
333 nscd_ssize_t maxnentries;
334 nscd_ssize_t maxnsearched;
c207f23b 335
404db64a
UD
336 uint64_t poshit;
337 uint64_t neghit;
338 uint64_t posmiss;
339 uint64_t negmiss;
c207f23b 340
404db64a
UD
341 uint64_t rdlockdelayed;
342 uint64_t wrlockdelayed;
c207f23b 343
404db64a 344 uint64_t addfailed;
c207f23b
UD
345
346 ref_t array[0];
347};
348
349
350/* Mapped database record. */
351struct mapped_database
352{
353 const struct database_pers_head *head;
354 const char *data;
355 size_t mapsize;
f7e7a396 356 int counter; /* > 0 indicates it is usable. */
0b25a49a 357 size_t datasize;
c207f23b
UD
358};
359#define NO_MAPPING ((struct mapped_database *) -1l)
360
361struct locked_map_ptr
362{
363 int lock;
364 struct mapped_database *mapped;
365};
5429ff76 366#define libc_locked_map_ptr(class, name) class struct locked_map_ptr name
c207f23b 367
509072a0
AJ
368/* Try acquiring lock for mapptr, returns true if it succeeds, false
369 if not. */
6540185f
RM
370static inline bool
371__nscd_acquire_maplock (volatile struct locked_map_ptr *mapptr)
509072a0
AJ
372{
373 int cnt = 0;
374 while (__builtin_expect (atomic_compare_and_exchange_val_acq (&mapptr->lock,
375 1, 0) != 0, 0))
376 {
377 // XXX Best number of rounds?
a1ffb40e 378 if (__glibc_unlikely (++cnt > 5))
509072a0
AJ
379 return false;
380
4eb984d3 381 atomic_spin_nop ();
509072a0
AJ
382 }
383
384 return true;
385}
386
c207f23b 387
4c5dd2a2 388/* Open socket connection to nscd server. */
40c38b6c
UD
389extern int __nscd_open_socket (const char *key, size_t keylen,
390 request_type type, void *response,
391 size_t responselen) attribute_hidden;
4c5dd2a2 392
3a2c0242
UD
393/* Try to get a file descriptor for the shared meory segment
394 containing the database. */
395extern struct mapped_database *__nscd_get_mapping (request_type type,
396 const char *key,
397 struct mapped_database **mappedp) attribute_hidden;
398
c207f23b
UD
399/* Get reference of mapping. */
400extern struct mapped_database *__nscd_get_map_ref (request_type type,
401 const char *name,
388df58d 402 volatile struct locked_map_ptr *mapptr,
a4338d99
L
403 int *gc_cyclep)
404 attribute_hidden;
c207f23b
UD
405
406/* Unmap database. */
a4338d99
L
407extern void __nscd_unmap (struct mapped_database *mapped)
408 attribute_hidden;
c207f23b
UD
409
410/* Drop reference of mapping. */
f1d70dad
RM
411static int
412__attribute__ ((unused))
413__nscd_drop_map_ref (struct mapped_database *map, int *gc_cycle)
c207f23b
UD
414{
415 if (map != NO_MAPPING)
416 {
085f2dd0 417 int now_cycle = map->head->gc_cycle;
a1ffb40e 418 if (__glibc_unlikely (now_cycle != *gc_cycle))
085f2dd0
UD
419 {
420 /* We might have read inconsistent data. */
421 *gc_cycle = now_cycle;
422 return -1;
423 }
c207f23b
UD
424
425 if (atomic_decrement_val (&map->counter) == 0)
426 __nscd_unmap (map);
427 }
428
429 return 0;
430}
431
432
433/* Search the mapped database. */
1a77d37f
JJ
434extern struct datahead *__nscd_cache_search (request_type type,
435 const char *key,
436 size_t keylen,
cfe1fc10 437 const struct mapped_database *mapped,
a4338d99
L
438 size_t datalen)
439 attribute_hidden;
c207f23b 440
804bb90a
UD
441/* Wrappers around read, readv and write that only read/write less than LEN
442 bytes on error or EOF. */
443extern ssize_t __readall (int fd, void *buf, size_t len)
444 attribute_hidden;
445extern ssize_t __readvall (int fd, const struct iovec *iov, int iovcnt)
446 attribute_hidden;
447extern ssize_t writeall (int fd, const void *buf, size_t len)
448 attribute_hidden;
449
3a2c0242 450/* Get netlink timestamp counter from mapped area or zero. */
a4338d99
L
451extern uint32_t __nscd_get_nl_timestamp (void)
452 attribute_hidden;
3a2c0242 453
4f6bfa80 454#endif /* nscd.h */