diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2003-02-21 16:34:45 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2003-02-21 16:34:45 +0000 |
commit | 8965598e2b2a6ec0802ec7f09ba0d80b265cfbbd (patch) | |
tree | 42b18162af9f6dfc2401309518cad784a22eaedb | |
parent | 46a29263c316b1e9d5bf478a2a1f58c905929276 (diff) |
fix restarts.
the etag-state file wasn't readable after chroot and privilege drop.
therefore, make it root.www 640.
split the read and write portions to their own functions, and in init_etag,
try to write the etag-state; in case of any problem with that, create a new
one and read that.
-rw-r--r-- | usr.sbin/httpd/src/main/http_protocol.c | 87 |
1 files changed, 52 insertions, 35 deletions
diff --git a/usr.sbin/httpd/src/main/http_protocol.c b/usr.sbin/httpd/src/main/http_protocol.c index 85b5a7c6db8..3f53a96a175 100644 --- a/usr.sbin/httpd/src/main/http_protocol.c +++ b/usr.sbin/httpd/src/main/http_protocol.c @@ -3189,69 +3189,86 @@ API_EXPORT(void) ap_send_error_response(request_rec *r, int recursive_error) */ static AP_SHA1_CTX baseCtx; -API_EXPORT(void) ap_init_etag(pool *pconf) +int ap_create_etag_state(pool *pconf) { - struct stat st; u_int32_t rnd; unsigned int u; int fd; const char* filename; - ap_SHA1Init(&baseCtx); - filename = ap_server_root_relative(pconf, "logs/etag-state"); - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, NULL, - "Initializing etag from %s", filename); + ap_server_strip_chroot(filename, 0); - if ((fd = open(filename, O_CREAT|O_RDWR|O_NOFOLLOW, 0600)) == -1) { + if ((fd = open(filename, O_CREAT|O_RDWR|O_NOFOLLOW, 0640)) == -1) { ap_log_error(APLOG_MARK, APLOG_CRIT, NULL, - "could not open %s", filename); + "could not create %s", filename); exit(-1); } - if (fstat(fd, &st) == -1) { + if (fchown(fd, -1, ap_group_id) == -1) { ap_log_error(APLOG_MARK, APLOG_CRIT, NULL, - "could not fstat %s", filename); + "could not chown %s", filename); exit(-1); } - if (st.st_size != sizeof(rnd)*4) { - if (st.st_size > 0) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, - "truncating %s from %qd bytes to 0", filename, st.st_size); - } - - if (ftruncate(fd, 0) == -1) { + /* generate random bytes and write them */ + for (u = 0; u < 4; u++) { + rnd = arc4random(); + if (write(fd, &rnd, sizeof(rnd)) == -1) { ap_log_error(APLOG_MARK, APLOG_CRIT, NULL, - "could not truncate %s", filename); + "could not write to %s", filename); exit(-1); } + } - /* generate random bytes and write them */ - for (u = 0; u < 4; u++) { - rnd = arc4random(); - if (write(fd, &rnd, sizeof(rnd)) == -1) { - ap_log_error(APLOG_MARK, APLOG_CRIT, NULL, - "could not write to %s", filename); - exit(-1); - } - } + close (fd); +} - /* rewind */ - if (lseek(fd, 0, SEEK_SET) == -1) { +API_EXPORT(void) ap_init_etag(pool *pconf) +{ + if (ap_read_etag_state(pconf) == -1) { + ap_create_etag_state(pconf); + if (ap_read_etag_state(pconf) == -1) { ap_log_error(APLOG_MARK, APLOG_CRIT, NULL, - "could not seek on %s", filename); + "could not initialize etag state"); exit(-1); } + } +} + +int ap_read_etag_state(pool *pconf) +{ + struct stat st; + u_int32_t rnd; + unsigned int u; + int fd; + const char* filename; + + ap_SHA1Init(&baseCtx); + + filename = ap_server_root_relative(pconf, "logs/etag-state"); + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, NULL, + "Initializing etag from %s", filename); + + ap_server_strip_chroot(filename, 0); + + if ((fd = open(filename, O_RDONLY|O_NOFOLLOW, 0640)) == -1) + return (-1); + + if (fstat(fd, &st) == -1) { + ap_log_error(APLOG_MARK, APLOG_CRIT, NULL, + "could not fstat %s", filename); + exit(-1); + } + + if (st.st_size != sizeof(rnd)*4) { + return (-1); } /* read 4 random 32-bit uints from file and update the hash context */ for (u = 0; u < 4; u++) { - if (read(fd, &rnd, sizeof(rnd)) < sizeof(rnd)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, NULL, - "could not read from %s", filename); - exit(-1); - } + if (read(fd, &rnd, sizeof(rnd)) < sizeof(rnd)) + return (-1); ap_SHA1Update_binary(&baseCtx, (const unsigned char *)&rnd, sizeof(rnd)); |