Commit Diff


commit - 97e0634664f953267d4dca4b99383e4dfb25b817
commit + a0a86356fb75f58f574be3f798b8553f30757553
blob - ebf0ba06b3f3b8c25adc16140de61303b4d6d6b3
blob + 514205b24b104a80a2b51b84839c77490c9f78cf
--- gotwebd/access.c
+++ gotwebd/access.c
@@ -37,13 +37,10 @@ static void
 access_shutdown(void)
 {
 	struct gotwebd *env = gotwebd_env;
-	int i;
 
 	imsgbuf_clear(&env->iev_parent->ibuf);
+	imsgbuf_clear(&env->iev_login->ibuf);
 
-	for (i = 0; i < env->nserver; i++)
-		imsgbuf_clear(&env->iev_login[i].ibuf);
-
 	free(env->iev_parent);
 	free(env->iev_login);
 	free(env);
@@ -193,10 +190,7 @@ access_check(uid_t uid, struct gotwebd_access_rule_lis
 static void
 access_launch(struct gotwebd *env)
 {
-	int i;
-
-	for (i = 0; i < env->nserver; i++)
-		event_add(&env->iev_login[i].ev, NULL);
+	event_add(&env->iev_login->ev, NULL);
 }
 
 static void
@@ -251,14 +245,14 @@ recv_login_pipe(struct gotwebd *env, struct imsg *imsg
 	struct imsgev *iev;
 	int fd;
 
-	if (env->server_cnt >= env->nserver)
-		fatalx("too many login pipes received");
-
 	fd = imsg_get_fd(imsg);
 	if (fd == -1)
 		fatalx("invalid login pipe fd");
 
-	iev = &env->iev_login[env->server_cnt];
+	iev = calloc(1, sizeof(*iev));
+	if (iev == NULL)
+		fatal("calloc");
+
 	if (imsgbuf_init(&iev->ibuf, fd) == -1)
 		fatal("imsgbuf_init");
 	imsgbuf_allow_fdpass(&iev->ibuf);
@@ -268,7 +262,7 @@ recv_login_pipe(struct gotwebd *env, struct imsg *imsg
 	event_set(&iev->ev, fd, EV_READ, access_dispatch_login, iev);
 	imsg_event_add(iev);
 
-	env->server_cnt++;
+	env->iev_login = iev;
 }
 
 static void
@@ -389,11 +383,6 @@ gotwebd_access(struct gotwebd *env, int fd)
 	    env->iev_parent);
 	event_add(&env->iev_parent->ev, NULL);
 
-	env->nserver = env->prefork_gotwebd;
-	env->iev_login = calloc(env->nserver, sizeof(*env->iev_login));
-	if (env->iev_login == NULL)
-		fatal("calloc");
-
 	signal(SIGPIPE, SIG_IGN);
 
 	signal_set(&sighup, SIGHUP, access_sighdlr, env);
blob - 453a31f9322abec89be8bdabd70c4897958d6883
blob + ddc6de1b9c5a3a6800e85b6e3dd01bba38d54cf0
--- gotwebd/gotwebd.c
+++ gotwebd/gotwebd.c
@@ -143,6 +143,22 @@ main_compose_login(struct gotwebd *env, uint32_t type,
 
 	for (i = 0; i < env->nserver; ++i) {
 		ret = send_imsg(&env->iev_login[i], type, fd, data, len);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+int
+main_compose_access(struct gotwebd *env, uint32_t type, int fd,
+    const void *data, uint16_t len)
+{
+	size_t i;
+	int ret = 0;
+
+	for (i = 0; i < env->nserver; ++i) {
+		ret = send_imsg(&env->iev_access[i], type, fd, data, len);
 		if (ret)
 			break;
 	}
@@ -720,9 +736,6 @@ main(int argc, char **argv)
 	env->iev_auth = calloc(1, sizeof(*env->iev_auth));
 	if (env->iev_auth == NULL)
 		fatal("calloc");
-	env->iev_access = calloc(1, sizeof(*env->iev_access));
-	if (env->iev_access == NULL)
-		fatal("calloc");
 	env->nserver = env->prefork_gotwebd;
 	env->iev_server = calloc(env->nserver, sizeof(*env->iev_server));
 	if (env->iev_server == NULL)
@@ -730,14 +743,15 @@ main(int argc, char **argv)
 	env->iev_login = calloc(env->nserver, sizeof(*env->iev_login));
 	if (env->iev_login == NULL)
 		fatal("calloc");
+	env->iev_access = calloc(env->nserver, sizeof(*env->iev_access));
+	if (env->iev_access == NULL)
+		fatal("calloc");
 	env->iev_gotweb = calloc(env->nserver, sizeof(*env->iev_gotweb));
 	if (env->iev_gotweb == NULL)
 		fatal("calloc");
 
 	spawn_process(env, argv0, env->iev_auth, GOTWEBD_PROC_AUTH,
 	    gotwebd_username, gotwebd_dispatch_auth);
-	spawn_process(env, argv0, env->iev_access, GOTWEBD_PROC_ACCESS,
-	    gotwebd_username, gotwebd_dispatch_access);
 
 	for (i = 0; i < env->nserver; ++i) {
 		spawn_process(env, argv0, &env->iev_server[i],
@@ -746,6 +760,9 @@ main(int argc, char **argv)
 		spawn_process(env, argv0, &env->iev_login[i],
 		    GOTWEBD_PROC_LOGIN, gotwebd_username,
 		    gotwebd_dispatch_login);
+		spawn_process(env, argv0, &env->iev_access[i],
+		    GOTWEBD_PROC_ACCESS, gotwebd_username,
+		    gotwebd_dispatch_access);
 		spawn_process(env, argv0, &env->iev_gotweb[i],
 		    GOTWEBD_PROC_GOTWEB, gotwebd_username,
 		    gotwebd_dispatch_gotweb);
@@ -804,13 +821,14 @@ main(int argc, char **argv)
 static void
 connect_children(struct gotwebd *env)
 {
-	struct imsgev *iev_server, *iev_login, *iev_gotweb;
+	struct imsgev *iev_server, *iev_login, *iev_access, *iev_gotweb;
 	int pipe[2];
 	int i;
 
 	for (i = 0; i < env->nserver; i++) {
 		iev_server = &env->iev_server[i];
 		iev_login = &env->iev_login[i];
+		iev_access = &env->iev_access[i];
 		iev_gotweb = &env->iev_gotweb[i];
 
 		if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe) == -1)
@@ -842,7 +860,7 @@ connect_children(struct gotwebd *env)
 		if (send_imsg(iev_login, GOTWEBD_IMSG_CTL_PIPE, pipe[0],
 		    NULL, 0))
 			fatal("send_imsg");
-		if (send_imsg(env->iev_access, GOTWEBD_IMSG_CTL_PIPE, pipe[1],
+		if (send_imsg(iev_access, GOTWEBD_IMSG_CTL_PIPE, pipe[1],
 		    NULL, 0))
 			fatal("send_imsg");
 	}
@@ -860,15 +878,17 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_
 	/* gotweb need to reload its config. */
 	env->servers_pending = env->prefork_gotwebd;
 	env->login_pending = env->prefork_gotwebd;
+	env->access_pending = env->prefork_gotwebd;
 	env->gotweb_pending = env->prefork_gotwebd;
 
 	arc4random_buf(auth_token_secret, sizeof(auth_token_secret));
 
 	/* send our global access rules */
-	config_set_access_rules(env->iev_access, &env->access_rules);
 	for (i = 0; i < env->nserver; ++i) {
 		config_set_access_rules(&env->iev_login[i],
 		    &env->access_rules);
+		config_set_access_rules(&env->iev_access[i],
+		    &env->access_rules);
 		config_set_access_rules(&env->iev_gotweb[i],
 		    &env->access_rules);
 	}
@@ -884,47 +904,48 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_
 		if (main_compose_gotweb(env, GOTWEBD_IMSG_CFG_SRV,
 		    -1, srv, sizeof(*srv)) == -1)
 			fatal("main_compose_gotweb GOTWEBD_IMSG_CFG_SRV");
-		if (send_imsg(env->iev_access, GOTWEBD_IMSG_CFG_SRV,
+		if (main_compose_access(env, GOTWEBD_IMSG_CFG_SRV,
 		    -1, srv, sizeof(*srv)) == -1)
 			fatal("send_imsg GOTWEBD_IMSG_CFG_SRV");
 
 		/* send per-server access rules */
-		config_set_access_rules(env->iev_access, &srv->access_rules);
 		for (i = 0; i < env->nserver; ++i) {
 			config_set_access_rules(&env->iev_login[i],
 			    &srv->access_rules);
+			config_set_access_rules(&env->iev_access[i],
+			    &srv->access_rules);
 			config_set_access_rules(&env->iev_gotweb[i],
 			    &srv->access_rules);
 		}
 
 		/* send repositories and per-repository access rules */
 		TAILQ_FOREACH(repo, &srv->repos, entry) {
-			config_set_repository(env->iev_access, repo);
-			config_set_access_rules(env->iev_access,
-			    &repo->access_rules);
-
 			for (i = 0; i < env->nserver; i++) {
 				config_set_repository(&env->iev_login[i],
 				    repo);
+				config_set_repository(&env->iev_access[i],
+				    repo);
 				config_set_repository(&env->iev_gotweb[i],
 				    repo);
 
 				config_set_access_rules(&env->iev_login[i],
 				    &repo->access_rules);
+				config_set_access_rules(&env->iev_access[i],
+				    &repo->access_rules);
 				config_set_access_rules(&env->iev_gotweb[i],
 				    &repo->access_rules);
 			}
 		}
 
-		if (imsgbuf_flush(&env->iev_access->ibuf) == -1)
-			fatal("imsgbuf_flush");
-		imsg_event_add(env->iev_access);
-
 		for (i = 0; i < env->nserver; i++) {
 			if (imsgbuf_flush(&env->iev_login[i].ibuf) == -1)
 				fatal("imsgbuf_flush");
 			imsg_event_add(&env->iev_login[i]);
 
+			if (imsgbuf_flush(&env->iev_access[i].ibuf) == -1)
+				fatal("imsgbuf_flush");
+			imsg_event_add(&env->iev_access[i]);
+
 			if (imsgbuf_flush(&env->iev_gotweb[i].ibuf) == -1)
 				fatal("imsgbuf_flush");
 			imsg_event_add(&env->iev_gotweb[i]);
@@ -940,32 +961,32 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_
 	if (main_compose_login(env, GOTWEBD_IMSG_AUTH_CONF, -1,
 	    &env->auth_config, sizeof(env->auth_config)) == -1)
 		fatal("main_compose_login GOTWEB_IMSG_AUTH_CONF");
+	if (main_compose_access(env, GOTWEBD_IMSG_AUTH_CONF, -1,
+	    &env->auth_config, sizeof(env->auth_config)) == -1)
+		fatal("send_imsg GOTWEB_IMSG_AUTH_CONF");
 	if (main_compose_gotweb(env, GOTWEBD_IMSG_AUTH_CONF, -1,
 	    &env->auth_config, sizeof(env->auth_config)) == -1)
 		fatal("main_compose_login GOTWEB_IMSG_AUTH_CONF");
-	if (send_imsg(env->iev_access, GOTWEBD_IMSG_AUTH_CONF, -1,
-	    &env->auth_config, sizeof(env->auth_config)) == -1)
-		fatal("send_imsg GOTWEB_IMSG_AUTH_CONF");
 
 	if (main_compose_login(env, GOTWEBD_IMSG_WWW_UID, -1,
 	    &env->www_uid, sizeof(env->www_uid)) == -1)
 		fatal("main_compose_login GOTWEB_IMSG_WWW_UID");
+	if (main_compose_access(env, GOTWEBD_IMSG_WWW_UID, -1,
+	    &env->www_uid, sizeof(env->www_uid)) == -1)
+		fatal("send_imsg GOTWEB_IMSG_WWW_UID");
 	if (main_compose_gotweb(env, GOTWEBD_IMSG_WWW_UID, -1,
 	    &env->www_uid, sizeof(env->www_uid)) == -1)
 		fatal("main_compose_login GOTWEB_IMSG_WWW_UID");
-	if (send_imsg(env->iev_access, GOTWEBD_IMSG_WWW_UID, -1,
-	    &env->www_uid, sizeof(env->www_uid)) == -1)
-		fatal("send_imsg GOTWEB_IMSG_WWW_UID");
 
 	if (main_compose_login(env, GOTWEBD_IMSG_AUTH_SECRET, -1,
 	    auth_token_secret, sizeof(auth_token_secret)) == -1)
 		fatal("main_compose_login GOTWEB_IMSG_AUTH_SECRET");
+	if (main_compose_access(env, GOTWEBD_IMSG_AUTH_SECRET, -1,
+	    auth_token_secret, sizeof(auth_token_secret)) == -1)
+		fatal("send_imsg GOTWEB_IMSG_AUTH_SECRET");
 	if (main_compose_auth(env, GOTWEBD_IMSG_AUTH_SECRET, -1,
 	    auth_token_secret, sizeof(auth_token_secret)) == -1)
 		fatal("main_compose_gotweb GOTWEB_IMSG_AUTH_SECRET");
-	if (send_imsg(env->iev_access, GOTWEBD_IMSG_AUTH_SECRET, -1,
-	    auth_token_secret, sizeof(auth_token_secret)) == -1)
-		fatal("send_imsg GOTWEB_IMSG_AUTH_SECRET");
 	
 	explicit_bzero(auth_token_secret, sizeof(auth_token_secret));
 
@@ -1008,6 +1029,14 @@ gotwebd_configure_done(struct gotwebd *env)
 			fatal("main_compose_login GOTWEBD_IMSG_CTL_START");
 	}
 
+	if (env->access_pending > 0) {
+		env->access_pending--;
+		if (env->access_pending == 0 &&
+		    main_compose_access(env, GOTWEBD_IMSG_CTL_START,
+		        -1, NULL, 0) == -1)
+			fatal("main_compose_access GOTWEBD_IMSG_CTL_START");
+	}
+
 	if (env->gotweb_pending > 0) {
 		env->gotweb_pending--;
 		if (env->gotweb_pending == 0 &&
@@ -1016,13 +1045,11 @@ gotwebd_configure_done(struct gotwebd *env)
 			fatal("main_compose_sockets GOTWEBD_IMSG_CTL_START");
 	}
 
-	if (env->servers_pending == 0 && env->gotweb_pending == 0) {
+	if (env->servers_pending == 0 && env->gotweb_pending == 0 &&
+	    env->login_pending == 0 && env->access_pending == 0) {
 		if (main_compose_auth(env, GOTWEBD_IMSG_CTL_START,
 			-1, NULL, 0) == -1)
 			fatal("main_compose_auth GOTWEBD_IMSG_CTL_START");
-		if (send_imsg(env->iev_access, GOTWEBD_IMSG_CTL_START,
-			-1, NULL, 0) == -1)
-			fatal("send_imsg GOTWEBD_IMSG_CTL_START");
 	}
 }
 
@@ -1039,10 +1066,12 @@ gotwebd_shutdown(void)
 	env->iev_auth->ibuf.fd = -1;
 	free(env->iev_auth);
 
-	event_del(&env->iev_access->ev);
-	imsgbuf_clear(&env->iev_access->ibuf);
-	close(env->iev_access->ibuf.fd);
-	env->iev_access->ibuf.fd = -1;
+	for (i = 0; i < env->nserver; ++i) {
+		event_del(&env->iev_access[i].ev);
+		imsgbuf_clear(&env->iev_access[i].ibuf);
+		close(env->iev_access[i].ibuf.fd);
+		env->iev_access[i].ibuf.fd = -1;
+	}
 	free(env->iev_access);
 
 	for (i = 0; i < env->nserver; ++i) {
blob - e3a745e3df95c9878c6d2fe4843e85f4d2aaafbe
blob + 658f263f082bd8a2d7cec58e8364388d004e3531
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
@@ -435,6 +435,7 @@ struct gotwebd {
 	uint16_t	 prefork_gotwebd;
 	int		 servers_pending;
 	int		 login_pending;
+	int		 access_pending;
 	int		 gotweb_pending;
 
 	int		 server_cnt;
@@ -521,6 +522,8 @@ int	 sockets_compose_main(struct gotwebd *, uint32_t,
 	    const void *, uint16_t);
 int	 main_compose_login(struct gotwebd *, uint32_t, int,
 	    const void *, uint16_t);
+int	 main_compose_access(struct gotwebd *, uint32_t, int,
+	    const void *, uint16_t);
 int	 login_compose_main(struct gotwebd *, uint32_t,
 	    const void *, uint16_t);
 int	 main_compose_gotweb(struct gotwebd *, uint32_t, int,