Skip to content

Commit

Permalink
Merge pull request #174 from nperron/ust_3115/dev/3858_add_suid_sgid_…
Browse files Browse the repository at this point in the history
…to_downloaded_files_bis

Fixes #3858 - Add possibility to set SUID and SGID for Download a file from a shared folder
  • Loading branch information
jooooooon committed Aug 29, 2013
2 parents 7f104c8 + b0b0f63 commit c51c2a9
Show file tree
Hide file tree
Showing 2 changed files with 326 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#####################################################################################
# Copyright 2011 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################


bundle agent download_from_shared_folder
{

vars:

&COPYFILE_NAME:{name |"copyfile[&i&][name]" string => "&name&";
}&

&COPYFILE_RECURSION:{rec |"copyfile[&i&][recursion]" string => "&rec&";
}&

&COPYFILE_OWNER:{owner |"copyfile[&i&][owner]" string => "&owner&";
}&

&COPYFILE_GROUP:{group |"copyfile[&i&][group]" string => "&group&";
}&

&COPYFILE_COMPARE_METHOD:{compare_method |"copyfile[&i&][compare_method]" string => "&compare_method&";
}&

&COPYFILE_PERM:{perms |"copyfile[&i&][perm]" string => "&perms&";
}&

&COPYFILE_DESTINATION:{destination |"copyfile[&i&][destination]" string => "&destination&";
}&

&COPYFILE_POST_HOOK_COMMAND:{command |"copyfile[&i&][posthook]" string => "&command&";
}&

&TRACKINGKEY:{piuuid |"copyfile[&i&][uuid]" string => "&piuuid&";
}&
"shared_folder" string => "&SHARED_FILES_FOLDER&";

"index" slist => getindices("copyfile");

iteration_1::
"extended_modes_${index}"
string => "4",
ifvarclass => "enable_suid_${index}.!enable_sgid_${index}";

"extended_modes_${index}"
string => "2",
ifvarclass => "!enable_suid_${index}.enable_sgid_${index}";

"extended_modes_${index}"
string => "6",
ifvarclass => "enable_suid_${index}.enable_sgid_${index}";

"extended_modes_${index}"
string => "0",
ifvarclass => "!enable_suid_${index}.!enable_sgid_${index}";

classes:
"is_valid" not => strcmp("&SHARED_FILES_FOLDER&", "");

"is_file_${index}" not => isdir("${copyfile[${index}][destination]}");
"exist_${index}" expression => fileexists("${copyfile[${index}][destination]}");

&COPYFILE_SUID:{suid |"enable_suid_&i&" expression => strcmp("&suid&", "true");
}&
&COPYFILE_SGID:{sgid |"enable_sgid_&i&" expression => strcmp("&sgid&", "true");
}&
# Set a class to define when we need to run the post-modification hook
&COPYFILE_POST_HOOK_RUN:{run |"execute_command_&i&" expression => strcmp("&run&", "true");
}&

"iteration_2" expression => "iteration_1";
"iteration_1" expression => "any";


files:
is_valid.iteration_2::

"${copyfile[${index}][destination]}"
copy_from => scp("&SHARED_FILES_FOLDER&/${copyfile[${index}][name]}", "${server_info.cfserved}", "${copyfile[${index}][compare_method]}", "false", "false", "false"),
depth_search => recurse("${copyfile[${index}][recursion]}"),
perms => mog(
"${copyfile[${index}][perm]}",
"${copyfile[${index}][owner]}",
"${copyfile[${index}][group]}"
),
comment => "Enforce content of ${copyfile[${index}][destination]} based on the content on the Rudder server with ${copyfile[${index}][compare_method]} method",
classes => kept_if_else("copy_file_${index}_kept", "copy_file_${index}_modified", "copy_file_${index}_failed"),
ifvarclass => "!exist_${index}|!is_file_${index}";

# If it s a file, the depth_search prevents from enforcing the file content
# Besides it is possible to specify suid or sgid only for a file since this
# is too dangerous to apply suid or sgid recursively and only copy an empty
# directory does not make sense.
"${copyfile[${index}][destination]}"
copy_from => scp("&SHARED_FILES_FOLDER&/${copyfile[${index}][name]}", "${server_info.cfserved}", "${copyfile[${index}][compare_method]}", "false", "false", "false"),
perms => mog(
"${extended_modes_${index}}${copyfile[${index}][perm]}",
"${copyfile[${index}][owner]}",
"${copyfile[${index}][group]}"
),
comment => "Enforce content of file ${copyfile[${index}][destination]} based on the content on the Rudder server with ${copyfile[${index}][compare_method]} method",
classes => kept_if_else("copy_file_${index}_kept", "copy_file_${index}_modified", "copy_file_${index}_failed"),
ifvarclass => "exist_${index}.is_file_${index}";

commands:
"${copyfile[${index}][posthook]}"
contain => in_shell,
classes => if_else("copyfile_posthook_${index}_command_run_ok", "copyfile_posthook_${index}_command_run_failed"),
ifvarclass => "execute_command_${index}.copy_file_${index}_modified.!copy_file_${index}_failed",
comment => "Execute the posthook command if a file was changed";

reports:
!is_valid::
"@@copyFile@@result_error@@${copyfile[${index}][uuid]}@@Copy file@@${copyfile[${index}][name]}@@${g.execRun}##${g.uuid}@#There is no shared folder on the Rudder Server, so it's not possible to copy a file from it";
linux|windows::
"@@copyFile@@result_success@@${copyfile[${index}][uuid]}@@Copy file@@${copyfile[${index}][name]}@@${g.execRun}##${g.uuid}@#The content of the file(s) is valid"
ifvarclass => "copy_file_${index}_kept.!copy_file_${index}_modified.!copy_file_$(index)_failed";

"@@copyFile@@result_repaired@@${copyfile[${index}][uuid]}@@Copy file@@${copyfile[${index}][name]}@@${g.execRun}##${g.uuid}@#The content or permissions of the file(s) has been repaired"
ifvarclass => "copy_file_${index}_modified.!copy_file_$(index)_failed";

"@@copyFile@@result_error@@${copyfile[${index}][uuid]}@@Copy file@@${copyfile[${index}][name]}@@${g.execRun}##${g.uuid}@#The content or permissions of the file(s) could not have been repaired for some reason"
ifvarclass => "copy_file_${index}_failed";

#posthook reports
"@@copyFile@@result_success@@${copyfile[${index}][uuid]}@@Post-modification hook@@${copyfile[${index}][name]}@@${g.execRun}##${g.uuid}@#No post-hook command for ${copyfile[${index}][destination]} was defined, not executing"
ifvarclass => "!execute_command_${index}";

"@@copyFile@@result_success@@${copyfile[${index}][uuid]}@@Post-modification hook@@${copyfile[${index}][name]}@@${g.execRun}##${g.uuid}@#${copyfile[${index}][destination]} was already in the desired state, so no command was executed"
ifvarclass => "execute_command_${index}.copy_file_${index}_kept.!copy_file_${index}_modified";

"@@copyFile@@result_success@@${copyfile[${index}][uuid]}@@Post-modification hook@@${copyfile[${index}][name]}@@${g.execRun}##${g.uuid}@#The post-hook command for ${copyfile[${index}][destination]} was correctly executed"
ifvarclass => "copyfile_posthook_${index}_command_run_ok";

"@@copyFile@@result_error@@${copyfile[${index}][uuid]}@@Post-modification hook@@${copyfile[${index}][name]}@@${g.execRun}##${g.uuid}@#The post-hook command for ${copyfile[${index}][destination]} couldn't be executed"
ifvarclass => "copyfile_posthook_${index}_command_run_failed";

# A copy_from + perms could result in any combinaision of success/repaired/failed, so we have to cover the failed.modified which results in no copy
"@@copyFile@@result_error@@$(copyfile[$(index)][uuid])@@Post-modification hook@@$(copyfile[$(index)][name])@@$(g.execRun)##$(g.uuid)@#$(copyfile[$(index)][destination]) couldn't be copied, so the post-hook command is not executed"
ifvarclass => "execute_command_$(index).copy_file_$(index)_failed";
}
170 changes: 170 additions & 0 deletions techniques/fileDistribution/copyGitFile/1.4/metadata.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<!--
Copyright 2011 Normation SAS
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, Version 3.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->

