X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/6207d2f3bcf38c072c2bcaa7c9e8dbd469b5e8e6..be968860e16975c9829cd8d8a11ec6a8adc6c83a:/server/server.c diff --git a/server/server.c b/server/server.c index 5e8f220..fd0fcd8 100644 --- a/server/server.c +++ b/server/server.c @@ -272,9 +272,8 @@ static int c_remove(struct conn *c, char **vec, queue_remove(q, c->who); /* De-prepare the track. */ abandon(c->ev, q); - /* If we removed a random track then add another one. */ - if(q->state == playing_random) - add_random_track(); + /* See about adding a new random track */ + add_random_track(c->ev); /* Prepare whatever the next head track is. */ if(qhead.next != &qhead) prepare(c->ev, qhead.next); @@ -615,9 +614,13 @@ static int c_allfiles(struct conn *c, static int c_get(struct conn *c, char **vec, int attribute((unused)) nvec) { - const char *v; + const char *v, *track; - if(vec[1][0] != '_' && (v = trackdb_get(vec[0], vec[1]))) + if(!(track = trackdb_resolve(vec[0]))) { + sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n"); + return 1; + } + if(vec[1][0] != '_' && (v = trackdb_get(track, vec[1]))) sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(v)); else sink_writes(ev_writer_sink(c->w), "555 not found\n"); @@ -643,7 +646,13 @@ static int c_length(struct conn *c, static int c_set(struct conn *c, char **vec, int attribute((unused)) nvec) { - if(vec[1][0] != '_' && !trackdb_set(vec[0], vec[1], vec[2])) + const char *track; + + if(!(track = trackdb_resolve(vec[0]))) { + sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n"); + return 1; + } + if(vec[1][0] != '_' && !trackdb_set(track, vec[1], vec[2])) sink_writes(ev_writer_sink(c->w), "250 OK\n"); else sink_writes(ev_writer_sink(c->w), "550 not found\n"); @@ -654,8 +663,13 @@ static int c_prefs(struct conn *c, char **vec, int attribute((unused)) nvec) { struct kvp *k; + const char *track; - k = trackdb_get_all(vec[0]); + if(!(track = trackdb_resolve(vec[0]))) { + sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n"); + return 1; + } + k = trackdb_get_all(track); sink_writes(ev_writer_sink(c->w), "253 prefs follow\n"); for(; k; k = k->next) if(k->name[0] != '_') /* omit internal values */ @@ -668,6 +682,7 @@ static int c_prefs(struct conn *c, static int c_exists(struct conn *c, char **vec, int attribute((unused)) nvec) { + /* trackdb_exists() does its own alias checking */ sink_printf(ev_writer_sink(c->w), "252 %s\n", noyes[trackdb_exists(vec[0])]); return 1; } @@ -768,7 +783,7 @@ static int c_volume(struct conn *c, sink_writes(ev_writer_sink(c->w), "510 Prohibited\n"); return 1; } - if(mixer_control(&l, &r, set)) + if(mixer_control(-1/*as configured*/, &l, &r, set)) sink_writes(ev_writer_sink(c->w), "550 error accessing mixer\n"); else { sink_printf(ev_writer_sink(c->w), "252 %d %d\n", l, r); @@ -932,8 +947,14 @@ static int c_moveafter(struct conn *c, static int c_part(struct conn *c, char **vec, int attribute((unused)) nvec) { + const char *track; + + if(!(track = trackdb_resolve(vec[0]))) { + sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n"); + return 1; + } sink_printf(ev_writer_sink(c->w), "252 %s\n", - quoteutf8(trackdb_getpart(vec[0], vec[1], vec[2]))); + quoteutf8(trackdb_getpart(track, vec[1], vec[2]))); return 1; } @@ -1097,6 +1118,11 @@ static int c_adduser(struct conn *c, int nvec) { const char *rights; + if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) { + error(0, "S%x: remote adduser", c->tag); + sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n"); + return 1; + } if(nvec > 2) { rights = vec[2]; if(parse_rights(vec[2], 0, 1)) { @@ -1118,6 +1144,11 @@ static int c_deluser(struct conn *c, int attribute((unused)) nvec) { struct conn *d; + if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) { + error(0, "S%x: remote deluser", c->tag); + sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n"); + return 1; + } if(trackdb_deluser(vec[0])) { sink_writes(ev_writer_sink(c->w), "550 Cannot delete user\n"); return 1; @@ -1135,6 +1166,11 @@ static int c_edituser(struct conn *c, int attribute((unused)) nvec) { struct conn *d; + if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) { + error(0, "S%x: remote edituser", c->tag); + sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n"); + return 1; + } /* RIGHT_ADMIN can do anything; otherwise you can only set your own email * address and password. */ if((c->rights & RIGHT_ADMIN) @@ -1154,7 +1190,7 @@ static int c_edituser(struct conn *c, /* Update rights for this user */ rights_type r; - if(parse_rights(vec[1], &r, 1)) + if(parse_rights(vec[2], &r, 1)) for(d = connections; d; d = d->next) if(!strcmp(d->who, vec[0])) d->rights = r; @@ -1173,8 +1209,17 @@ static int c_userinfo(struct conn *c, struct kvp *k; const char *value; + /* We allow remote querying of rights so that clients can figure out what + * they're allowed to do */ + if(!config->remote_userman + && !(c->rights & RIGHT__LOCAL) + && strcmp(vec[1], "rights")) { + error(0, "S%x: remote userinfo %s %s", c->tag, vec[0], vec[1]); + sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n"); + return 1; + } /* RIGHT_ADMIN allows anything; otherwise you can only get your own email - * address and righst list. */ + * address and rights list. */ if((c->rights & RIGHT_ADMIN) || (!strcmp(c->who, vec[0]) && (!strcmp(vec[1], "email")