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