def test_sets_setuid_and_setgid_when_told_to(self): self.metadata.st_mode = 0777 | stat.S_ISUID | stat.S_ISGID obnamlib.set_metadata(self.fs, self.filename, self.metadata, always_set_id_bits=True) st = os.stat(self.filename) self.assertEqual(st.st_mode & stat.S_ISUID, stat.S_ISUID) self.assertEqual(st.st_mode & stat.S_ISGID, stat.S_ISGID)
def setUp(self): self.metadata = obnamlib.Metadata() self.metadata.st_atime_sec = 12765 self.metadata.st_atime_nsec = 0 self.metadata.st_mode = 42 | stat.S_IFREG self.metadata.st_mtime_sec = 10**9 self.metadata.st_mtime_nsec = 0 # make sure the uid/gid magic numbers aren't the current users self.metadata.st_uid = os.getuid() + 1234 self.metadata.st_gid = 5678 while self.metadata.st_gid in os.getgroups(): self.metadata.st_gid += 1 fd, self.filename = tempfile.mkstemp() os.close(fd) # On some systems (e.g. FreeBSD) /tmp is apparently setgid and # default gid of files is therefore not the user's gid. os.chown(self.filename, os.getuid(), os.getgid()) self.fs = obnamlib.LocalFS('/') self.fs.connect() self.uid_set = None self.gid_set = None self.fs.lchown = self.fake_lchown obnamlib.set_metadata(self.fs, self.filename, self.metadata) self.st = os.stat(self.filename)
def restore_safely(self, gen, pathname, metadata): try: dirname = os.path.dirname(pathname) if self.write_ok and not self.fs.exists("./" + dirname): self.fs.makedirs("./" + dirname) set_metadata = True if metadata.isdir(): self.restore_dir(gen, pathname, metadata) elif metadata.islink(): self.restore_symlink(gen, pathname, metadata) elif metadata.st_nlink > 1: link = self.hardlinks.filename(metadata) if link: self.restore_hardlink(pathname, link, metadata) set_metadata = False else: self.hardlinks.add(pathname, metadata) self.restore_first_link(gen, pathname, metadata) else: self.restore_first_link(gen, pathname, metadata) if set_metadata and self.write_ok: try: obnamlib.set_metadata(self.fs, "./" + pathname, metadata) except (IOError, OSError), e: msg = "Could not set metadata: %s: %d: %s" % (pathname, e.errno, e.strerror) logging.error(msg) self.app.ts.notify(msg) self.errors = True except Exception, e: # Reaching this code path means we've hit a bug, so we log a full traceback. msg = "Failed to restore %s:" % (pathname,) logging.exception(msg) self.app.ts.notify(msg + " " + str(e)) self.errors = True
def test_sets_symlink_mtime_perms(self): self.fs.remove(self.filename) self.metadata.st_mode = 0777 | stat.S_IFLNK self.metadata.target = 'target' obnamlib.set_metadata(self.fs, self.filename, self.metadata) st = os.lstat(self.filename) self.assertEqual(st.st_mode, self.metadata.st_mode) self.assertEqual(st.st_mtime, self.metadata.st_mtime_sec)
def test_sets_gid_when_not_running_as_root(self): # Root can set it to any group, non-root can only set it to a group # they are part of. Set it with the real lchown and check the file. # Generally only meaningful if the user is in multiple groups. self.fs.lchown = os.lchown for gid in os.getgroups(): self.metadata.st_gid = gid obnamlib.set_metadata(self.fs, self.filename, self.metadata) self.st = os.stat(self.filename) self.assertEqual(self.st.st_gid, gid) self.fs.lchown = self.fake_lchown
def restore_safely(self, gen, pathname): try: dirname = os.path.dirname(pathname) if self.write_ok and not self.fs.exists('./' + dirname): self.fs.makedirs('./' + dirname) metadata = self.construct_metadata_object(gen, pathname) set_metadata = True if metadata.isdir(): self.restore_dir(gen, pathname, metadata) elif metadata.islink(): self.restore_symlink(gen, pathname, metadata) elif metadata.st_nlink > 1: link = self.hardlinks.filename(metadata) if link: self.restore_hardlink(pathname, link, metadata) set_metadata = False else: self.hardlinks.add(pathname, metadata) self.restore_first_link(gen, pathname, metadata) else: self.restore_first_link(gen, pathname, metadata) if set_metadata and self.write_ok: always = self.app.settings['always-restore-setuid'] try: obnamlib.set_metadata( self.fs, './' + pathname, metadata, always_set_id_bits=always) except (IOError, OSError), e: msg = ('Could not set metadata: %s: %d: %s' % (pathname, e.errno, e.strerror)) logging.error(msg) self.app.ts.error(msg) self.errors = True except Exception, e: # Reaching this code path means we've hit a bug, so we log # a full traceback. msg = "Failed to restore %s:" % (pathname,) logging.exception(msg) self.app.ts.error(msg + " " + str(e)) self.errors = True
def restore_safely(self, gen, pathname): try: dirname = os.path.dirname(pathname) if self.write_ok and not self.fs.exists('./' + dirname): self.fs.makedirs('./' + dirname) metadata = self.construct_metadata_object(gen, pathname) set_metadata = True if metadata.isdir(): self.restore_dir(gen, pathname, metadata) elif metadata.islink(): self.restore_symlink(gen, pathname, metadata) elif metadata.st_nlink > 1: link = self.hardlinks.filename(metadata) if link: self.restore_hardlink(pathname, link, metadata) set_metadata = False else: self.hardlinks.add(pathname, metadata) self.restore_first_link(gen, pathname, metadata) else: self.restore_first_link(gen, pathname, metadata) if set_metadata and self.write_ok: always = self.app.settings['always-restore-setuid'] try: obnamlib.set_metadata(self.fs, './' + pathname, metadata, always_set_id_bits=always) except obnamlib.SetMetadataError as e: self.app.ts.error(str(e)) self.errors = True except Exception, e: # Reaching this code path means we've hit a bug, so we log # a full traceback. msg = "Failed to restore %s:" % (pathname, ) logging.exception(msg) self.app.ts.error(msg + " " + str(e)) self.errors = True
def restore_safely(self, gen, pathname): try: dirname = os.path.dirname(pathname) if self.write_ok and not self.fs.exists('./' + dirname): self.fs.makedirs('./' + dirname) metadata = self.repo.get_metadata_from_file_keys(gen, pathname) set_metadata = True if metadata.isdir(): self.restore_dir(gen, pathname, metadata) elif metadata.islink(): self.restore_symlink(gen, pathname, metadata) elif metadata.st_nlink > 1: link = self.hardlinks.filename(metadata) if link: self.restore_hardlink(pathname, link, metadata) set_metadata = False else: self.hardlinks.add(pathname, metadata) self.restore_first_link(gen, pathname, metadata) else: self.restore_first_link(gen, pathname, metadata) if set_metadata and self.write_ok: always = self.app.settings['always-restore-setuid'] try: obnamlib.set_metadata( self.fs, './' + pathname, metadata, always_set_id_bits=always) except obnamlib.SetMetadataError as e: self.app.ts.error(str(e)) self.errors = True except Exception, e: # pylint: disable=broad-except # Reaching this code path means we've hit a bug, so we log # a full traceback. msg = "Failed to restore %s:" % (pathname,) logging.exception(msg) self.app.ts.error(msg + " " + str(e)) self.errors = True
def test_sets_symlink_target(self): self.fs.remove(self.filename) self.metadata.st_mode = 0777 | stat.S_IFLNK self.metadata.target = 'target' obnamlib.set_metadata(self.fs, self.filename, self.metadata) self.assertEqual(self.fs.readlink(self.filename), 'target')
def test_catches_lchown_throw(self): self.fs.lchown = self.oserror_lchown obnamlib.set_metadata(self.fs, self.filename, self.metadata) self.assert_(self.oserror_lchown_called) self.fs.lchown = self.fake_lchown
def test_sets_gid_when_running_as_root(self): obnamlib.set_metadata(self.fs, self.filename, self.metadata, getuid=lambda: 0) self.assertEqual(self.gid_set, self.metadata.st_gid)