* Created anvil-daemon->check_setuid_wrappers() function that will dynamically create setuid c-wrappers on daemon startup, when needed.

* Updated variable names to clarify their purpose in striker.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent 99e1e4faf2
commit 6f74ca376b
  1. 1
      Anvil/Tools.pm
  2. 6
      Anvil/Tools/Storage.pm
  3. 29
      cgi-bin/striker
  4. 3
      share/words.xml
  5. 88
      tools/anvil-daemon

@ -1031,6 +1031,7 @@ sub _set_paths
expect => "/usr/bin/expect", expect => "/usr/bin/expect",
'firewall-cmd' => "/usr/bin/firewall-cmd", 'firewall-cmd' => "/usr/bin/firewall-cmd",
free => "/usr/bin/free", free => "/usr/bin/free",
gcc => "/usr/bin/gcc",
getent => "/usr/bin/getent", getent => "/usr/bin/getent",
gethostip => "/usr/bin/gethostip", gethostip => "/usr/bin/gethostip",
'grep' => "/usr/bin/grep", 'grep' => "/usr/bin/grep",

@ -420,9 +420,9 @@ sub change_owner
my $group = defined $parameter->{group} ? $parameter->{group} : getgrgid($(); my $group = defined $parameter->{group} ? $parameter->{group} : getgrgid($();
my $user = defined $parameter->{user} ? $parameter->{user} : getpwuid($<); my $user = defined $parameter->{user} ? $parameter->{user} : getpwuid($<);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
path => $path, path => $path,
group => $group, group => $group,
user => $user, user => $user,
}}); }});
# Make sure the user and group and just one digit or word. # Make sure the user and group and just one digit or word.

