diff --git a/cf-execd/cf-execd-runner.c b/cf-execd/cf-execd-runner.c index 75b7ebcc5d..bf14a1cbe4 100644 --- a/cf-execd/cf-execd-runner.c +++ b/cf-execd/cf-execd-runner.c @@ -564,6 +564,7 @@ static bool CompareResultEqualOrFiltered(const ExecConfig *config, #ifndef TEST_CF_EXECD int ConnectToSmtpSocket(const ExecConfig *config) { + assert(config != NULL); struct hostent *hp = gethostbyname(config->mail_server); if (!hp) { @@ -572,17 +573,10 @@ int ConnectToSmtpSocket(const ExecConfig *config) return -1; } - struct servent *server = getservbyname("smtp", "tcp"); - if (!server) - { - Log(LOG_LEVEL_ERR, "Mail report: unable to lookup smtp service. (getservbyname: %s)", GetErrorStr()); - return -1; - } - struct sockaddr_in raddr; memset(&raddr, 0, sizeof(raddr)); - raddr.sin_port = (unsigned int) server->s_port; + raddr.sin_port = config->mail_port; raddr.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr; raddr.sin_family = AF_INET; diff --git a/cf-execd/exec-config.c b/cf-execd/exec-config.c index 433b48a08e..31d7381d8f 100644 --- a/cf-execd/exec-config.c +++ b/cf-execd/exec-config.c @@ -151,6 +151,17 @@ ExecConfig *ExecConfigNew(bool scheduled_run, const EvalContext *ctx, const Poli exec_config->ip_address = xstrdup(VIPADDRESS); exec_config->ip_addresses = GetIpAddresses(ctx); + struct servent *server = getservbyname("smtp", "tcp"); + if (!server) + { + exec_config->mail_port = 25; + } + else + { + exec_config->mail_port = (unsigned int) server->s_port; + } + + Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_EXECUTOR); if (constraints) { @@ -199,6 +210,11 @@ ExecConfig *ExecConfigNew(bool scheduled_run, const EvalContext *ctx, const Poli exec_config->mail_server = xstrdup(value); Log(LOG_LEVEL_DEBUG, "smtpserver '%s'", exec_config->mail_server); } + else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_SMTPPORT].lval) == 0) + { + exec_config->mail_port = IntFromString(value); + Log(LOG_LEVEL_DEBUG, "smtpport '%d'", exec_config->mail_port); + } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_EXECCOMMAND].lval) == 0) { free(exec_config->exec_command); @@ -237,12 +253,14 @@ ExecConfig *ExecConfigNew(bool scheduled_run, const EvalContext *ctx, const Poli ExecConfig *ExecConfigCopy(const ExecConfig *config) { + assert(config != NULL); ExecConfig *copy = xcalloc(1, sizeof(ExecConfig)); copy->scheduled_run = config->scheduled_run; copy->exec_command = xstrdup(config->exec_command); copy->agent_expireafter = config->agent_expireafter; copy->mail_server = xstrdup(config->mail_server); + copy->mail_port = config->mail_port; copy->mail_from_address = xstrdup(config->mail_from_address); copy->mail_to_address = xstrdup(config->mail_to_address); copy->mail_subject = xstrdup(config->mail_subject); diff --git a/cf-execd/exec-config.h b/cf-execd/exec-config.h index 5d7f3769fd..74c118a9d3 100644 --- a/cf-execd/exec-config.h +++ b/cf-execd/exec-config.h @@ -40,6 +40,7 @@ typedef struct char *mail_to_address; char *mail_subject; int mail_max_lines; + unsigned int mail_port; // These two contain regular expression strings. Seq *mailfilter_include; Seq *mailfilter_exclude; diff --git a/libpromises/cf3.defs.h b/libpromises/cf3.defs.h index fe02dba7c3..71ca9f7f3b 100644 --- a/libpromises/cf3.defs.h +++ b/libpromises/cf3.defs.h @@ -515,6 +515,7 @@ typedef enum EXEC_CONTROL_EXECCOMMAND, EXEC_CONTROL_AGENT_EXPIREAFTER, EXEC_CONTROL_RUNAGENT_ALLOW_USERS, + EXEC_CONTROL_SMTPPORT, EXEC_CONTROL_NONE } ExecControl; diff --git a/libpromises/mod_common.c b/libpromises/mod_common.c index 17e0485b5e..3d41cd4270 100644 --- a/libpromises/mod_common.c +++ b/libpromises/mod_common.c @@ -394,6 +394,7 @@ const ConstraintSyntax CFEX_CONTROLBODY[] = /* enum cfexcontrol */ ConstraintSyntaxNewString("exec_command", CF_ABSPATHRANGE,"The full path and command to the executable run by default (overriding builtin)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("agent_expireafter", "0,10080", "Maximum agent runtime (in minutes). Default value: 120", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("runagent_socket_allow_users", "", "Users allowed to work with the runagent.socket to trigger agent runs", SYNTAX_STATUS_NORMAL), + ConstraintSyntaxNewInt("smtpport", "0,10080", "Port used for sending mail", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; diff --git a/tests/unit/exec-config-test.c b/tests/unit/exec-config-test.c index 8e4de9662c..0bb662ef49 100644 --- a/tests/unit/exec-config-test.c +++ b/tests/unit/exec-config-test.c @@ -101,6 +101,7 @@ static void exec_config_empty_cb(const EvalContext *ctx, const Policy *policy) /* FIXME: exec-config should provide default subject */ assert_string_equal("", config->mail_subject); assert_int_equal(30, config->mail_max_lines); + assert_int_equal(25, config->mail_port); assert_string_equal("localhost.localdomain", config->fq_name); assert_string_equal("127.0.0.100", config->ip_address); assert_string_equal("127.0.0.100 127.0.0.101", config->ip_addresses); @@ -123,6 +124,7 @@ static void CheckFullExecConfig(const ExecConfig *config) assert_string_equal("cfengine_mail@example.org", config->mail_to_address); assert_string_equal("Test [localhost/127.0.0.1]", config->mail_subject); assert_int_equal(50, config->mail_max_lines); + assert_int_equal(25, config->mail_port); assert_string_equal("localhost.localdomain", config->fq_name); assert_string_equal("127.0.0.100", config->ip_address); assert_string_equal("127.0.0.100 127.0.0.101", config->ip_addresses);