def testInit(self): """Construct an empty or seeded ShadowMap.""" self.assertEqual(shadow.ShadowMap, type(shadow.ShadowMap()), msg='failed to create emtpy ShadowMap') smap = shadow.ShadowMap([self._good_entry]) self.assertEqual(self._good_entry, smap.PopItem(), msg='failed to seed ShadowMap with list') self.assertRaises(TypeError, shadow.ShadowMap, ['string'])
def testVerifyFailure(self): # create a map m = shadow.ShadowMap() s = shadow.ShadowMapEntry() s.name = 'foo' self.assertTrue(m.Add(s)) updater = nssdb.NssDbShadowHandler({ 'dir': self.workdir, 'makedb': '/usr/bin/makedb' }) written = updater.Write(m) self.assertTrue(os.path.exists(updater.temp_cache_filename), 'updater.Write() did not create a file') # change the cache db = btopen(updater.temp_cache_filename) del db[db.first()[0]] db.sync() db.close() retval = updater.Verify(written) self.assertEqual(False, retval) self.assertFalse( os.path.exists(os.path.join(updater.temp_cache_filename)))
def testGetMap(self): shadow_map = shadow.ShadowMap() cache_info = StringIO.StringIO('''[ {"Key": "org/groups/foo/passwd", "Value": "Kg=="}, {"Key": "org/groups/foo/lstchg", "Value": "MTcyNDY="}, {"Key": "org/groups/foo/min", "Value": "MA=="}, {"Key": "org/groups/foo/max", "Value": "OTk5OTk="}, {"Key": "org/groups/foo/warn", "Value": "Nw=="} ]''') self.parser.GetMap(cache_info, shadow_map) self.assertEquals(self.good_entry, shadow_map.PopItem())
def testGetMap(self): shadow_map = shadow.ShadowMap() cache_info = StringIO.StringIO('''[ { "Key": "foo", "Value": { "passwd": "*", "lstchg": 17246, "min": 0, "max": 99999, "warn": 7 } } ]''') self.parser.GetMap(cache_info, shadow_map) self.assertEquals(self.good_entry, shadow_map.PopItem())
def testAdd(self): """Add throws an error for objects it can't verify.""" smap = shadow.ShadowMap() entry = self._good_entry self.assertTrue(smap.Add(entry), msg='failed to append new entry.') self.assertEqual(1, len(smap), msg='unexpected size for Map.') ret_entry = smap.PopItem() self.assertEqual(ret_entry, entry, msg='failed to pop existing entry.') pentry = passwd.PasswdMapEntry() pentry.name = 'foo' pentry.uid = 10 pentry.gid = 10 self.assertRaises(TypeError, smap.Add, pentry)
def testVerifyFailure(self): # Can't test if no makedb if not os.path.exists('/usr/bin/makedb'): raise TestSkipped('no /usr/bin/makedb') # Hide the warning that we expect to get class TestFilter(logging.Filter): def filter(self, record): return not record.msg.startswith( 'verify failed: %d keys missing') fltr = TestFilter() logging.getLogger('NssDbShadowHandler').addFilter(fltr) # create a map m = shadow.ShadowMap() s = shadow.ShadowMapEntry() s.name = 'foo' self.failUnless(m.Add(s)) updater = nssdb.NssDbShadowHandler({ 'dir': self.workdir, 'makedb': '/usr/bin/makedb' }) written = updater.Write(m) self.failUnless(os.path.exists(updater.temp_cache_filename), 'updater.Write() did not create a file') # change the cache db = bsddb.btopen(updater.temp_cache_filename) del db[db.first()[0]] db.sync() db.close() retval = updater.Verify(written) self.failUnlessEqual(False, retval) self.failIf(os.path.exists(os.path.join(updater.temp_cache_filename))) # no longer hide this message logging.getLogger('NssDbShadowHandler').removeFilter(fltr)
def testVerify(self): m = shadow.ShadowMap() s = shadow.ShadowMapEntry() s.name = 'foo' self.failUnless(m.Add(s)) updater = nssdb.NssDbShadowHandler({ 'dir': self.workdir, 'makedb': '/usr/bin/makedb' }) written = updater.Write(m) self.failUnless(os.path.exists(updater.temp_cache_filename), 'updater.Write() did not create a file') retval = updater.Verify(written) self.failUnlessEqual(True, retval) os.unlink(updater.temp_cache_filename)
def testNssDbShadowHandlerWrite(self): ent = 'foo:*:::::::0' makedb_stdin = self.mox.CreateMock(sys.stdin) makedb_stdin.write('.foo %s\n' % ent) makedb_stdin.write('00 %s\n' % ent) makedb_stdin.close() makedb_stdout = self.mox.CreateMock(sys.stdout) makedb_stdout.read().AndReturn('') makedb_stdout.close() m = shadow.ShadowMap() s = shadow.ShadowMapEntry() s.name = 'foo' s.passwd = '*' s.Verify() self.failUnless(m.Add(s)) self.mox.StubOutWithMock(select, 'select') select.select([makedb_stdout], (), (), 0).AndReturn(([37], [], [])) select.select([makedb_stdout], (), (), 0).AndReturn(([], [], [])) def SpawnMakeDb(): makedb = MakeDbDummy() makedb.stdin = makedb_stdin makedb.stdout = makedb_stdout return makedb writer = nssdb.NssDbShadowHandler({ 'makedb': '/usr/bin/makedb', 'dir': self.workdir }) writer._SpawnMakeDb = SpawnMakeDb self.mox.ReplayAll() writer.Write(m) tmpshadow = os.path.join(self.workdir, 'shadow.db') self.failIf(os.path.exists(tmpshadow)) # just clean it up, Write() doesn't Commit() writer._Rollback()
def testNssDbShadowHandlerWriteData(self): ent = 'foo:!!:::::::0' makedb_stdin = self.mox.CreateMock(sys.stdin) makedb_stdin.write('.foo %s\n' % ent) makedb_stdin.write('00 %s\n' % ent) m = shadow.ShadowMap() s = shadow.ShadowMapEntry() s.name = 'foo' self.failUnless(m.Add(s)) writer = nssdb.NssDbShadowHandler({ 'makedb': '/bin/false', 'dir': '/tmp' }) self.mox.ReplayAll() writer.WriteData(makedb_stdin, s, 0)
def testNssDbShadowHandlerWriteData(self): ent = 'foo:!!:::::::0' makedb_stdin = self.mox.CreateMock(io.BytesIO) makedb_stdin.write(('.foo %s\n' % ent).encode('ascii')) makedb_stdin.write(('00 %s\n' % ent).encode('ascii')) m = shadow.ShadowMap() s = shadow.ShadowMapEntry() s.name = 'foo' self.assertTrue(m.Add(s)) writer = nssdb.NssDbShadowHandler({ 'makedb': '/bin/false', 'dir': '/tmp' }) self.mox.ReplayAll() writer.WriteData(makedb_stdin, s, 0)
def GetShadowMap(): """Returns a ShadowMap built from nss calls.""" getent = _SpawnGetent(config.MAP_SHADOW) (getent_stdout, getent_stderr) = getent.communicate() # The following is going to be map-specific each time, so no point in # making more methods. shadow_map = shadow.ShadowMap() for line in getent_stdout.split(): line = line.decode('utf-8') nss_entry = line.strip().split(':') map_entry = shadow.ShadowMapEntry() map_entry.name = nss_entry[0] map_entry.passwd = nss_entry[1] if nss_entry[2] != '': map_entry.lstchg = int(nss_entry[2]) if nss_entry[3] != '': map_entry.min = int(nss_entry[3]) if nss_entry[4] != '': map_entry.max = int(nss_entry[4]) if nss_entry[5] != '': map_entry.warn = int(nss_entry[5]) if nss_entry[6] != '': map_entry.inact = int(nss_entry[6]) if nss_entry[7] != '': map_entry.expire = int(nss_entry[7]) if nss_entry[8] != '': map_entry.flag = int(nss_entry[8]) shadow_map.Add(map_entry) if getent_stderr: logging.debug('captured error %s', getent_stderr) retval = getent.returncode if retval != 0: logging.warning('%s returned error code: %d', GETENT, retval) return shadow_map
def __init__(self, conf, map_name, automount_mountpoint=None): """Initialise the Cache object. Args: conf: A dictionary of key/value pairs map_name: A string representation of the map type automount_mountpoint: A string containing the automount mountpoint, used only by automount maps. Raises: UnsupportedMap: for map types we don't know about """ super(Cache, self).__init__() # Set up a logger for our children self.log = logging.getLogger(self.__class__.__name__) # Store config info self.conf = conf self.output_dir = conf.get('dir', '.') self.automount_mountpoint = automount_mountpoint self.map_name = map_name # Setup the map we may be asked to load our cache into. if map_name == config.MAP_PASSWORD: self.data = passwd.PasswdMap() elif map_name == config.MAP_SSHKEY: self.data = sshkey.SshkeyMap() elif map_name == config.MAP_GROUP: self.data = group.GroupMap() elif map_name == config.MAP_SHADOW: self.data = shadow.ShadowMap() elif map_name == config.MAP_NETGROUP: self.data = netgroup.NetgroupMap() elif map_name == config.MAP_AUTOMOUNT: self.data = automount.AutomountMap() else: raise error.UnsupportedMap('Cache does not support %s' % map_name)
def CreateMap(self): """Return a ShadowMap instance.""" return shadow.ShadowMap()
def CreateMap(self): """Returns a new ShadowMap instance to have ShadowMapEntries added to it.""" return shadow.ShadowMap()