static int run_restore(struct asfd *asfd, struct sdirs *sdirs, struct conf **cconfs, int srestore) { int ret=-1; char *dir_for_notify=NULL; enum action act=ACTION_RESTORE; struct iobuf *rbuf=asfd->rbuf; const char *cname=get_string(cconfs[OPT_CNAME]); if(parse_restore_str_and_set_confs(rbuf->buf, &act, cconfs)) goto end; iobuf_free_content(rbuf); if(act==ACTION_RESTORE) { int r; if((r=client_can_restore(cconfs))<0) goto end; else if(!r) { logp("Not allowing restore of %s\n", cname); if(!asfd->write_str(asfd, CMD_GEN, "Client restore is not allowed")) ret=0; goto end; } } if(act==ACTION_VERIFY && !(client_can_generic(cconfs, OPT_CLIENT_CAN_VERIFY))) { logp("Not allowing verify of %s\n", cname); if(!asfd->write_str(asfd, CMD_GEN, "Client verify is not allowed")) ret=0; goto end; } if(asfd->write_str(asfd, CMD_GEN, "ok")) goto end; ret=do_restore_server(asfd, sdirs, act, srestore, &dir_for_notify, cconfs); if(dir_for_notify) maybe_do_notification(asfd, ret, sdirs->client, dir_for_notify, act==ACTION_RESTORE?"restorelog":"verifylog", act==ACTION_RESTORE?"restore":"verify", cconfs); end: free_w(&dir_for_notify); return ret; }
static int run_action_server_do(struct async *as, struct sdirs *sdirs, const char *incexc, int srestore, int *timer_ret, struct conf **cconfs) { int ret; int resume=0; char msg[256]=""; struct iobuf *rbuf=as->asfd->rbuf; // Make sure some directories exist. if(mkpath(&sdirs->current, sdirs->dedup)) { snprintf(msg, sizeof(msg), "could not mkpath %s", sdirs->current); log_and_send(as->asfd, msg); return -1; } if(rbuf->cmd!=CMD_GEN) return unknown_command(as->asfd); // List and diff should work even while backups are running. if(!strncmp_w(rbuf->buf, "list ") || !strncmp_w(rbuf->buf, "listb ")) return run_list(as->asfd, sdirs, cconfs); if(!strncmp_w(rbuf->buf, "diff ")) return run_diff(as->asfd, sdirs, cconfs); switch((ret=get_lock_sdirs(as->asfd, sdirs))) { case 0: break; // OK. case 1: return 1; // Locked out. default: // Error. maybe_do_notification(as->asfd, ret, "", "error in get_lock_sdirs()", "", buf_to_notify_str(rbuf), cconfs); return -1; } switch((ret=check_for_rubble(as, sdirs, incexc, &resume, cconfs))) { case 0: break; // OK. case 1: return 1; // Now finalising. default: // Error. maybe_do_notification(as->asfd, ret, "", "error in check_for_rubble()", "", buf_to_notify_str(rbuf), cconfs); return -1; } if(!strncmp_w(rbuf->buf, "backup")) { ret=run_backup(as, sdirs, cconfs, incexc, timer_ret, resume); if(*timer_ret<0) maybe_do_notification(as->asfd, ret, "", "error running timer script", "", "backup", cconfs); else if(!*timer_ret) maybe_do_notification(as->asfd, ret, sdirs->client, sdirs->current, "log", "backup", cconfs); return ret; } if(!strncmp_w(rbuf->buf, "restore ") || !strncmp_w(rbuf->buf, "verify ")) return run_restore(as->asfd, sdirs, cconfs, srestore); if(!strncmp_w(rbuf->buf, "Delete ")) return run_delete(as->asfd, sdirs, cconfs); // Old clients will send 'delete', possibly accidentally due to the // user trying to use the new diff/long diff options. // Stop them from working, just to be safe. if(!strncmp_w(rbuf->buf, "delete ")) { logp("old style delete from %s denied\n", get_string(cconfs[OPT_CNAME])); as->asfd->write_str(as->asfd, CMD_ERROR, "old style delete is not supported on this server"); return -1; } return unknown_command(as->asfd); }
static int run_restore(struct asfd *asfd, struct sdirs *sdirs, struct conf **cconfs, int srestore) { int ret=-1; char *cp=NULL; char *copy=NULL; enum action act; char *backupnostr=NULL; char *restoreregex=NULL; char *dir_for_notify=NULL; struct iobuf *rbuf=asfd->rbuf; const char *cname=get_string(cconfs[OPT_CNAME]); if(!(copy=strdup_w(rbuf->buf, __func__))) goto end; iobuf_free_content(rbuf); if(!strncmp_w(copy, "restore ")) act=ACTION_RESTORE; else act=ACTION_VERIFY; if(!(backupnostr=strchr(copy, ' '))) { logp("Could not parse %s in %s\n", copy, __func__); goto end; } backupnostr++; if(set_string(cconfs[OPT_BACKUP], backupnostr)) goto end; // FIX THIS. if((cp=strchr(cconfs[OPT_BACKUP]->data.s, ':'))) *cp='\0'; if(act==ACTION_RESTORE) { int r; if((r=client_can_restore(cconfs))<0) goto end; else if(!r) { logp("Not allowing restore of %s\n", cname); if(!asfd->write_str(asfd, CMD_GEN, "Client restore is not allowed")) ret=0; goto end; } } if(act==ACTION_VERIFY && !(client_can_generic(cconfs, OPT_CLIENT_CAN_VERIFY))) { logp("Not allowing verify of %s\n", cname); if(!asfd->write_str(asfd, CMD_GEN, "Client verify is not allowed")) ret=0; goto end; } if((restoreregex=strchr(copy, ':'))) { *restoreregex='\0'; restoreregex++; } if(restoreregex && *restoreregex && set_string(cconfs[OPT_REGEX], restoreregex)) goto end; if(asfd->write_str(asfd, CMD_GEN, "ok")) goto end; ret=do_restore_server(asfd, sdirs, act, srestore, &dir_for_notify, cconfs); if(dir_for_notify) maybe_do_notification(asfd, ret, sdirs->client, dir_for_notify, act==ACTION_RESTORE?"restorelog":"verifylog", act==ACTION_RESTORE?"restore":"verify", cconfs); end: free_w(©); free_w(&dir_for_notify); return ret; }