source: trunk/include/slib.h@ 270

Last change on this file since 270 was 252, checked in by katerina, 15 years ago

Add code to check for stale file records on close() and fclose(), fix sl_close() to handle open stream (ticket #163).

File size: 16.5 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 strncmp replacement
223 */
224 int sl_strncmp(const char * a, const char * b, size_t n);
225
226 /*
227 * robust strcmp replacement
228 */
229 int sl_strcmp(const char * a, const char * b);
230
231 /*
232 * robust strcasecmp replacement
233 */
234 int sl_strcasecmp(const char * one, const char * two);
235
236 /*
237 * robust strlen replacement
238 */
239#define sl_strlen(arg) ((arg == NULL) ? 0 : (strlen(arg)))
240
241 /* ----------------------------------------------------------------
242 *
243 * Privilege handling routines
244 *
245 * ---------------------------------------------------------------- */
246
247 /*
248 * ONE OF THE FOLLOWING THREE FUNCTIONS
249 * SHOULD BE CALLED BEFORE ANY OTHER OF THE
250 * UID HANDLING FUNCTIONS.
251 */
252 int sl_policy_get_user(const char *username); /* drop SUID to <username> */
253 int sl_policy_get_real(char *username); /* drop privs to <username> */
254 int sl_policy_get_root(void); /* drop SUID to root */
255
256 /*
257 * If not using one of the above, use this function,
258 * and then call sh_unset_suid().
259 * This function saves the uid's.
260 * It calls abort() on error.
261 */
262 int sl_save_uids(void);
263
264 /*
265 * This function returns the saved euid.
266 * It calls abort() if the uid's are not saved already.
267 */
268 int sl_get_euid(/*@out@*/uid_t * ret);
269 uid_t sl_ret_euid(void);
270
271 /*
272 * This function returns the saved egid.
273 * It calls abort() if the uid's are not saved already.
274 */
275 int sl_get_egid(/*@out@*/gid_t * ret);
276
277 /*
278 * This function returns the saved current ruid.
279 * It calls abort() if the uid's are not saved already.
280 */
281 int sl_get_ruid(/*@out@*/uid_t * ret);
282
283 /*
284 * This function returns the saved current rgid.
285 * It calls abort() if the uid's are not saved already.
286 */
287 int sl_get_rgid(gid_t * ret);
288
289 /*
290 * This function returns the saved original ruid.
291 * It calls abort() if the uid's are not saved already.
292 */
293 int sl_get_ruid_orig(uid_t * ret);
294
295 /*
296 * This function returns the saved original rgid.
297 * It calls abort() if the uid's are not saved already.
298 */
299 int sl_get_rgid_orig(gid_t * ret);
300
301 /*
302 * This function returns true if the program is SUID.
303 * It calls abort() if the uid's are not saved already.
304 */
305 int sl_is_suid(void);
306
307 /*
308 * This function sets the effective uid
309 * to the saved effective uid.
310 */
311 int sl_set_suid (void);
312
313 /*
314 * This function sets the effective uid to the real uid.
315 */
316 int sl_unset_suid (void);
317
318 /*
319 * This function drops SUID privileges irrevocably.
320 */
321 int sl_drop_privileges(void);
322
323 /* ----------------------------------------------------------------
324 *
325 * File handling routines
326 *
327 * ---------------------------------------------------------------- */
328
329#define SL_OFILE_SIZE 32
330
331 char * sl_check_badfd();
332 char * sl_check_stale();
333
334 /* Create a file record for an open file
335 */
336 SL_TICKET sl_make_ticket (const char * ofile, int oline,
337 int fd, const char * filename, FILE * stream);
338
339 /* Get the pointer to a stream. If none exists yet, open it
340 */
341 FILE * sl_stream (SL_TICKET ticket, char * mode);
342
343 /* Open for writing.
344 */
345 SL_TICKET sl_open_write (const char * ofile, int oline,
346 const char * fname, int priviledge_mode);
347
348 /* Open for reading.
349 */
350 SL_TICKET sl_open_read (const char * ofile, int oline,
351 const char * fname, int priviledge_mode);
352
353 /* Drop from cach when closing
354 */
355 int sl_set_drop_cache(const char * str);
356
357 /* Open for reading w/minimum checking.
358 */
359 SL_TICKET sl_open_fastread (const char * ofile, int oline,
360 const char * fname, int priviledge_mode);
361
362 /* Open for read and write.
363 */
364 SL_TICKET sl_open_rdwr (const char * ofile, int oline,
365 const char * fname, int priviledge_mode);
366
367 /* Open for read and write, fail if file exists.
368 */
369 SL_TICKET sl_open_safe_rdwr (const char * ofile, int oline,
370 const char * fname, int priv);
371
372 /* Open for write, truncate.
373 */
374 SL_TICKET sl_open_write_trunc (const char * ofile, int oline,
375 const char * fname, int priviledge_mode);
376
377 /* Open for read and write, truncate.
378 */
379 SL_TICKET sl_open_rdwr_trunc (const char * ofile, int oline,
380 const char * fname, int priviledge_mode);
381
382 /* Initialize the content sh_string.
383 */
384 int sl_init_content (SL_TICKET ticket, size_t size);
385
386 /* Get the (pointer to) the content sh_string.
387 */
388 sh_string * sl_get_content (SL_TICKET ticket);
389
390 /* Lock file (uses fcntl F_SETLK).
391 */
392 int sl_lock (SL_TICKET ticket);
393
394 /* Close file.
395 */
396 int sl_close (SL_TICKET ticket);
397
398 /* Close file descriptor.
399 */
400 int sl_close_fd (const char * file, int line, int fd);
401
402 /* Close stream.
403 */
404 int sl_fclose (const char * file, int line, FILE * fp);
405
406 /* Unlink file.
407 */
408 int sl_unlink (SL_TICKET ticket);
409
410 /* Rewind file.
411 */
412 int sl_rewind (SL_TICKET ticket);
413
414 /* Seek file.
415 */
416 int sl_seek (SL_TICKET ticket, off_t off_data);
417
418 /* Forward file.
419 */
420 int sl_forward (SL_TICKET ticket);
421
422 /* Sync file.
423 */
424 int sl_sync (SL_TICKET ticket);
425
426 /* Read file.
427 */
428 int sl_read (SL_TICKET ticket, void * buf, size_t count);
429
430 int sl_read_timeout_prep (SL_TICKET ticket);
431
432 int sl_read_timeout_fd (int fd, void * buf,
433 size_t count, int timeout, int is_nonblocking);
434
435 int sl_read_timeout (SL_TICKET ticket, void * buf,
436 size_t count, int timeout, int is_nonblocking);
437
438 int sl_read_fast (SL_TICKET ticket, void * buf_in, size_t count);
439
440 /* Write file.
441 */
442 int sl_write (SL_TICKET ticket, const void * msg, long nbytes);
443
444 /* Write file, terminate with newline.
445 */
446 int sl_write_line (SL_TICKET ticket, const void * msg, long nbytes);
447
448 /* As above, but only for non-constant strings.
449 */
450 int sl_write_line_fast (SL_TICKET ticket, void * msg, long nbytes);
451
452 /* Drop all metadata for file descriptors >= fd.
453 */
454 int sl_dropall(int fd, int except);
455 int sl_dropall_dirty(int fd, int except); /* don't deallocate */
456
457 /* Check whether file is trustworthy.
458 */
459 int sl_trustfile(const char * path, uid_t * ok, uid_t * bad);
460
461 /* Check whether file is trustworthy.
462 */
463 int sl_trustfile_euid(const char * filename, uid_t euid);
464
465 /* purge list of trusted users
466 */
467 int sl_trust_purge_user (void);
468
469 /* Add a trusted user.
470 */
471 int sl_trust_add_user (uid_t pwid);
472
473 /* Get error string.
474 */
475 char * sl_error_string(int errorcode);
476
477 /* Get error file.
478 */
479 char * sl_trust_errfile(void);
480
481 /* Overflow tests
482 */
483 int sl_ok_muli (int a, int b) SL_GNUC_CONST;
484 int sl_ok_divi (int a, int b) SL_GNUC_CONST;
485 int sl_ok_addi (int a, int b) SL_GNUC_CONST;
486 int sl_ok_subi (int a, int b) SL_GNUC_CONST;
487
488 int sl_ok_muls (size_t a, size_t b) SL_GNUC_CONST;
489 int sl_ok_adds (size_t a, size_t b) SL_GNUC_CONST;
490
491
492#ifdef __cplusplus
493}
494#endif
495
496/* Privilege modes for file access.
497 */
498#define SL_YESPRIV 0x33
499#define SL_NOPRIV 0x34
500
501/* Suitable for Linux
502 */
503#define MAXFILENAME 4096
504
505
506/*
507 * This macro is TRUE if (x) < 0.
508 */
509#define SL_ISERROR(x) ((long)(x) < 0)
510
511#if defined(WITH_TPT)
512#define TPT(arg) dlog arg ;
513#else
514#define TPT(arg)
515#endif
516
517
518/*
519 * The 'require' macro.
520 */
521#define SL_REQUIRE(assertion, astext) \
522do { \
523 /*@i@*/ if (assertion) ; \
524 else { \
525 dlog(0, FIL__, __LINE__, SDG_AFAIL, \
526 FIL__, __LINE__, astext); \
527 _exit(EXIT_FAILURE); \
528 } \
529} while (0)
530
531
532/*
533 * The enter macro. Prints the trace if TRACE is on.
534 */
535extern int slib_do_trace;
536extern int slib_trace_fd;
537
538#if defined(SL_DEBUG)
539#define SL_ENTER(s) sl_stack_push(s, FIL__, __LINE__);
540#else
541#define SL_ENTER(s) if (slib_do_trace != 0) sl_trace_in(s, FIL__, __LINE__);
542#endif
543
544/*
545 * The return macro.
546 */
547#if defined(SL_DEBUG)
548#ifndef S_SPLINT_S
549#define SL_RETURN(x, s) \
550do { \
551 sl_stack_pop(s, FIL__, __LINE__); \
552 return(x); \
553} while(0)
554#else
555/*@notfunction@*/
556#define SL_RETURN(x, s) return(x);
557#endif /* S_SPLINT_S */
558#else
559#ifndef S_SPLINT_S
560#define SL_RETURN(x, s) \
561do { \
562 if (slib_do_trace != 0) \
563 sl_trace_out(s, FIL__, __LINE__); \
564 return(x); \
565} while(0)
566#else
567/*@notfunction@*/
568#define SL_RETURN(x, s) return(x);
569#endif /* S_SPLINT_S */
570#endif /* SL_RETURN macro */
571
572#if defined(SL_DEBUG)
573#define SL_RET0(s) \
574do { \
575 sl_stack_pop(s, FIL__, __LINE__); \
576 return; \
577} while(0)
578#else
579#ifndef S_SPLINT_S
580#define SL_RET0(s) \
581do { \
582 if (slib_do_trace != 0) \
583 sl_trace_out(s, FIL__, __LINE__); \
584 return; \
585} while(0)
586#else
587/*@notfunction@*/
588#define SL_RET0(s) return;
589#endif /* S_SPLINT_S */
590#endif /* SL_RETURN macro */
591
592#if defined(SL_DEBUG)
593void sl_stack_push(char * c, char * file, int line);
594void sl_stack_pop(char * c, char * file, int line);
595void sl_stack_print(void);
596#endif
597void sl_trace_in (const char * str, const char * file, int line);
598void sl_trace_out (const char * str, const char * file, int line);
599int sl_trace_file (const char * str);
600int sl_trace_use (const char * str);
601
602
603
604
605/*
606 * The internal return macro. Sets sl_errno to the return value.
607 */
608
609#if defined(SL_DEBUG)
610#define SL_IRETURN(x, s) \
611do { \
612 if((long)(x) < 0) { \
613 TPT((0, FIL__, __LINE__, SDG_ERROR, (long)(x))) \
614 sl_errno=(x); \
615 } \
616 sl_stack_pop(s, FIL__, __LINE__); \
617 if (1) return(x); \
618} while(0)
619#else
620#define SL_IRETURN(x, s) \
621do { \
622 if ((long)(x) < 0) sl_errno=(x); \
623 if (slib_do_trace) \
624 sl_trace_out(s, FIL__, __LINE__); \
625 if (1) return(x); \
626} while(0)
627
628#endif /* SL_IRETURN macro */
629
630
631
632/* slib.h */
633#endif
634
635
636
637
Note: See TracBrowser for help on using the repository browser.