--- proto.h.orig 2017-06-04 22:50:06.814525000 +0200 +++ proto.h 2017-06-04 22:50:30.000000000 +0200 @@ -183,6 +183,9 @@ void start_write_batch(int fd); void stop_write_batch(void); char *lp_bind_address(void); +char *lp_daemon_chroot(void); +char *lp_daemon_gid(void); +char *lp_daemon_uid(void); char *lp_motd_file(void); char *lp_pid_file(void); char *lp_socket_options(void); --- loadparm.c.orig 2017-06-04 22:49:56.753698000 +0200 +++ loadparm.c 2017-06-04 22:50:54.000000000 +0200 @@ -93,6 +93,9 @@ /* This structure describes global (ie., server-wide) parameters. */ typedef struct { char *bind_address; + char *daemon_chroot; + char *daemon_gid; + char *daemon_uid; char *motd_file; char *pid_file; char *socket_options; @@ -172,6 +175,9 @@ /* ==== global_vars ==== */ { /* bind_address; */ NULL, + /* daemon_chroot; */ NULL, + /* daemon_gid; */ NULL, + /* daemon_uid; */ NULL, /* motd_file; */ NULL, /* pid_file; */ NULL, /* socket_options; */ NULL, @@ -313,6 +319,9 @@ static struct parm_struct parm_table[] = { {"address", P_STRING, P_GLOBAL,&Vars.g.bind_address, NULL,0}, + {"daemon chroot", P_STRING, P_GLOBAL,&Vars.g.daemon_chroot, NULL,0}, + {"daemon gid", P_STRING, P_GLOBAL,&Vars.g.daemon_gid, NULL,0}, + {"daemon uid", P_STRING, P_GLOBAL,&Vars.g.daemon_uid, NULL,0}, {"listen backlog", P_INTEGER,P_GLOBAL,&Vars.g.listen_backlog, NULL,0}, {"motd file", P_STRING, P_GLOBAL,&Vars.g.motd_file, NULL,0}, {"pid file", P_STRING, P_GLOBAL,&Vars.g.pid_file, NULL,0}, @@ -444,6 +453,9 @@ int fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;} FN_GLOBAL_STRING(lp_bind_address, &Vars.g.bind_address) +FN_GLOBAL_STRING(lp_daemon_chroot, &Vars.g.daemon_chroot) +FN_GLOBAL_STRING(lp_daemon_gid, &Vars.g.daemon_gid) +FN_GLOBAL_STRING(lp_daemon_uid, &Vars.g.daemon_uid) FN_GLOBAL_STRING(lp_motd_file, &Vars.g.motd_file) FN_GLOBAL_STRING(lp_pid_file, &Vars.g.pid_file) FN_GLOBAL_STRING(lp_socket_options, &Vars.g.socket_options) --- clientserver.c.orig 2017-06-04 22:50:15.488946000 +0200 +++ clientserver.c 2017-06-04 22:50:25.000000000 +0200 @@ -1040,6 +1040,9 @@ char line[1024]; const char *addr, *host; int i; + char *chroot_path, *p = NULL; + gid_t gid; + uid_t uid; io_set_sock_fds(f_in, f_out); @@ -1050,6 +1053,32 @@ if (!load_config(0)) exit_cleanup(RERR_SYNTAX); + chroot_path = lp_daemon_chroot(); + if (*chroot_path) { + if (chroot(chroot_path)) { + log_init(0); //Let's init syslog before chrooting + rsyserr(FLOG, errno, "daemon chroot %s failed", chroot_path); + return -1; + } + chdir("/"); + } + p = lp_daemon_gid(); + if (*p) { + if (!group_to_gid(p, &gid, True)) { + rprintf(FLOG, "Invalid gid %s\n", p); + return -1; + } + setgid(gid); + } + p = lp_daemon_uid(); + if (*p) { + if (!user_to_uid(p, &uid, True)) { + rprintf(FLOG, "Invalid uid %s\n", p); + return -1; + } + setuid(uid); + } + addr = client_addr(f_in); host = lp_reverse_lookup(-1) ? client_name(f_in) : undetermined_hostname; rprintf(FLOG, "connect from %s (%s)\n", host, addr); --- rsyncd.conf.5.orig 2017-06-04 22:49:49.051335000 +0200 +++ rsyncd.conf.5 2017-06-04 22:55:57.000000000 +0200 @@ -166,6 +166,17 @@ that is displayed next to the module name when clients obtain a list of available modules. The default is no comment. .IP +.IP "\fBdaemon chroot\fP" +This parameter specifies a path to which daemon will chroot before +beginning communication with clients. Modules paths will then be related +to this one. +.IP +.IP "\fBdaemon gid\fP" +This parameter specifies a gid under which the daemon will run. +.IP +.IP "\fBdaemon uid\fP" +This parameter specifies a uid under which the daemon will run. +.IP .IP "\fBpath\fP" This parameter specifies the directory in the daemon\(cq\&s filesystem to make available in this module. You must specify this parameter