diff --git a/ipmitool/include/ipmitool/helper.h b/ipmitool/include/ipmitool/helper.h index 9fae8d0..73a3374 100644 --- a/ipmitool/include/ipmitool/helper.h +++ b/ipmitool/include/ipmitool/helper.h @@ -50,10 +50,12 @@ unsigned short buf2short(unsigned char * buf); uint32_t buf2long(unsigned char * buf); const char * buf2str(unsigned char * buf, int len); void printbuf(const unsigned char * buf, int len, const char * desc); - void signal_handler(int sig, void * handler); - unsigned char ipmi_csum(unsigned char * d, int s); +int ipmi_open_file(const char * file, int flags); + +#define ipmi_open_file_read(file) ipmi_open_file(file, 0) +#define ipmi_open_file_write(file) ipmi_open_file(file, 1) #define SIG_IGNORE(s) ((void)signal((s), SIG_IGN)) #define SIG_DEFAULT(s) ((void)signal((s), SIG_DFL)) diff --git a/ipmitool/lib/helper.c b/ipmitool/lib/helper.c index 68ca07e..c81a9b8 100644 --- a/ipmitool/lib/helper.c +++ b/ipmitool/lib/helper.c @@ -39,6 +39,12 @@ #include #include #include +#include +#include +#include +#include +#include + #include uint32_t buf2long(unsigned char * buf) @@ -145,3 +151,67 @@ unsigned char ipmi_csum(unsigned char * d, int s) return -c; } +/* safely open a file for reading or writing + * file: filename + * rw: read-write flag, 1=write + */ +int ipmi_open_file(const char * file, int rw) +{ + struct stat st1, st2; + int fp; + + /* verify existance */ + if (lstat(file, &st1) < 0) { + if (rw) { + /* does not exist, ok to create */ + fp = open(file, O_WRONLY|O_TRUNC|O_EXCL|O_CREAT, 0600); + if (fp < 0) { + printf("ERROR: Unable to open file %s for write: %s\n", + file, strerror(errno)); + return -1; + } + return fp; + } else { + printf("ERROR: File %s does not exist\n", file); + return -1; + } + } + + /* it exists - only regular files, not links */ + if (!S_ISREG(st1.st_mode)) { + printf("ERROR: File %s has invalid mode: %d\n", file, st1.st_mode); + return -1; + } + + /* allow only files with 1 link (itself) */ + if (st1.st_nlink != 1) { + printf("ERROR: File %s has invalid link count: %d != 1\n", + file, (int)st1.st_nlink); + return -1; + } + + fp = open(file, rw ? (O_WRONLY|O_TRUNC) : O_RDONLY, 0600); + if (fp < 0) { + printf("ERROR: Unable to open file %s: %s\n", + file, strerror(errno)); + return -1; + } + + /* stat again */ + if (fstat(fp, &st2) < 0) { + close(fp); + return -1; + } + + /* verify inode, owner, link count */ + if (st2.st_ino != st1.st_ino || + st2.st_uid != st1.st_uid || + st2.st_nlink != 1) { + printf("ERROR: Unable to verify file %s\n", file); + close(fp); + return -1; + } + + return fp; +} + diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index 654425d..af0f73f 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/lib/ipmi_sdr.c @@ -38,11 +38,8 @@ #include #include -#include #include -#include #include -#include #include #include @@ -1388,51 +1385,13 @@ ipmi_sdr_print_info(struct ipmi_intf * intf) static int ipmi_sdr_dump_bin(struct ipmi_intf * intf, const char * ofile) { - struct stat st1, st2; struct sdr_get_rs * header; struct ipmi_sdr_iterator * itr; int fd; - /* open file for writing */ - if (lstat(ofile, &st1) < 0) { - /* does not exist, ok to create */ - fd = open(ofile, O_WRONLY|O_TRUNC|O_EXCL|O_CREAT, 0600); - if (fd < 1) { - printf("ERROR: Unable to open file '%s' for write: %s\n", - ofile, strerror(errno)); - return -1; - } - } else { - /* it exists - allow only regular file, not links */ - if (!S_ISREG(st1.st_mode)) { - printf("ERROR: file '%s' has invalid mode: %d\n", - ofile, st1.st_mode); - return -1; - } - - /* allow only files with 1 link (itself) */ - if (st1.st_nlink != 1) { - printf("ERROR: file '%s' has invalid link count: %d != 1\n", - ofile, (int)st1.st_nlink); - return -1; - } - - /* open it for write, overwrite existing file */ - fd = open(ofile, O_WRONLY | O_TRUNC, 0600); - if (fd < 1) { - printf("ERROR: unable to overwrite file '%s': %s\n", - ofile, strerror(errno)); - return -1; - } - - /* stat again and verify inode/owner/link count */ - fstat(fd, &st2); - if (st2.st_ino != st1.st_ino || st2.st_uid != st1.st_uid || - st2.st_nlink != 1) { - printf("ERROR: unable to verify file '%s'\n", ofile); - close(fd); - return -1; - } + fd = ipmi_open_file_write(ofile); + if (fd < 0) { + return -1; } /* open connection to SDR */ diff --git a/ipmitool/src/ipmitool.c b/ipmitool/src/ipmitool.c index 007ccdd..fffbb8a 100644 --- a/ipmitool/src/ipmitool.c +++ b/ipmitool/src/ipmitool.c @@ -35,14 +35,10 @@ */ #include -#include #include -#include #include #include #include -#include -#include #include #include @@ -160,38 +156,14 @@ static void usage(void) } -static char * ipmi_password_file_read(char * file) +static char * ipmi_password_file_read(char * filename) { - struct stat st1, st2; int fp; char * pass = NULL; - /* verify existance */ - if (lstat(file, &st1) < 0) { - return NULL; - } - - /* only regular files: no links */ - if (!S_ISREG(st1.st_mode) || st1.st_nlink != 1) { - return NULL; - } - - /* open it read-only */ - if ((fp = open(file, O_RDONLY, 0)) < 0) { - return NULL; - } - - /* stat again */ - if (fstat(fp, &st2) < 0) { - close(fp); - return NULL; - } - - /* verify inode, owner, link count */ - if (st2.st_ino != st1.st_ino || - st2.st_uid != st1.st_uid || - st2.st_nlink != 1) { - close(fp); + fp = ipmi_open_file_read((const char *)filename); + if (fp < 0) { + printf("Unable to open password file %s\n", filename); return NULL; } @@ -207,9 +179,7 @@ static char * ipmi_password_file_read(char * file) return NULL; } - /* close file */ close(fp); - return pass; }