diff options
Diffstat (limited to 'src/or/config.c')
-rw-r--r-- | src/or/config.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/src/or/config.c b/src/or/config.c index 22039b46ef..5060b1b5be 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -308,6 +308,7 @@ static config_var_t option_vars_[] = { V(Socks5ProxyUsername, STRING, NULL), V(Socks5ProxyPassword, STRING, NULL), V(KeepalivePeriod, INTERVAL, "5 minutes"), + V(KeepCapabilities, AUTOBOOL, "auto"), VAR("Log", LINELIST, Logs, NULL), V(LogMessageDomains, BOOL, "0"), V(LogTimeGranularity, MSEC_INTERVAL, "1 second"), @@ -567,7 +568,8 @@ static int parse_ports(or_options_t *options, int validate_only, char **msg_out, int *n_ports_out, int *world_writable_control_socket); static int check_server_ports(const smartlist_t *ports, - const or_options_t *options); + const or_options_t *options, + int *num_low_ports_out); static int validate_data_directory(or_options_t *options); static int write_configuration_file(const char *fname, @@ -1045,6 +1047,9 @@ consider_adding_dir_servers(const or_options_t *options, return 0; } +/* Helps determine flags to pass to switch_id. */ +static int have_low_ports = -1; + /** Fetch the active option list, and take actions based on it. All of the * things we do should survive being done repeatedly. If present, * <b>old_options</b> contains the previous value of the options. @@ -1178,8 +1183,14 @@ options_act_reversible(const or_options_t *old_options, char **msg) } /* Setuid/setgid as appropriate */ + tor_assert(have_low_ports != -1); if (options->User) { - if (switch_id(options->User) != 0) { + unsigned switch_id_flags = 0; + if (options->KeepCapabilities == 1 || + (options->KeepCapabilities == -1 && have_low_ports)) { + switch_id_flags |= SWITCH_ID_KEEP_BINDLOW; + } + if (switch_id(options->User, switch_id_flags) != 0) { /* No need to roll back, since you can't change the value. */ *msg = tor_strdup("Problem with User value. See logs for details."); goto done; @@ -3997,6 +4008,12 @@ options_transition_allowed(const or_options_t *old, return -1; } + if (old->KeepCapabilities != new_val->KeepCapabilities) { + *msg = tor_strdup("While Tor is running, changing KeepCapabilities is " + "not allowed."); + return -1; + } + if (!opt_streq(old->SyslogIdentityTag, new_val->SyslogIdentityTag)) { *msg = tor_strdup("While Tor is running, changing " "SyslogIdentityTag is not allowed."); @@ -6535,10 +6552,13 @@ parse_ports(or_options_t *options, int validate_only, } } - if (check_server_ports(ports, options) < 0) { + int n_low_ports = 0; + if (check_server_ports(ports, options, &n_low_ports) < 0) { *msg = tor_strdup("Misconfigured server ports"); goto err; } + if (have_low_ports < 0) + have_low_ports = (n_low_ports > 0); *n_ports_out = smartlist_len(ports); @@ -6592,10 +6612,12 @@ parse_ports(or_options_t *options, int validate_only, } /** Given a list of <b>port_cfg_t</b> in <b>ports</b>, check them for internal - * consistency and warn as appropriate. */ + * consistency and warn as appropriate. Set *<b>n_low_port</b> to the number + * of sub-1024 ports we will be binding. */ static int check_server_ports(const smartlist_t *ports, - const or_options_t *options) + const or_options_t *options, + int *n_low_ports_out) { int n_orport_advertised = 0; int n_orport_advertised_ipv4 = 0; @@ -6658,16 +6680,24 @@ check_server_ports(const smartlist_t *ports, r = -1; } - if (n_low_port && options->AccountingMax) { + if (n_low_port && options->AccountingMax && + (!have_capability_support() || options->KeepCapabilities == 0)) { + const char *extra = ""; + if (options->KeepCapabilities == 0 && have_capability_support()) + extra = ", and you have disabled KeepCapabilities."; log_warn(LD_CONFIG, "You have set AccountingMax to use hibernation. You have also " - "chosen a low DirPort or OrPort. This combination can make Tor stop " + "chosen a low DirPort or OrPort%s." + "This combination can make Tor stop " "working when it tries to re-attach the port after a period of " "hibernation. Please choose a different port or turn off " "hibernation unless you know this combination will work on your " - "platform."); + "platform.", extra); } + if (n_low_ports_out) + *n_low_ports_out = n_low_port; + return r; } |