30
" [--interpolated-path=<path>]\n"
31
" [--reuseaddr] [--pid-file=<file>]\n"
32
" [--(enable|disable|allow-override|forbid-override)=<service>]\n"
33
+" [--access-hook=<path>]\n"
34
" [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>]\n"
35
" [--detach] [--user=<user> [--group=<group>]]\n"
36
" [<directory>...]";
257
return -1;
258
}
259
260
+static char *access_hook;
261
+
262
+static int run_access_hook(struct daemon_service *service, const char *dir, const char *path)
263
+{
264
+ struct child_process child;
265
+ struct strbuf buf = STRBUF_INIT;
266
+ const char *argv[8];
267
+ const char **arg = argv;
268
+ char *eol;
269
+ int seen_errors = 0;
270
+
271
+#define STRARG(x) ((x) ? (x) : "")
272
+ *arg++ = access_hook;
273
+ *arg++ = service->name;
274
+ *arg++ = path;
275
+ *arg++ = STRARG(hostname);
276
+ *arg++ = STRARG(canon_hostname);
277
+ *arg++ = STRARG(ip_address);
278
+ *arg++ = STRARG(tcp_port);
279
+ *arg = NULL;
280
+#undef STRARG
281
+
282
+ memset(&child, 0, sizeof(child));
283
+ child.use_shell = 1;
284
+ child.argv = argv;
285
+ child.no_stdin = 1;
286
+ child.no_stderr = 1;
287
+ child.out = -1;
288
+ if (start_command(&child)) {
289
+ logerror("daemon access hook '%s' failed to start",
290
+ access_hook);
291
+ goto error_return;
292
+ }
293
+ if (strbuf_read(&buf, child.out, 0) < 0) {
294
+ logerror("failed to read from pipe to daemon access hook '%s'",
295
+ access_hook);
296
+ strbuf_reset(&buf);
297
+ seen_errors = 1;
298
+ }
299
+ if (close(child.out) < 0) {
300
+ logerror("failed to close pipe to daemon access hook '%s'",
301
+ access_hook);
302
+ seen_errors = 1;
303
+ }
304
+ if (finish_command(&child))
305
+ seen_errors = 1;
306
+
307
+ if (!seen_errors) {
308
+ strbuf_release(&buf);
309
+ return 0;
310
+ }
311
+
312
+error_return:
313
+ strbuf_ltrim(&buf);
314
+ if (!buf.len)
315
+ strbuf_addstr(&buf, "service rejected");
316
+ eol = strchr(buf.buf, '\n');
317
+ if (eol)
318
+ *eol = '\0';
319
+ errno = EACCES;
320
+ daemon_error(dir, buf.buf);
321
+ strbuf_release(&buf);
322
+ return -1;
323
+}
324
+
325
static int run_service(char *dir, struct daemon_service *service)
326
{
327
const char *path;
369
return daemon_error(dir, "service not enabled");
370
}
371
372
+ /*
373
+ * Optionally, a hook can choose to deny access to the
374
+ * repository depending on the phase of the moon.
375
+ */
376
+ if (access_hook && run_access_hook(service, dir, path))
377
+ return -1;
378
+
379
/*
380
* We'll ignore SIGTERM from now on, we have a
381
* good client.
1215
export_all_trees = 1;
1216
continue;
1217
}
1218
+ if (!prefixcmp(arg, "--access-hook=")) {
1219
+ access_hook = arg + 14;
1220
+ continue;
1221
+ }
1222
if (!prefixcmp(arg, "--timeout=")) {
1223
timeout = atoi(arg+10);
1224
continue;