source: trunk/include/slib.h@ 581

Last change on this file since 581 was 568, checked in by katerina, 3 years ago

Fix for ticket #458 (inotify issue).

File size: 16.8 KB
Line 
1/* --------------------------------------------------------------
2 *
3 * The developement of this library has been stimulated by reading
4 * a paper on 'Robust Programming' by Matt Bishop, although
5 * not all of his ideas might be implemented in the same
6 * strictness as discussed in the paper.
7 *
8 * --------------------------------------------------------------
9 */
10
11#ifndef SL_SLIB_H
12#define SL_SLIB_H
13
14#include <errno.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <stdarg.h>
18#include <sys/types.h>
19
20#include "config_xor.h"
21
22#ifdef HAVE_UNISTD_H
23#include <unistd.h>
24#endif
25
26#include "sh_string.h"
27
28/****************
29
30 -- Defined in config.h. --
31
32 #ifndef _(string)
33 #define _(string) string
34 #endif
35
36 #ifndef N_(string)
37 #define N_(string) string
38 #endif
39
40*****************/
41
42
43/* --------------------------------------------------------------
44 *
45 * Typedefs, global variables, macros.
46 *
47 * --------------------------------------------------------------
48 */
49
50extern long int sl_errno; /* Global error variable. */
51
52
53/* The ticketing system; used to hide internals from the
54 * programmer.
55 */
56typedef long int SL_TICKET; /* Unique ID for opened files. */
57
58
59/*
60 * TRUE, FALSE
61 */
62#if !defined(S_TRUE)
63#define S_TRUE 1
64#define S_FALSE 0
65#endif
66
67#define SH_GRBUF_SIZE 4096
68#define SH_PWBUF_SIZE 32768
69
70
71#if defined(__GNUC__) && (__GNUC__ >= 3)
72#undef SL_GNUC_CONST
73#define SL_GNUC_CONST __attribute__((const))
74#else
75#undef SL_GNUC_CONST
76#define SL_GNUC_CONST
77#endif
78
79/*
80 * The following macros are provided:
81 *
82 * SL_ISERROR(x) TRUE if return status of 'x' is an error code.
83 * SL_REQUIRE(x, xstr) Abort if 'x' is false.
84 * SL_ENTER(s) Trace entry in function 's'.
85 * SL_RETURN(x, s) Trace return from function 's'.
86 */
87
88
89/*
90 * The error codes.
91 */
92#define SL_ENONE 0
93
94#define SL_ENULL -1024 /* Invalid use of NULL pointer. */
95#define SL_ERANGE -1025 /* Argument out of range. */
96#define SL_ETRUNC -1026 /* Result truncated. */
97#define SL_EREPEAT -1027 /* Illegal repeated use of function. */
98
99#define SL_EINTERNAL -1028 /* Internal error. */
100#define SL_ETICKET -1029 /* Bad ticket. */
101#define SL_EBADFILE -1030 /* File access error. Check errno. */
102#define SL_EBOGUS -1031 /* Bogus file. */
103#define SL_EMEM -1032 /* Out of memory. */
104#define SL_EUNLINK -1033 /* Unlink error. Check errno. */
105#define SL_EREWIND -1034 /* Rewind error. Check errno. */
106#define SL_EFORWARD -1035 /* Forward error. Check errno. */
107#define SL_EREAD -1036 /* Read error. Check errno. */
108#define SL_EWRITE -1037 /* Write error. Check errno. */
109#define SL_ESYNC -1038 /* Write error. Check errno. */
110#define SL_ECLOSE -1039 /* Close error. Check errno. */
111
112#define SL_EBADNAME -1040 /* Invalid name. */
113#define SL_ESTAT -1041 /* stat of file failed. Check errno. */
114#define SL_EFSTAT -1042 /* fstat of file failed. Check errno. */
115
116#define SL_EBADUID -1050 /* Owner not trustworthy. */
117#define SL_EBADGID -1051 /* Group writeable and not trustworthy.*/
118#define SL_EBADOTH -1052 /* World writeable. */
119
120#define SL_TOOMANY -1053 /* Too many open files */
121#define SL_TIMEOUT -1054 /* Timeout in read */
122
123#define SL_EISDIR -1055 /* Is a directory */
124
125#define SL_EINTERNAL01 -1061 /* Internal error. */
126#define SL_EINTERNAL02 -1062 /* Internal error. */
127#define SL_EINTERNAL03 -1063 /* Internal error. */
128#define SL_EINTERNAL04 -1064 /* Internal error. */
129#define SL_EINTERNAL05 -1065 /* Internal error. */
130#define SL_EINTERNAL06 -1066 /* Internal error. */
131#define SL_EINTERNAL07 -1067 /* Internal error. */
132#define SL_EINTERNAL08 -1068 /* Internal error. */
133#define SL_EINTERNAL09 -1069 /* Internal error. */
134#define SL_EINTERNAL10 -1070 /* Internal error. */
135#define SL_EINTERNAL11 -1071 /* Internal error. */
136#define SL_EINTERNAL12 -1072 /* Internal error. */
137
138/*
139 * All int functions return SL_NONE on success.
140 */
141
142#ifdef __cplusplus
143extern "C" {
144#endif
145
146 int dlog (int flag, const char * file, int line, const char *fmt, ...);
147
148 char * sl_get_errmsg(void);
149
150 /* ----------------------------------------------------------------
151 *
152 * Heap consistency routines
153 *
154 * ---------------------------------------------------------------- */
155
156 int sl_test_heap(void);
157
158 /* ----------------------------------------------------------------
159 *
160 * Capability routines
161 *
162 * ---------------------------------------------------------------- */
163
164 extern int sl_useCaps;
165
166 int sl_drop_cap (void);
167 int sl_drop_cap_sub(void);
168 int sl_get_cap_sub(void);
169 int sl_drop_cap_qdel(void);
170 int sl_get_cap_qdel(void);
171
172 /* ----------------------------------------------------------------
173 *
174 * String handling routines
175 *
176 * ---------------------------------------------------------------- */
177
178 /*
179 * A memset that does not get optimized away
180 */
181 void *sl_memset(void *s, int c, size_t n);
182#if !defined(SH_REAL_SET)
183#undef memset
184#define memset sl_memset
185#endif
186
187 /*
188 * Copy src to dst. siz is the length of dst.
189 */
190 int sl_strlcpy(char * dst, /*@null@*/const char * src, size_t siz);
191
192 /*
193 * Append src to dst. siz is the length of dst.
194 */
195 int sl_strlcat(char * dst, /*@null@*/const char *src, size_t siz);
196
197 /*
198 * An implementation of vsnprintf. va_start/va_end are in the caller
199 * function.
200 */
201 int sl_vsnprintf(char *str, size_t n,
202 const char *format, va_list vl );
203
204 /*
205 * An implementation of snprintf.
206 */
207 int sl_snprintf(char *str, size_t n,
208 const char *format, ... );
209
210 /*
211 * A robust drop-in replacement of strncpy. strlcpy is preferable.
212 */
213 char * sl_strncpy(/*@out@*/char *dst, const char *src, size_t size);
214
215 /*
216 * Robust strncat.
217 */
218 char * sl_strncat(char *dst, const char *src, size_t n);
219
220 /*
221 * strstr
222 */
223 char * sl_strstr (const char * haystack, const char * needle);
224
225 /*
226 * robust strn[case]cmp replacement
227 */
228 int sl_strncmp(const char * a, const char * b, size_t n);
229 int sl_ts_strncmp(const char * a, const char * b, size_t n);
230
231 int sl_strncasecmp(const char * a, const char * b, size_t n);
232
233 /*
234 * robust strcmp replacement
235 */
236 int sl_strcmp(const char * a, const char * b);
237
238 /*
239 * robust strcasecmp replacement
240 */
241 int sl_strcasecmp(const char * one, const char * two);
242
243 /*
244 * robust strlen replacement
245 */
246#define sl_strlen(arg) ((arg == NULL) ? 0 : (strlen(arg)))
247
248 /* ----------------------------------------------------------------
249 *
250 * Privilege handling routines
251 *
252 * ---------------------------------------------------------------- */
253
254 /*
255 * ONE OF THE FOLLOWING THREE FUNCTIONS
256 * SHOULD BE CALLED BEFORE ANY OTHER OF THE
257 * UID HANDLING FUNCTIONS.
258 */
259 int sl_policy_get_user(const char *username); /* drop SUID to <username> */
260 int sl_policy_get_real(char *username); /* drop privs to <username> */
261 int sl_policy_get_root(void); /* drop SUID to root */
262
263 /*
264 * If not using one of the above, use this function,
265 * and then call sh_unset_suid().
266 * This function saves the uid's.
267 * It calls abort() on error.
268 */
269 int sl_save_uids(void);
270
271 /*
272 * This function returns the saved euid.
273 * It calls abort() if the uid's are not saved already.
274 */
275 int sl_get_euid(/*@out@*/uid_t * ret);
276 uid_t sl_ret_euid(void);
277
278 /*
279 * This function returns the saved egid.
280 * It calls abort() if the uid's are not saved already.
281 */
282 int sl_get_egid(/*@out@*/gid_t * ret);
283
284 /*
285 * This function returns the saved current ruid.
286 * It calls abort() if the uid's are not saved already.
287 */
288 int sl_get_ruid(/*@out@*/uid_t * ret);
289
290 /*
291 * This function returns the saved current rgid.
292 * It calls abort() if the uid's are not saved already.
293 */
294 int sl_get_rgid(gid_t * ret);
295
296 /*
297 * This function returns the saved original ruid.
298 * It calls abort() if the uid's are not saved already.
299 */
300 int sl_get_ruid_orig(uid_t * ret);
301
302 /*
303 * This function returns the saved original rgid.
304 * It calls abort() if the uid's are not saved already.
305 */
306 int sl_get_rgid_orig(gid_t * ret);
307
308 /*
309 * This function returns true if the program is SUID.
310 * It calls abort() if the uid's are not saved already.
311 */
312 int sl_is_suid(void);
313
314 /*
315 * This function sets the effective uid
316 * to the saved effective uid.
317 */
318 int sl_set_suid (void);
319
320 /*
321 * This function sets the effective uid to the real uid.
322 */
323 int sl_unset_suid (void);
324
325 /*
326 * This function drops SUID privileges irrevocably.
327 */
328 int sl_drop_privileges(void);
329
330 /* ----------------------------------------------------------------
331 *
332 * File handling routines
333 *
334 * ---------------------------------------------------------------- */
335
336#define SL_OFILE_SIZE 32
337
338 char * sl_check_badfd();
339 char * sl_check_stale();
340
341 /* Create a file record for an open file
342 */
343 SL_TICKET sl_make_ticket (const char * ofile, int oline,
344 int fd, const char * filename, FILE * stream);
345
346 /* Get the pointer to a stream. If none exists yet, open it
347 */
348 FILE * sl_stream (SL_TICKET ticket, char * mode);
349
350 /* Open for writing.
351 */
352 SL_TICKET sl_open_write (const char * ofile, int oline,
353 const char * fname, int priviledge_mode);
354
355 /* Open for reading.
356 */
357 SL_TICKET sl_open_read (const char * ofile, int oline,
358 const char * fname, int priviledge_mode);
359
360 /* Drop from cach when closing
361 */
362 int sl_set_drop_cache(const char * str);
363
364 /* Open for reading w/minimum checking.
365 */
366 SL_TICKET sl_open_fastread (const char * ofile, int oline,
367 const char * fname, int priviledge_mode);
368
369 /* Open for read and write.
370 */
371 SL_TICKET sl_open_rdwr (const char * ofile, int oline,
372 const char * fname, int priviledge_mode);
373
374 /* Open for read and write, fail if file exists.
375 */
376 SL_TICKET sl_open_safe_rdwr (const char * ofile, int oline,
377 const char * fname, int priv);
378
379 /* Open for write, truncate.
380 */
381 SL_TICKET sl_open_write_trunc (const char * ofile, int oline,
382 const char * fname, int priviledge_mode);
383
384 /* Open for read and write, truncate.
385 */
386 SL_TICKET sl_open_rdwr_trunc (const char * ofile, int oline,
387 const char * fname, int priviledge_mode);
388
389 /* Initialize the content sh_string.
390 */
391 int sl_init_content (SL_TICKET ticket, size_t size);
392
393 /* Get the (pointer to) the content sh_string.
394 */
395 sh_string * sl_get_content (SL_TICKET ticket);
396
397 /* Lock file (uses fcntl F_SETLK).
398 */
399 int sl_lock (SL_TICKET ticket);
400
401 /* Close file.
402 */
403 int sl_close (SL_TICKET ticket);
404
405 /* Close file descriptor.
406 */
407 int sl_close_fd (const char * file, int line, int fd);
408
409 /* Close stream.
410 */
411 int sl_fclose (const char * file, int line, FILE * fp);
412
413 /* Unlink file.
414 */
415 int sl_unlink (SL_TICKET ticket);
416
417 /* Rewind file.
418 */
419 int sl_rewind (SL_TICKET ticket);
420
421 /* Seek file.
422 */
423 int sl_seek (SL_TICKET ticket, off_t off_data);
424
425 /* Forward file.
426 */
427 int sl_forward (SL_TICKET ticket);
428
429 /* Sync file.
430 */
431 int sl_sync (SL_TICKET ticket);
432
433 /* Read file.
434 */
435 int sl_read (SL_TICKET ticket, void * buf, size_t count);
436
437 int sl_read_timeout_prep (SL_TICKET ticket);
438
439 int sl_read_timeout_fd (int fd, void * buf,
440 size_t count, int timeout, int is_nonblocking);
441
442 int sl_read_timeout_fd_once (int fd, void * buf,
443 size_t count, int timeout, int is_nonblocking);
444
445 int sl_read_timeout (SL_TICKET ticket, void * buf,
446 size_t count, int timeout, int is_nonblocking);
447
448 int sl_read_fast (SL_TICKET ticket, void * buf_in, size_t count);
449
450 /* Write file.
451 */
452 int sl_write (SL_TICKET ticket, const void * msg, long nbytes);
453
454 /* Write file, terminate with newline.
455 */
456 int sl_write_line (SL_TICKET ticket, const void * msg, long nbytes);
457
458 /* As above, but only for non-constant strings.
459 */
460 int sl_write_line_fast (SL_TICKET ticket, void * msg, long nbytes);
461
462 /* Drop all metadata for file descriptors >= fd.
463 */
464 int sl_dropall(int fd, int except);
465 int sl_dropall_dirty(int fd, int except); /* don't deallocate */
466
467 /* Check whether file is trustworthy.
468 */
469 int sl_trustfile(const char * path, uid_t * ok, uid_t * bad);
470
471 /* Check whether file is trustworthy.
472 */
473 int sl_trustfile_euid(const char * filename, uid_t euid);
474
475 /* purge list of trusted users
476 */
477 int sl_trust_purge_user (void);
478
479 /* Add a trusted user.
480 */
481 int sl_trust_add_user (uid_t pwid);
482
483 /* Get error string.
484 */
485 char * sl_error_string(int errorcode);
486
487 /* Get error file.
488 */
489 char * sl_trust_errfile(void);
490
491 /* Overflow tests
492 */
493 int sl_ok_muli (int a, int b) SL_GNUC_CONST;
494 int sl_ok_divi (int a, int b) SL_GNUC_CONST;
495 int sl_ok_addi (int a, int b) SL_GNUC_CONST;
496 int sl_ok_subi (int a, int b) SL_GNUC_CONST;
497
498 int sl_ok_muls (size_t a, size_t b) SL_GNUC_CONST;
499 int sl_ok_adds (size_t a, size_t b) SL_GNUC_CONST;
500
501
502#ifdef __cplusplus
503}
504#endif
505
506/* Privilege modes for file access.
507 */
508#define SL_YESPRIV 0x33
509#define SL_NOPRIV 0x34
510
511/* Suitable for Linux
512 */
513#define MAXFILENAME 4096
514
515
516/*
517 * This macro is TRUE if (x) < 0.
518 */
519#define SL_ISERROR(x) ((long)(x) < 0)
520
521#if defined(WITH_TPT)
522#define TPT(arg) dlog arg ;
523#else
524#define TPT(arg)
525#endif
526
527
528/*
529 * The 'require' macro.
530 */
531#define SL_REQUIRE(assertion, astext) \
532do { \
533 /*@i@*/ if (assertion) ; \
534 else { \
535 dlog(0, FIL__, __LINE__, SDG_AFAIL, \
536 FIL__, __LINE__, astext); \
537 _exit(EXIT_FAILURE); \
538 } \
539} while (0)
540
541
542/*
543 * The enter macro. Prints the trace if TRACE is on.
544 */
545extern int slib_do_trace;
546extern int slib_trace_fd;
547
548#if defined(SL_DEBUG)
549#define SL_ENTER(s) sl_stack_push(s, FIL__, __LINE__);
550#else
551#define SL_ENTER(s) if (slib_do_trace != 0) sl_trace_in(s, FIL__, __LINE__);
552#endif
553
554/*
555 * The return macro.
556 */
557#if defined(SL_DEBUG)
558#ifndef S_SPLINT_S
559#define SL_RETURN(x, s) \
560do { \
561 sl_stack_pop(s, FIL__, __LINE__); \
562 return(x); \
563} while(0)
564#else
565/*@notfunction@*/
566#define SL_RETURN(x, s) return(x);
567#endif /* S_SPLINT_S */
568#else
569#ifndef S_SPLINT_S
570#define SL_RETURN(x, s) \
571do { \
572 if (slib_do_trace != 0) \
573 sl_trace_out(s, FIL__, __LINE__); \
574 return(x); \
575} while(0)
576#else
577/*@notfunction@*/
578#define SL_RETURN(x, s) return(x);
579#endif /* S_SPLINT_S */
580#endif /* SL_RETURN macro */
581
582#if defined(SL_DEBUG)
583#define SL_RET0(s) \
584do { \
585 sl_stack_pop(s, FIL__, __LINE__); \
586 return; \
587} while(0)
588#else
589#ifndef S_SPLINT_S
590#define SL_RET0(s) \
591do { \
592 if (slib_do_trace != 0) \
593 sl_trace_out(s, FIL__, __LINE__); \
594 return; \
595} while(0)
596#else
597/*@notfunction@*/
598#define SL_RET0(s) return;
599#endif /* S_SPLINT_S */
600#endif /* SL_RETURN macro */
601
602#if defined(SL_DEBUG)
603void sl_stack_push(char * c, char * file, int line);
604void sl_stack_pop(char * c, char * file, int line);
605void sl_stack_print(void);
606#endif
607void sl_trace_in (const char * str, const char * file, int line);
608void sl_trace_out (const char * str, const char * file, int line);
609int sl_trace_file (const char * str);
610int sl_trace_use (const char * str);
611
612
613
614
615/*
616 * The internal return macro. Sets sl_errno to the return value.
617 */
618
619#if defined(SL_DEBUG)
620#define SL_IRETURN(x, s) \
621do { \
622 if((long)(x) < 0) { \
623 TPT((0, FIL__, __LINE__, SDG_ERROR, (long)(x))) \
624 sl_errno=(x); \
625 } \
626 sl_stack_pop(s, FIL__, __LINE__); \
627 if (1) return(x); \
628} while(0)
629#else
630#define SL_IRETURN(x, s) \
631do { \
632 if ((long)(x) < 0) sl_errno=(x); \
633 if (slib_do_trace) \
634 sl_trace_out(s, FIL__, __LINE__); \
635 if (1) return(x); \
636} while(0)
637
638#endif /* SL_IRETURN macro */
639
640
641
642/* slib.h */
643#endif
644
645
646
647
Note: See TracBrowser for help on using the repository browser.