18326 imageconfig should cope with running pkg operations as an unprivileged user
authorBrock Pytlik <brock.pytlik@oracle.com>
Mon, 16 May 2011 11:51:51 -0700
changeset 2360 ce037ea421aa
parent 2358 32123821917d
child 2361 1b5ced2f406f
18326 imageconfig should cope with running pkg operations as an unprivileged user
src/modules/client/image.py
src/modules/client/imageconfig.py
src/tests/cli/t_pkg_sysrepo.py
--- a/src/modules/client/image.py	Mon May 16 08:42:56 2011 -0700
+++ b/src/modules/client/image.py	Mon May 16 11:51:51 2011 -0700
@@ -871,8 +871,12 @@
                         for p in self.cfg.removed_pubs:
                                 p.meta_root = self._get_publisher_meta_root(
                                     p.prefix)
-                                self.remove_publisher_metadata(p, rebuild=False)
-                                changed = True
+                                try:
+                                        self.remove_publisher_metadata(p,
+                                            rebuild=False)
+                                        changed = True
+                                except apx.PermissionsException:
+                                        pass
                         if changed:
                                 self.__rebuild_image_catalogs()
 
--- a/src/modules/client/imageconfig.py	Mon May 16 08:42:56 2011 -0700
+++ b/src/modules/client/imageconfig.py	Mon May 16 11:51:51 2011 -0700
@@ -816,8 +816,11 @@
         """Dummy system publisher object for use when an image doesn't use a
         system publisher."""
 
+        __supported_props = ("publisher-search-order", "property.proxied-urls")
+
         def __init__(self):
                 self.publishers = {}
+                self.__props = dict([(p, []) for p in self.__supported_props])
 
         def write(self):
                 return
