source: trunk/include/slib.h@ 351

Last change on this file since 351 was 272, checked in by katerina, 15 years ago

Fixes tickets #190, #191, #192, #193, and #194.

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