15686 pkgsend create-repository should not create cfg_cache with mode 0600
authorRichard Lowe <richlowe@richlowe.net>
Sat, 24 Apr 2010 23:40:12 -0400
changeset 1878 badde6b7111b
parent 1877 3bdaef023cdb
child 1879 7dc50f542f19
15686 pkgsend create-repository should not create cfg_cache with mode 0600
src/modules/server/repositoryconfig.py
src/tests/api/t_repositoryconfig.py
--- a/src/modules/server/repositoryconfig.py	Tue Apr 27 08:08:43 2010 +0100
+++ b/src/modules/server/repositoryconfig.py	Sat Apr 24 23:40:12 2010 -0400
@@ -20,13 +20,16 @@
 # CDDL HEADER END
 #
 
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
 
 import ConfigParser
+import errno
 import os
 from pkg import misc, portable
 import random
+import stat
 import tempfile
 import uuid
 
@@ -491,13 +494,31 @@
                 try:
                         dirname = os.path.dirname(self.__pathname)
                         fd, fn = tempfile.mkstemp(dir=dirname)
+
+                        st = None
+                        try:
+                                st = os.stat(self.__pathname)
+                        except OSError, e:
+                                if e.errno != errno.ENOENT:
+                                        raise
+
+                        if st:
+                                os.fchmod(fd, stat.S_IMODE(st.st_mode))
+                                try:
+                                        portable.chown(fn, st.st_uid, st.st_gid)
+                                except OSError, e:
+                                        if e.errno != errno.EPERM:
+                                                raise
+                        else:
+                                os.fchmod(fd, misc.PKG_FILE_MODE)
+
                         with os.fdopen(fd, "w") as f:
                                 cp.write(f)
                         portable.rename(fn, self.__pathname)
                         self.__dirty = False
                 except EnvironmentError, e:
-                        raise RuntimeError("Unable to open %s for writing: "
-                            "%s" % (e.pathname, e.strerror))
+                        raise RuntimeError("Failed to write configuration: %s: "
+                            "%s" % (e.filename, e.strerror))
                 finally:
                         if fn and os.path.exists(fn):
                                 os.unlink(fn)
--- a/src/tests/api/t_repositoryconfig.py	Tue Apr 27 08:08:43 2010 +0100
+++ b/src/tests/api/t_repositoryconfig.py	Sat Apr 24 23:40:12 2010 -0400
@@ -20,8 +20,9 @@
 # CDDL HEADER END
 #
 
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
 
 import testutils
 if __name__ == "__main__":
@@ -31,9 +32,10 @@
 import unittest
 import copy
 import os
-import sys
+import stat
 import tempfile
 
+from pkg import misc, portable
 import pkg.server.repositoryconfig as rcfg
 
 class TestRepositoryConfig(pkg5unittest.Pkg5TestCase):
@@ -558,6 +560,35 @@
                 self.assertEqual(rc.get_property("publisher", "prefix"),
                     "overridden")
 
+        def test_perms_are_sane(self):
+                """Verify that cfg_cache is created with sane permissions,
+                and retains user-specified permissions
+                """
+
+                os.remove(self.sample_conf)
+
+                rc = rcfg.RepositoryConfig(self.sample_conf,
+                    {"publisher": {"prefix": "default"}})
+                rc.write()
+                self.assertEqual(stat.S_IMODE(
+                    os.stat(self.sample_conf).st_mode), misc.PKG_FILE_MODE)
+
+                os.chmod(self.sample_conf, 0777)
+                rc = rcfg.RepositoryConfig(self.sample_conf)
+                rc.set_property("publisher", "prefix", "foobar")
+                rc.write()
+                self.assertEqual(
+                    stat.S_IMODE(os.stat(self.sample_conf).st_mode), 0777)
+
+                if portable.util.get_canonical_os_type() == "unix":
+                        portable.chown(self.sample_conf, 65534, 65534)
+                        rc = rcfg.RepositoryConfig(self.sample_conf)
+                        rc.set_property("publisher", "prefix", "foobaz")
+                        rc.write()
+                        self.assertEqual(os.stat(self.sample_conf).st_uid,
+                            65534)
+                        self.assertEqual(os.stat(self.sample_conf).st_gid,
+                            65534)
 
 if __name__ == "__main__":
         unittest.main()