@@ -827,8 +830,14 @@
                 has any knowledge of it."""
 
                 if section == "property" and \
-                    name in ("publisher-search-order", "property.proxied-urls"):
-                        return []
+                    name in self.__supported_props:
+                        return self.__props[name]
+                raise NotImplementedError()
+
+        def set_property(self, section, name, value):
+                if section == "property" and name in self.__supported_props:
+                        self.__props[name] = value
+                        return
                 raise NotImplementedError()
 
 
@@ -902,13 +911,45 @@
                                 self.sys_cfg = old_sysconfig
                         else:
                                 try:
-                                        # Remove any previous system repository
-                                        # configuration.
-                                        portable.remove(syscfg_path)
+                                        try:
+                                                # Try to remove any previous
+                                                # system repository
+                                                # configuration.
+                                                portable.remove(syscfg_path)
+                                        except OSError, e:
+                                                if e.errno == errno.ENOENT:
+                                                        # Check to see whether
+                                                        # we'll be able to write
+                                                        # the configuration
+                                                        # later.
+                                                        with open(syscfg_path,
+                                                            "wb") as fh:
+                                                                fh.close()
+                                                        self.sys_cfg = \
+                                                            ImageConfig(
+                                                            syscfg_path, None)
+                                                else:
+                                                        raise
                                 except OSError, e:
-                                        if e.errno != errno.ENOENT:
+                                        if e.errno in \
+                                            (errno.EACCES, errno.EROFS):
+                                                # A permissions error means that
+                                                # either we couldn't remove the
+                                                # existing configuration or
+                                                # create a new configuration in
+                                                # that place.  In that case, use
+                                                # an in-memory only version of
+                                                # the ImageConfig.
+                                                self.sys_cfg = \
+                                                    NullSystemPublisher()
+                                        else:
                                                 raise
-                                self.sys_cfg = ImageConfig(syscfg_path, None)
+                                else:
+                                        # The previous configuration was
+                                        # successfully removed, so use that
+                                        # location for the new ImageConfig.
+                                        self.sys_cfg = \
+                                            ImageConfig(syscfg_path, None)
                                 for p in pubs:
                                         assert not p.disabled, "System " \
                                             "publisher %s was unexpectedly " \
--- a/src/tests/cli/t_pkg_sysrepo.py	Mon May 16 08:42:56 2011 -0700
+++ b/src/tests/cli/t_pkg_sysrepo.py	Mon May 16 11:51:51 2011 -0700
@@ -79,6 +79,13 @@
 
         misc_files = ["tmp/example_file"]
 
+        expected_all_access =  """\
+PUBLISHER\tSTICKY\tSYSPUB\tENABLED\tTYPE\tSTATUS\tURI
+test1\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
+test12\tfalse\ttrue\ttrue\torigin\tonline\tproxy://%s/
+test3\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
+"""
+
         def killalldepots(self):
                 try:
                         pkg5unittest.ManyDepotTestCase.killalldepots(self)
@@ -371,8 +378,10 @@
                 if update_conf and self.sc:
                         self.sc.conf = self.apache_confs[name]
 
-        def __check_publisher_info(self, expected, set_debug_value=True):
-                self.pkg("publisher -F tsv", debug_smf=set_debug_value)
+        def __check_publisher_info(self, expected, set_debug_value=True,
+            su_wrap=False):
+                self.pkg("publisher -F tsv", debug_smf=set_debug_value,
+                    su_wrap=su_wrap)
                 output = self.reduceSpaces(self.output)
                 self.assertEqualDiff(expected, output, bound_white_space=True)
 
@@ -409,12 +418,8 @@
                 for n in ("test1", "test12", "test3"):
                         self.assert_(os.path.isdir(os.path.join(self.img_path(),
                             "var/pkg/publisher/%s" % n)))
-                expected = """\
-PUBLISHER\tSTICKY\tSYSPUB\tENABLED\tTYPE\tSTATUS\tURI
-test1\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
-test12\tfalse\ttrue\ttrue\torigin\tonline\tproxy://%s/
-test3\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
-""" % (self.durl1, self.durl2, self.durl3)
+                expected =  self.expected_all_access % \
+                    (self.durl1, self.durl2, self.durl3)
                 self.__check_publisher_info(expected)
 
                 self.pkg("publisher test1")
@@ -453,12 +458,8 @@
                 api_obj = self.image_create(props={"use-system-repo": True})
                 self.sc.conf = self.apache_confs["none"]
 
-                expected = """\
-PUBLISHER\tSTICKY\tSYSPUB\tENABLED\tTYPE\tSTATUS\tURI
-test1\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
-test12\tfalse\ttrue\ttrue\torigin\tonline\tproxy://%s/
-test3\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
-""" % (self.durl1, self.durl2, self.durl3)
+                expected =  self.expected_all_access % \
+                    (self.durl1, self.durl2, self.durl3)
                 self.__check_publisher_info(expected)
 
                 self.pkg("list -a")
@@ -978,12 +979,8 @@
                 os.environ["PKG_SYSREPO_URL"] = "localhost:%s" % \
                     self.sysrepo_alt_port
                 api_obj = self.image_create(props={"use-system-repo": True})
-                expected = """\
-PUBLISHER\tSTICKY\tSYSPUB\tENABLED\tTYPE\tSTATUS\tURI
-test1\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
-test12\tfalse\ttrue\ttrue\torigin\tonline\tproxy://%s/
-test3\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
-""" % (self.durl1, self.durl2, self.durl3)
+                expected =  self.expected_all_access % \
+                    (self.durl1, self.durl2, self.durl3)
                 self.__check_publisher_info(expected, set_debug_value=False)
                 if old_psu:
                         os.environ["PKG_SYSREPO_URL"] = old_psu
@@ -1081,12 +1078,8 @@
                 self.__check_publisher_info(expected)
 
                 self.__set_responses("all-access")
-                expected = """\
-PUBLISHER\tSTICKY\tSYSPUB\tENABLED\tTYPE\tSTATUS\tURI
-test1\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
-test12\tfalse\ttrue\ttrue\torigin\tonline\tproxy://%s/
-test3\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%s/
-""" % (self.durl1, self.durl2, self.durl3)
+                expected =  self.expected_all_access % \
+                    (self.durl1, self.durl2, self.durl3)
                 self.__check_publisher_info(expected)
 
         def test_10_test_mirrors(self):
@@ -1162,12 +1155,8 @@
                 self.__check_publisher_info(expected)
 
                 self.__set_responses("all-access")
-                expected = """\
-PUBLISHER\tSTICKY\tSYSPUB\tENABLED\tTYPE\tSTATUS\tURI
-test1\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%(durl1)s/
-test12\tfalse\ttrue\ttrue\torigin\tonline\tproxy://%(durl2)s/
-test3\ttrue\ttrue\ttrue\torigin\tonline\tproxy://%(durl3)s/
-""" % {"durl1": self.durl1, "durl2": self.durl2, "durl3": self.durl3}
+                expected =  self.expected_all_access % \
+                    (self.durl1, self.durl2, self.durl3)
                 self.__check_publisher_info(expected)
 
                 self.__set_responses("mirror-access")
@@ -1262,6 +1251,34 @@
 test3\ttrue\ttrue\ttrue\torigin\tonline\thttp://localhost:%(port)s/test3/%(hash3)s/
 """ % {"port": self.sysrepo_port, "hash1": hash1, "hash3": hash3}
 
+        def test_bug_18326(self):
+                """Test that an unprivileged user can use non-image modifying
+                commands and that image modifying commands don't trace back."""
+
+                self.__prep_configuration(["all-access", "none"])
+                self.__set_responses("all-access")
+                self.sc = pkg5unittest.SysrepoController(
+                    self.apache_confs["all-access"], self.sysrepo_port,
+                    self.common_config_dir, testcase=self)
+                self.sc.start()
+                api_obj = self.image_create(props={"use-system-repo": True})
+
+                expected =  self.expected_all_access % \
+                    (self.durl1, self.durl2, self.durl3)
+                self.__check_publisher_info(expected, su_wrap=True)
+                self.pkg("property", su_wrap=True)
+                self.pkg("install foo", su_wrap=True, exit=1)
+
+                self.__set_responses("none")
+                expected = """\
+PUBLISHER\tSTICKY\tSYSPUB\tENABLED\tTYPE\tSTATUS\tURI
+"""
+                self.__check_publisher_info(expected, su_wrap=True)
+                self.__check_publisher_info(expected)
+                self.__set_responses("all-access")
+                expected =  self.expected_all_access % \
+                    (self.durl1, self.durl2, self.durl3)
+                self.__check_publisher_info(expected, su_wrap=True)
 
 
         __smf_cmds_template = { \