<TECHNIQUE name="Download a file from the shared folder">
<DESCRIPTION>This technique ensure that some files are the copy of files on the shared folder of the Rudder Root Server, and let you optionally execute a command if the content of the file was modified</DESCRIPTION>

<MULTIINSTANCE>true</MULTIINSTANCE>
<COMPATIBLE>
<OS version=">= 4 (Etch)">Debian</OS>
<OS version=">= 4 (Nahant)">RHEL / CentOS</OS>
<OS version=">= 10 SP1 (Agama Lizard)">SuSE LES / DES / OpenSuSE</OS>
<AGENT version=">= 3.2.0">cfengine-community</AGENT>
</COMPATIBLE>

<BUNDLES>
<NAME>download_from_shared_folder</NAME>
</BUNDLES>

<TMLS>
<TML name="copyFileFromSharedFolder"/>
</TMLS>

<TRACKINGVARIABLE>
<SAMESIZEAS>COPYFILE_NAME</SAMESIZEAS>
</TRACKINGVARIABLE>

<SYSTEMVARS>
<NAME>SHARED_FILES_FOLDER</NAME>
</SYSTEMVARS>

<SECTIONS>
<SECTION name="Copy file and PostHook" multivalued="true">
<SECTION name="Copy file" multivalued="false" component="true" componentKey="COPYFILE_NAME">
<INPUT>
<NAME>COPYFILE_NAME</NAME>
<DESCRIPTION>Path of the file to be copied</DESCRIPTION>
<LONGDESCRIPTION>This is the relative path of the file/folder to be copied, on the Rudder policy server</LONGDESCRIPTION>
</INPUT>
<INPUT>
<NAME>COPYFILE_DESTINATION</NAME>
<DESCRIPTION>Destination of the file</DESCRIPTION>
<LONGDESCRIPTION>This is the absolute path of the file/folder on the managed node</LONGDESCRIPTION>
</INPUT>
<SELECT1>
<NAME>COPYFILE_RECURSION</NAME>
<DESCRIPTION>What should be the recursion level of the copy</DESCRIPTION>
<ITEM>
<VALUE>0</VALUE>
<LABEL>Only this file</LABEL>
</ITEM>
<ITEM>
<VALUE>1</VALUE>
<LABEL>The whole content of the folder</LABEL>
</ITEM>
<ITEM>
<VALUE>inf</VALUE>
<LABEL>The folder, its content, and all the subfolders</LABEL>
</ITEM>
<CONSTRAINT>
<DEFAULT>0</DEFAULT>
</CONSTRAINT>
</SELECT1>
<SELECT1>
<NAME>COPYFILE_COMPARE_METHOD</NAME>
<DESCRIPTION>File comparison method</DESCRIPTION>
<LONGDESCRIPTION>This is the method to use for comparison between source and destination files.
- "mtime" copies the file if the modification time of the source file is more recent than that of the promised file.
- "ctime" CFEngine copies the file if the creation time of the source file is more recent than that of the promised file.
- "atime" CFEngine copies the file if the modification time or creation time of the source file is more recent than that of the promised file. If the times are equal, a byte-for-byte comparison is done on the files to determine if it needs to be copied.
- "exists" copies the file if the promised file does not already exist.
- "binary" copies the file if they are both plain files and a byte-for-byte comparison determines that they are different. If both are not plain files, CFEngine reverts to comparing the mtime and ctime of the files. If the source file is on a different machine (i.e., network copy), then hash is used instead to reduce network bandwidth.
- "digest" copies the file if they are both plain files and a MD5 message digest comparison indicates that the files are different.
The "mtime" option is set by default but "digest" is highly recommended for critical files such as shadow.</LONGDESCRIPTION>
<ITEM>
<VALUE>mtime</VALUE>
<LABEL>mtime</LABEL>
</ITEM>
<ITEM>
<VALUE>atime</VALUE>
<LABEL>atime</LABEL>
</ITEM>
<ITEM>
<VALUE>ctime</VALUE>
<LABEL>ctime</LABEL>
</ITEM>
<ITEM>
<VALUE>digest</VALUE>
<LABEL>digest</LABEL>
</ITEM>
<ITEM>
<VALUE>binary</VALUE>
<LABEL>binary</LABEL>
</ITEM>
<ITEM>
<VALUE>exists</VALUE>
<LABEL>exists</LABEL>
</ITEM>
</SELECT1>