@ -988,11 +988,11 @@ sub add_sync_peer
ping => $ping, ping => $ping,
}}); }});
my $pgsql_port = 5432; my $pgsql_port = 5432;
my $ssh_port = 22; my $ssh_port = 22;
my $peer_uuid = ""; my $peer_host_uuid = "";
my $peer_host = ""; my $peer_host_name = "";
my $use_ip = ""; # This will contain the local IP to use for the peer to setup comms with us my $use_ip = ""; # This will contain the local IP to use for the peer to setup comms with us
if ($host =~ /,ssh=(\d+)$/) if ($host =~ /,ssh=(\d+)$/)
{ {
$ssh_port = $1; $ssh_port = $1;
@ -1083,23 +1083,28 @@ sub add_sync_peer
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /host_name=(.*)$/) if ($line =~ /host_name=(.*)$/)
{ {
$peer_host = $1; # We collect this, but apparently not for any real reason...
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_host => $peer_host }}); $peer_host_name = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_host_name => $peer_host_name }});
} }
if ($line =~ /host_uuid=(.*)$/) if ($line =~ /host_uuid=(.*)$/)
{ {
$peer_uuid = $1; $peer_host_uuid = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_uuid => $peer_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_host_uuid => $peer_host_uuid }});
} }
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
peer_host_name => $peer_host_name,
peer_host_uuid => $peer_host_uuid,
}});
# Make sure the database entry is gone (striker-get-peer-data should have removed it, but lets be safe). # Make sure the database entry is gone (striker-get-peer-data should have removed it, but lets be safe).
my $query = "DELETE FROM states WHERE state_name = ".$anvil->Database->quote("peer::".$host."::password").";"; my $query = "DELETE FROM states WHERE state_name = ".$anvil->Database->quote("peer::".$host."::password").";";
$anvil->Database->write({uuid => $anvil->data->{sys}{host_uuid}, debug => 2, query => $query, source => $THIS_FILE, line => __LINE__}); $anvil->Database->write({uuid => $anvil->data->{sys}{host_uuid}, debug => 2, query => $query, source => $THIS_FILE, line => __LINE__});
if (not $anvil->Validate->is_uuid({uuid => $peer_uuid})) if (not $anvil->Validate->is_uuid({uuid => $peer_host_uuid}))
{ {
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0005", variables => { uuid => $peer_uuid }}) }}); $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0005", variables => { uuid => $peer_host_uuid }}) }});
} }
# Lastly, if bi-directional is set, make sure we have a way to talk to it. # Lastly, if bi-directional is set, make sure we have a way to talk to it.
@ -1169,7 +1174,7 @@ sub add_sync_peer
if ($anvil->data->{cgi}{confirm}{value}) if ($anvil->data->{cgi}{confirm}{value})
{ {
# OK, save the job! # OK, save the job!
my $job_command = $anvil->data->{path}{exe}{'striker-manage-peers'}." --add --host-uuid ".$peer_uuid." --host ".$host." --port ".$pgsql_port." --ping ".$ping; my $job_command = $anvil->data->{path}{exe}{'striker-manage-peers'}." --add --host-uuid ".$peer_host_uuid." --host ".$host." --port ".$pgsql_port." --ping ".$ping;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
job_command => $job_command, job_command => $job_command,
password => $anvil->Log->is_secure($password), password => $anvil->Log->is_secure($password),

@ -758,6 +758,7 @@ Failed to promote the DRBD resource: [#!variable!resource!#] primary. Expected a
<key name="log_0433">The 'smaps' proc file for the process ID: [#!variable!pid!#] was not found. Did the program just close?</key> <key name="log_0433">The 'smaps' proc file for the process ID: [#!variable!pid!#] was not found. Did the program just close?</key>
<key name="log_0434">- The DRBD resource: [#!variable!resource!#] is in the role: [#!variable!role!#] already, no need to bring it up.</key> <key name="log_0434">- The DRBD resource: [#!variable!resource!#] is in the role: [#!variable!role!#] already, no need to bring it up.</key>
<key name="log_0435">Program: [#!variable!program!#] running as the real user: [#!variable!real_user!# (#!variable!real_uid!#)] and effective user: [#!variable!effective_user!# (#!variable!effective_uid!#)].</key> <key name="log_0435">Program: [#!variable!program!#] running as the real user: [#!variable!real_user!# (#!variable!real_uid!#)] and effective user: [#!variable!effective_user!# (#!variable!effective_uid!#)].</key>
<key name="log_0436">The setuid c-wrapper: [#!variable!wrapper!#] already exists, no need to create it.</key>
<!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. --> <!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. -->
<key name="t_0000">Test</key> <key name="t_0000">Test</key>
@ -1051,6 +1052,8 @@ Failed to generate an RSA public key for the user: [#!variable!user!#]. The outp
<key name="error_0068"><![CDATA[There was a problem reading the password from the database.]]></key> <key name="error_0068"><![CDATA[There was a problem reading the password from the database.]]></key>
<key name="error_0069"><![CDATA[Unable to access the host: [#!variable!host!#].]]></key> <key name="error_0069"><![CDATA[Unable to access the host: [#!variable!host!#].]]></key>
<key name="error_0070"><![CDATA[Unable to find the host UUID on the host: [#!variable!host!#].]]></key> <key name="error_0070"><![CDATA[Unable to find the host UUID on the host: [#!variable!host!#].]]></key>
<key name="error_0071">Something went wrong trying to write: [#!variable!file!#], unable to proceed.</key>
<key name="error_0072">Something went wrong trying to compile the C-program: [#!variable!file!#], unable to proceed.</key>
<!-- These are units, words and so on used when displaying information. --> <!-- These are units, words and so on used when displaying information. -->
<key name="unit_0001">Yes</key> <key name="unit_0001">Yes</key>

@ -810,6 +810,9 @@ sub run_once
# Check the ssh stuff. # Check the ssh stuff.
check_ssh_keys($anvil); check_ssh_keys($anvil);
# Check setuid wrappers
check_setuid_wrappers($anvil);
if ($anvil->data->{switches}{'startup-only'}) if ($anvil->data->{switches}{'startup-only'})
{ {
$anvil->nice_exit({code => 0}); $anvil->nice_exit({code => 0});
@ -818,6 +821,91 @@ sub run_once
return(0); return(0);
} }
# This creates, as needed, the setuid wrappers used by apache to make certain system calls.
sub check_setuid_wrappers
{
my ($anvil) = @_;
# Does the call_striker-get-peer-data wrapper exist yet?
if (-e $anvil->data->{path}{exe}{'call_striker-get-peer-data'})
{
# Exists, skipping.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0436", variables => { wrapper => $anvil->data->{path}{exe}{'call_striker-get-peer-data'} }});
}
else
{
# What is the admin user and group ID?
my $admin_uid = getpwnam('admin');
my $admin_gid = getgrnam('admin');
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
admin_uid => $admin_uid,
admin_gid => $admin_gid,
}});
next if not $admin_uid;
next if not $admin_gid;
# Write the body out
my $call_striker_get_peer_data_body = "#define REAL_PATH \"".$anvil->data->{path}{exe}{'striker-get-peer-data'}."\"\n";
$call_striker_get_peer_data_body .= "main(ac, av)\n";
$call_striker_get_peer_data_body .= "char **av;\n";
$call_striker_get_peer_data_body .= "{\n";
$call_striker_get_peer_data_body .= " setuid(".$admin_uid.");\n";
$call_striker_get_peer_data_body .= " setgid(".$admin_gid.");\n";
$call_striker_get_peer_data_body .= " execv(REAL_PATH, av);\n";
$call_striker_get_peer_data_body .= "}\n";
my $error = $anvil->Storage->write_file({
debug => 2,
file => $anvil->data->{path}{exe}{'call_striker-get-peer-data'}.".c",
body => $call_striker_get_peer_data_body,
mode => '644',
overwrite => 1,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { error => $error }});
# If it wrote out, compile it.
if (not -e $anvil->data->{path}{exe}{'call_striker-get-peer-data'}.".c")
{
# Failed to write.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "error_0071", variables => { file => $anvil->data->{path}{exe}{'call_striker-get-peer-data'}.".c" }});
}
else
{
# Compile it
my ($output, $return_code) = $anvil->System->call({
debug => 2,
shell_call => $anvil->data->{path}{exe}{gcc}." -o ".$anvil->data->{path}{exe}{'call_striker-get-peer-data'}." ".$anvil->data->{path}{exe}{'call_striker-get-peer-data'}.".c",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
return_code => $return_code,
}});
# If it compiled, setuid it.
if (not -e $anvil->data->{path}{exe}{'call_striker-get-peer-data'})
{
# Something went wrong compiling it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "error_0072", variables => { file => $anvil->data->{path}{exe}{'call_striker-get-peer-data'}.".c" }});
}
else
{
$anvil->Storage->change_owner({
debug => 2,
path => $anvil->data->{path}{exe}{'call_striker-get-peer-data'},
user => 'root',
group => 'root',
});
$anvil->Storage->change_mode({
debug => 2,
path => $anvil->data->{path}{exe}{'call_striker-get-peer-data'},
mode => '4755',
});
}
}
}
return(0);
}
# Configure/update the firewall. # Configure/update the firewall.
sub check_firewall sub check_firewall
{ {

Loading…
Cancel
Save