diff --git a/src/common/safeopen.c b/src/common/safeopen.c new file mode 100644 index 0000000000000000000000000000000000000000..7573853be4c3d0d640c97a2a777c31b71b150050 --- /dev/null +++ b/src/common/safeopen.c @@ -0,0 +1,54 @@ +/* $Id$ */ + +/* safer interface to open() + */ + + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#if HAVE_UNISTD_H +# include <unistd.h> +#endif +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "safeopen.h" + +FILE * safeopen(const char *path, const char *mode, int flags) +{ + int fd; + int oflags; + struct stat fb1, fb2; + + if(mode[0] == 'w') { + oflags = O_WRONLY; + } else if (mode[0] == 'a') { + oflags = O_CREAT | O_WRONLY | O_APPEND; + } else + oflags = O_RDONLY; + + oflags |= !(flags & SAFEOPEN_NOCREATE) ? O_CREAT : 0; + oflags |= (flags & SAFEOPEN_CREATE_ONLY) ? O_EXCL : 0; + + if ((fd = open(path, oflags, S_IRUSR|S_IWUSR)) < 0) + return NULL; + + if (!(flags & SAFEOPEN_LINK_OK)) { + lstat(path, &fb1); + fstat(fd, &fb2); + + if (fb2.st_ino != fb1.st_ino) { + fprintf(stderr, "safeopen(): refusing to open `%s', " + "which is a soft link\n", path); + close(fd); + return NULL; + } + } + + return fdopen(fd, mode); + +} diff --git a/src/common/safeopen.h b/src/common/safeopen.h new file mode 100644 index 0000000000000000000000000000000000000000..cb2948036caa3553090602d6736fdbad41236322 --- /dev/null +++ b/src/common/safeopen.h @@ -0,0 +1,23 @@ +/* $Id$ */ + +/* safer interface to open(): + * + */ + +#ifndef _SAFEOPEN_H +#define _SAFEOPEN_H + +/* safeopen flags: + * + * default is to create if needed, and fail if path is a soft link + */ +#define SAFEOPEN_LINK_OK (1<<0) /* do not check for soft link */ +#define SAFEOPEN_CREATE_ONLY (1<<1) /* create, fail if file exists */ +#define SAFEOPEN_NOCREATE (1<<2) /* fail if file doesn't exist */ + +/* open a file for read, write, or append + * perform some simple sanity checks on file and return stream pointer + */ +FILE *safeopen(const char *path, const char *mode, int flags); + +#endif /* _SAFEOPEN_H */