summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-12-09 09:38:04 -0500
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-12-09 09:38:04 -0500
commit7497f20a4821515fc9c8dadf85d3c4f3b47245eb (patch)
treebe129aa775852ed70bac6be82af719b9bfc7901f /src/lib/Bcfg2/Server/Lint/TemplateAbuse.py
parenteff366a0c3b9ba87f3ee06f90dccdd242579b7b1 (diff)
parentbf2ee31f956447fa42ae85dc69820405eda8c490 (diff)
downloadbcfg2-7497f20a4821515fc9c8dadf85d3c4f3b47245eb.tar.gz
bcfg2-7497f20a4821515fc9c8dadf85d3c4f3b47245eb.tar.bz2
bcfg2-7497f20a4821515fc9c8dadf85d3c4f3b47245eb.zip
Merge branch 'maint'
Conflicts: doc/appendix/guides/fedora.txt misc/bcfg2.spec schemas/types.xsd src/lib/Bcfg2/Encryption.py src/lib/Bcfg2/Options.py src/lib/Bcfg2/Server/Admin/Client.py src/lib/Bcfg2/Server/Core.py src/lib/Bcfg2/Server/Lint/Validate.py src/lib/Bcfg2/Server/Plugin/helpers.py src/lib/Bcfg2/Server/Plugins/Bundler.py src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenerator.py src/lib/Bcfg2/Server/Plugins/Probes.py src/sbin/bcfg2-crypt testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgEncryptedGenerator.py testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py testsuite/common.py testsuite/install.sh
Diffstat (limited to 'src/lib/Bcfg2/Server/Lint/TemplateAbuse.py')
-rw-r--r--src/lib/Bcfg2/Server/Lint/TemplateAbuse.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py b/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py
new file mode 100644
index 000000000..202a1487d
--- /dev/null
+++ b/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py
@@ -0,0 +1,76 @@
+""" Check for templated scripts or executables. """
+
+import os
+import stat
+import Bcfg2.Server.Lint
+from Bcfg2.Compat import any # pylint: disable=W0622
+from Bcfg2.Server.Plugin import default_path_metadata
+from Bcfg2.Server.Plugins.Cfg.CfgInfoXML import CfgInfoXML
+from Bcfg2.Server.Plugins.Cfg.CfgGenshiGenerator import CfgGenshiGenerator
+from Bcfg2.Server.Plugins.Cfg.CfgCheetahGenerator import CfgCheetahGenerator
+from Bcfg2.Server.Plugins.Cfg.CfgEncryptedGenshiGenerator import \
+ CfgEncryptedGenshiGenerator
+from Bcfg2.Server.Plugins.Cfg.CfgEncryptedCheetahGenerator import \
+ CfgEncryptedCheetahGenerator
+
+
+class TemplateAbuse(Bcfg2.Server.Lint.ServerPlugin):
+ """ Check for templated scripts or executables. """
+ templates = [CfgGenshiGenerator, CfgCheetahGenerator,
+ CfgEncryptedGenshiGenerator, CfgEncryptedCheetahGenerator]
+ extensions = [".pl", ".py", ".sh", ".rb"]
+
+ def Run(self):
+ if 'Cfg' in self.core.plugins:
+ for entryset in self.core.plugins['Cfg'].entries.values():
+ for entry in entryset.entries.values():
+ if (self.HandlesFile(entry.name) and
+ any(isinstance(entry, t) for t in self.templates)):
+ self.check_template(entryset, entry)
+
+ @classmethod
+ def Errors(cls):
+ return {"templated-script": "warning",
+ "templated-executable": "warning"}
+
+ def check_template(self, entryset, entry):
+ """ Check a template to see if it's a script or an executable. """
+ # first, check for a known script extension
+ ext = os.path.splitext(entryset.path)[1]
+ if ext in self.extensions:
+ self.LintError("templated-script",
+ "Templated script found: %s\n"
+ "File has a known script extension: %s\n"
+ "Template a config file for the script instead" %
+ (entry.name, ext))
+ return
+
+ # next, check for a shebang line
+ firstline = open(entry.name).readline()
+ if firstline.startswith("#!"):
+ self.LintError("templated-script",
+ "Templated script found: %s\n"
+ "File starts with a shebang: %s\n"
+ "Template a config file for the script instead" %
+ (entry.name, firstline))
+ return
+
+ # finally, check for executable permissions in info.xml
+ for entry in entryset.entries.values():
+ if isinstance(entry, CfgInfoXML):
+ for pinfo in entry.infoxml.pnode.data.xpath("//FileInfo"):
+ try:
+ mode = int(
+ pinfo.get("mode",
+ default_path_metadata()['mode']), 8)
+ except ValueError:
+ # LintError will be produced by RequiredAttrs plugin
+ self.logger.warning("Non-octal mode: %s" % mode)
+ continue
+ if mode & stat.S_IXUSR != 0:
+ self.LintError(
+ "templated-executable",
+ "Templated executable found: %s\n"
+ "Template a config file for the executable instead"
+ % entry.name)
+ return