Commit 95897331 authored by Vincent Pelletier's avatar Vincent Pelletier

Drop umask in favour of mode.

umask cannot set a regular file as executable, nor allows setting
suid/sgid/sticky bits.
Using chmod properly, there is no security problem.
parent 6819d839
...@@ -112,9 +112,9 @@ Optional: ...@@ -112,9 +112,9 @@ Optional:
Template's MD5, for file integrity checking. By default, no integrity check Template's MD5, for file integrity checking. By default, no integrity check
is done. is done.
``umask`` ``mode``
Umask, in octal notation (no need for 0-prefix), to create output file with. Mode, in octal representation (no need for 0-prefix) to set output file to.
Defaults to system's umask at the time recipe is instanciated. This is applied before storing anything in output file.
``extensions`` ``extensions``
Jinja2 extensions to enable when rendering the template, Jinja2 extensions to enable when rendering the template,
...@@ -210,7 +210,7 @@ If the md5sum doesn't match, the buildout fail:: ...@@ -210,7 +210,7 @@ If the md5sum doesn't match, the buildout fail::
Specify filesystem permissions Specify filesystem permissions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can specify the umask for rendered file:: You can specify the mode for rendered file::
>>> write('template.in', '{{bar}}') >>> write('template.in', '{{bar}}')
>>> write('buildout.cfg', >>> write('buildout.cfg',
...@@ -223,7 +223,7 @@ You can specify the umask for rendered file:: ...@@ -223,7 +223,7 @@ You can specify the umask for rendered file::
... template = template.in ... template = template.in
... rendered = foo ... rendered = foo
... context = key bar buildout:parts ... context = key bar buildout:parts
... umask = 570 ... mode = 206
... ''') ... ''')
>>> print system(join('bin', 'buildout')), >>> print system(join('bin', 'buildout')),
Uninstalling template. Uninstalling template.
......
...@@ -62,6 +62,8 @@ EXPRESSION_HANDLER = { ...@@ -62,6 +62,8 @@ EXPRESSION_HANDLER = {
} }
class Recipe(object): class Recipe(object):
mode = None
def __init__(self, buildout, name, options): def __init__(self, buildout, name, options):
self.template = zc.buildout.download.Download( self.template = zc.buildout.download.Download(
buildout['buildout'], buildout['buildout'],
...@@ -85,8 +87,10 @@ class Recipe(object): ...@@ -85,8 +87,10 @@ class Recipe(object):
variable_name, )) variable_name, ))
context[variable_name] = EXPRESSION_HANDLER[expression_type]( context[variable_name] = EXPRESSION_HANDLER[expression_type](
expression, buildout, name, options) expression, buildout, name, options)
if 'umask' in options: mode = options.get('mode')
self.umask = int(options['umask'], 8) if mode:
self.mode = int(mode, 8)
# umask is deprecated, but kept for backward compatibility
umask_value = options.get('umask') umask_value = options.get('umask')
if umask_value: if umask_value:
self.umask = int(umask_value, 8) self.umask = int(umask_value, 8)
...@@ -102,7 +106,14 @@ class Recipe(object): ...@@ -102,7 +106,14 @@ class Recipe(object):
outdir = os.path.dirname(self.rendered) outdir = os.path.dirname(self.rendered)
if outdir and not os.path.exists(outdir): if outdir and not os.path.exists(outdir):
os.makedirs(outdir) os.makedirs(outdir)
with open(self.rendered, 'w') as out: # XXX: open doesn't allow providing a filesystem mode, so use
# os.open and os.fdopen instead.
out_fd = os.open(self.rendered,
os.O_CREAT | os.O_TRUNC | os.O_WRONLY,
)
if self.mode is not None:
os.fchmod(out_fd, self.mode)
with os.fdopen(out_fd, 'w') as out:
out.write(Template( out.write(Template(
open(self.template).read(), open(self.template).read(),
extensions=self.extension_list, extensions=self.extension_list,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment