source: trunk/include/slib.h@ 509

Last change on this file since 509 was 481, checked in by katerina, 9 years ago

Enhancements and fixes for tickets #374, #375, #376, #377, #378, and #379.

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