<INPUT>
<NAME>COPYFILE_OWNER</NAME>
<DESCRIPTION>Owner of the file</DESCRIPTION>
<CONSTRAINT>
<DEFAULT>root</DEFAULT>
</CONSTRAINT>
</INPUT>
<INPUT>
<NAME>COPYFILE_GROUP</NAME>
<DESCRIPTION>Group of the file</DESCRIPTION>
<CONSTRAINT>
<DEFAULT>root</DEFAULT>
</CONSTRAINT>
</INPUT>
<INPUT>
<NAME>COPYFILE_PERM</NAME>
<DESCRIPTION>Permissions to apply on the file</DESCRIPTION>
<CONSTRAINT>
<TYPE>perm</TYPE>
</CONSTRAINT>
</INPUT>
<INPUT>
<NAME>COPYFILE_SUID</NAME>
<DESCRIPTION>Set SetUID bit?</DESCRIPTION>
<LONGDESCRIPTION>Note: The SetUID and SetGID bits will not be applied recursively, for obvious security reasons.</LONGDESCRIPTION>
<CONSTRAINT>
<TYPE>boolean</TYPE>
</CONSTRAINT>
</INPUT>
<INPUT>
<NAME>COPYFILE_SGID</NAME>
<DESCRIPTION>Set SetGID bit?</DESCRIPTION>
<LONGDESCRIPTION>Note: The SetUID and SetGID bits will not be applied recursively, for obvious security reasons.</LONGDESCRIPTION>
<CONSTRAINT>
<TYPE>boolean</TYPE>
</CONSTRAINT>
</INPUT>
</SECTION>

<SECTION name="Post-modification hook" component="true" multivalued="false" componentKey="COPYFILE_NAME">
<INPUT>
<NAME>COPYFILE_POST_HOOK_RUN</NAME>
<DESCRIPTION>Should the command(s) below be run if any modifications (permission or overwriting) are made on the files above?</DESCRIPTION>
<CONSTRAINT><TYPE>boolean</TYPE></CONSTRAINT>
</INPUT>
<INPUT>
<NAME>COPYFILE_POST_HOOK_COMMAND</NAME>
<DESCRIPTION>Command to run after any modifications</DESCRIPTION>
<CONSTRAINT>
<TYPE>textarea</TYPE>
<MAYBEEMPTY>true</MAYBEEMPTY>
</CONSTRAINT>
</INPUT>
</SECTION>
</SECTION>
</SECTIONS>

</TECHNIQUE>

0 comments on commit c51c2a9

Please sign in to comment.