summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2003-02-21 16:34:45 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2003-02-21 16:34:45 +0000
commit8965598e2b2a6ec0802ec7f09ba0d80b265cfbbd (patch)
tree42b18162af9f6dfc2401309518cad784a22eaedb
parent46a29263c316b1e9d5bf478a2a1f58c905929276 (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.c87
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));