X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/05b75f8d50b83e943af3be4071449304d82dbdcd..75e7b7c3b97a24f611e87e1220001258652a63e3:/server/server.c diff --git a/server/server.c b/server/server.c index 0ddfd53..ad3a7ab 100644 --- a/server/server.c +++ b/server/server.c @@ -348,16 +348,16 @@ static void start_fresh_rescan(void *ru) { static int c_rescan(struct conn *c, char **vec, int nvec) { - int wait = 0, fresh = 0, n; + int flag_wait = 0, flag_fresh = 0, n; /* Parse flags */ for(n = 0; n < nvec; ++n) { if(!strcmp(vec[n], "wait")) - wait = 1; /* wait for rescan to complete */ + flag_wait = 1; /* wait for rescan to complete */ #if 0 /* Currently disabled because untested (and hard to test). */ else if(!strcmp(vec[n], "fresh")) - fresh = 1; /* don't piggyback underway rescan */ + flag_fresh = 1; /* don't piggyback underway rescan */ #endif else { sink_writes(ev_writer_sink(c->w), "550 unknown flag\n"); @@ -366,15 +366,15 @@ static int c_rescan(struct conn *c, } /* Report what was requested */ info("S%x rescan by %s (%s %s)", c->tag, c->who, - wait ? "wait" : "", - fresh ? "fresh" : ""); + flag_wait ? "wait" : "", + flag_fresh ? "fresh" : ""); if(trackdb_rescan_underway()) { - if(fresh) { + if(flag_fresh) { /* We want a fresh rescan but there is already one underway. Arrange a * callback when it completes and then set off a new one. */ - c->rescan_wait = wait; + c->rescan_wait = flag_wait; trackdb_add_rescanned(start_fresh_rescan, c); - if(wait) + if(flag_wait) return 0; else { sink_writes(ev_writer_sink(c->w), "250 rescan queued\n"); @@ -382,7 +382,7 @@ static int c_rescan(struct conn *c, } } else { /* There's a rescan underway, and it's acceptable to piggyback on it */ - if(wait) { + if(flag_wait) { /* We want to block until completion. */ trackdb_add_rescanned(finished_rescan, c); return 0; @@ -395,7 +395,7 @@ static int c_rescan(struct conn *c, } } else { /* No rescan is underway. fresh is therefore irrelevant. */ - if(wait) { + if(flag_wait) { /* We want to block until completion */ trackdb_rescan(c->ev, 1/*check*/, finished_rescan, c); return 0; @@ -876,8 +876,19 @@ static void logclient(const char *msg, void *user) { if(!c->w || !c->r) { /* This connection has gone up in smoke for some reason */ eventlog_remove(c->lo); + c->lo = 0; return; } + /* user_* messages are restricted */ + if(!strncmp(msg, "user_", 5)) { + /* They are only sent to admin users */ + if(!(c->rights & RIGHT_ADMIN)) + return; + /* They are not sent over TCP connections unless remote user-management is + * enabled */ + if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) + return; + } sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" %s\n", (uintmax_t)time(0), msg); } @@ -1234,10 +1245,21 @@ static int c_edituser(struct conn *c, /* Update rights for this user */ rights_type r; - if(parse_rights(vec[2], &r, 1)) - for(d = connections; d; d = d->next) - if(!strcmp(d->who, vec[0])) + if(!parse_rights(vec[2], &r, 1)) { + const char *new_rights = rights_string(r); + for(d = connections; d; d = d->next) { + if(!strcmp(d->who, vec[0])) { + /* Update rights */ d->rights = r; + /* Notify any log connections */ + if(d->lo) + sink_printf(ev_writer_sink(d->w), + "%"PRIxMAX" rights_changed %s\n", + (uintmax_t)time(0), + quoteutf8(new_rights)); + } + } + } } sink_writes(ev_writer_sink(c->w), "250 OK\n"); } else { @@ -1404,6 +1426,7 @@ static int c_reminder(struct conn *c, sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n"); return 1; } + /* TODO use email_valid() */ if(!(email = kvp_get(k, "email")) || !strchr(email, '@')) { error(0, "user '%s' has no valid email address", vec[0]); @@ -1751,6 +1774,7 @@ static int listen_callback(ev_source *ev, D(("server listen_callback fd %d (%s)", fd, l->name)); nonblock(fd); cloexec(fd); + c->next = connections; c->tag = tags++; c->ev = ev; c->w = ev_writer_new(ev, fd, writer_error, c, @@ -1762,6 +1786,7 @@ static int listen_callback(ev_source *ev, c->reader = reader_callback; c->l = l; c->rights = 0; + connections = c; gcry_randomize(c->nonce, sizeof c->nonce, GCRY_STRONG_RANDOM); sink_printf(ev_writer_sink(c->w), "231 %d %s %s\n", 2,