1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #ifndef _NSCD_CLIENT_H
25: #define _NSCD_CLIENT_H 1
26:
27: #include <stdbool.h>
28: #include <stdint.h>
29: #include <sys/types.h>
30: #include <atomic.h>
31: #include <nscd-types.h>
32: #include <sys/uio.h>
33:
34:
35:
36: #define NSCD_VERSION 2
37:
38:
39: #define _PATH_NSCDPID "/var/run/nscd/nscd.pid"
40:
41:
42: #define _PATH_NSCDSOCKET "/var/run/nscd/socket"
43:
44:
45: #define _PATH_NSCDCONF "/etc/nscd.conf"
46:
47:
48: #define MAXKEYLEN 1024
49:
50:
51:
52: typedef enum
53: {
54: GETPWBYNAME,
55: GETPWBYUID,
56: GETGRBYNAME,
57: GETGRBYGID,
58: GETHOSTBYNAME,
59: GETHOSTBYNAMEv6,
60: GETHOSTBYADDR,
61: GETHOSTBYADDRv6,
62: SHUTDOWN,
63: GETSTAT,
64: INVALIDATE,
65: GETFDPW,
66: GETFDGR,
67: GETFDHST,
68: GETAI,
69: INITGROUPS,
70: GETSERVBYNAME,
71: GETSERVBYPORT,
72: GETFDSERV,
73: LASTREQ
74: } request_type;
75:
76:
77:
78: typedef struct
79: {
80: int32_t version;
81: request_type type;
82: int32_t key_len;
83: } request_header;
84:
85:
86:
87:
88: typedef struct
89: {
90: int32_t version;
91: int32_t found;
92: nscd_ssize_t pw_name_len;
93: nscd_ssize_t pw_passwd_len;
94: uid_t pw_uid;
95: gid_t pw_gid;
96: nscd_ssize_t pw_gecos_len;
97: nscd_ssize_t pw_dir_len;
98: nscd_ssize_t pw_shell_len;
99: } pw_response_header;
100:
101:
102:
103:
104: typedef struct
105: {
106: int32_t version;
107: int32_t found;
108: nscd_ssize_t gr_name_len;
109: nscd_ssize_t gr_passwd_len;
110: gid_t gr_gid;
111: nscd_ssize_t gr_mem_cnt;
112: } gr_response_header;
113:
114:
115:
116:
117: typedef struct
118: {
119: int32_t version;
120: int32_t found;
121: nscd_ssize_t h_name_len;
122: nscd_ssize_t h_aliases_cnt;
123: int32_t h_addrtype;
124: int32_t h_length;
125: nscd_ssize_t h_addr_list_cnt;
126: int32_t error;
127: } hst_response_header;
128:
129:
130:
131:
132: typedef struct
133: {
134: int32_t version;
135: int32_t found;
136: nscd_ssize_t naddrs;
137: nscd_ssize_t addrslen;
138: nscd_ssize_t canonlen;
139: int32_t error;
140: } ai_response_header;
141:
142:
143: struct nscd_ai_result
144: {
145: int naddrs;
146: char *canon;
147: uint8_t *family;
148: char *addrs;
149: };
150:
151:
152:
153: typedef struct
154: {
155: int32_t version;
156: int32_t found;
157: nscd_ssize_t ngrps;
158: } initgr_response_header;
159:
160:
161:
162:
163: typedef struct
164: {
165: int32_t version;
166: int32_t found;
167: nscd_ssize_t s_name_len;
168: nscd_ssize_t s_proto_len;
169: nscd_ssize_t s_aliases_cnt;
170: int32_t s_port;
171: } serv_response_header;
172:
173:
174:
175: typedef uint32_t ref_t;
176:
177: #define ENDREF UINT32_MAX
178:
179:
180: typedef uint64_t nscd_time_t;
181:
182:
183: #define ALIGN 16
184:
185:
186:
187: struct datahead
188: {
189: nscd_ssize_t allocsize;
190: nscd_ssize_t recsize;
191: nscd_time_t timeout;
192: uint8_t notfound;
193: uint8_t nreloads;
194: uint8_t usable;
195: uint64_t :40;
196:
197:
198:
199:
200: union
201: {
202: pw_response_header pwdata;
203: gr_response_header grdata;
204: hst_response_header hstdata;
205: ai_response_header aidata;
206: initgr_response_header initgrdata;
207: serv_response_header servdata;
208: nscd_ssize_t align1;
209: nscd_time_t align2;
210: } data[0];
211: };
212:
213:
214:
215: struct hashentry
216: {
217: request_type type:8;
218: bool first;
219: nscd_ssize_t len;
220: ref_t key;
221: int32_t owner;
222: ref_t next;
223: ref_t packet;
224: union
225: {
226: struct hashentry *dellist;
227:
228: ref_t *prevp;
229:
230: };
231: };
232:
233:
234:
235: #define DB_VERSION 1
236:
237:
238: #define MAPPING_TIMEOUT (5 * 60)
239:
240:
241:
242: struct database_pers_head
243: {
244: int32_t version;
245: int32_t header_size;
246: volatile int32_t gc_cycle;
247: volatile int32_t nscd_certainly_running;
248: volatile nscd_time_t timestamp;
249:
250: nscd_ssize_t module;
251: nscd_ssize_t data_size;
252:
253: nscd_ssize_t first_free;
254:
255: nscd_ssize_t nentries;
256: nscd_ssize_t maxnentries;
257: nscd_ssize_t maxnsearched;
258:
259: uint64_t poshit;
260: uint64_t neghit;
261: uint64_t posmiss;
262: uint64_t negmiss;
263:
264: uint64_t rdlockdelayed;
265: uint64_t wrlockdelayed;
266:
267: uint64_t addfailed;
268:
269: ref_t array[0];
270: };
271:
272:
273:
274: struct mapped_database
275: {
276: const struct database_pers_head *head;
277: const char *data;
278: size_t mapsize;
279: int counter;
280: size_t datasize;
281: };
282: #define NO_MAPPING ((struct mapped_database *) -1l)
283:
284: struct locked_map_ptr
285: {
286: int lock;
287: struct mapped_database *mapped;
288: };
289: #define libc_locked_map_ptr(class, name) class struct locked_map_ptr name
290:
291:
292:
293: extern int __nscd_open_socket (const char *key, size_t keylen,
294: request_type type, void *response,
295: size_t responselen) attribute_hidden;
296:
297:
298: extern struct mapped_database *__nscd_get_map_ref (request_type type,
299: const char *name,
300: volatile struct locked_map_ptr *mapptr,
301: int *gc_cyclep);
302:
303:
304: extern void __nscd_unmap (struct mapped_database *mapped);
305:
306:
307: static inline int __nscd_drop_map_ref (struct mapped_database *map,
308: int *gc_cycle)
309: {
310: if (map != NO_MAPPING)
311: {
312: int now_cycle = map->head->gc_cycle;
313: if (__builtin_expect (now_cycle != *gc_cycle, 0))
314: {
315:
316: *gc_cycle = now_cycle;
317: return -1;
318: }
319:
320: if (atomic_decrement_val (&map->counter) == 0)
321: __nscd_unmap (map);
322: }
323:
324: return 0;
325: }
326:
327:
328:
329: extern struct datahead *__nscd_cache_search (request_type type,
330: const char *key,
331: size_t keylen,
332: const struct mapped_database *mapped);
333:
334:
335:
336: extern ssize_t __readall (int fd, void *buf, size_t len)
337: attribute_hidden;
338: extern ssize_t __readvall (int fd, const struct iovec *iov, int iovcnt)
339: attribute_hidden;
340: extern ssize_t writeall (int fd, const void *buf, size_t len)
341: attribute_hidden;
342: extern ssize_t sendfileall (int tofd, int fromfd, off_t off, size_t len)
343: attribute_hidden;
344:
345: #endif