Esempio n. 1
0
 def testInit(self):
     """Construct empty and seeded ShadowMapEntry."""
     self.assertTrue(shadow.ShadowMapEntry(),
                     msg='Could not create empty ShadowMapEntry')
     seed = {'name': 'foo'}
     entry = shadow.ShadowMapEntry(seed)
     self.assertTrue(entry.Verify(),
                     msg='Could not verify seeded ShadowMapEntry')
     self.assertEqual(entry.name,
                      'foo',
                      msg='Entry returned wrong value for name')
     self.assertEqual(entry.passwd,
                      '!!',
                      msg='Entry returned wrong value for passwd')
     self.assertEqual(entry.lstchg,
                      None,
                      msg='Entry returned wrong value for lstchg')
     self.assertEqual(entry.min,
                      None,
                      msg='Entry returned wrong value for min')
     self.assertEqual(entry.max,
                      None,
                      msg='Entry returned wrong value for max')
     self.assertEqual(entry.warn,
                      None,
                      msg='Entry returned wrong value for warn')
     self.assertEqual(entry.inact,
                      None,
                      msg='Entry returned wrong value for inact')
     self.assertEqual(entry.expire,
                      None,
                      msg='Entry returned wrong value for expire')
     self.assertEqual(entry.flag,
                      None,
                      msg='Entry returned wrong value for flag')
Esempio n. 2
0
    def testGetShadowMap(self):
        """Verify we build a correct shadow map from nss calls."""
        line1 = 'foo:!!::::::::'
        line2 = 'bar:!!::::::::'
        lines = [line1, line2]

        mock_getent = self.mox.CreateMockAnything()
        mock_getent.communicate().AndReturn(['\n'.join(lines), ''])
        mock_getent.returncode = 0

        entry1 = shadow.ShadowMapEntry()
        entry1.name = 'foo'
        entry2 = shadow.ShadowMapEntry()
        entry2.name = 'bar'

        self.mox.StubOutWithMock(nss, '_SpawnGetent')
        nss._SpawnGetent(config.MAP_SHADOW).AndReturn(mock_getent)

        self.mox.ReplayAll()

        shadow_map = nss.GetShadowMap()

        self.assertTrue(isinstance(shadow_map, shadow.ShadowMap))
        self.assertEquals(len(shadow_map), 2)
        self.assertTrue(shadow_map.Exists(entry1))
        self.assertTrue(shadow_map.Exists(entry2))
Esempio n. 3
0
 def testAttributes(self):
     """Test that we can get and set all expected attributes."""
     entry = shadow.ShadowMapEntry()
     entry.name = 'foo'
     self.assertEqual(entry.name,
                      'foo',
                      msg='Could not set attribute: name')
     entry.passwd = 'seekret'
     self.assertEqual(entry.passwd,
                      'seekret',
                      msg='Could not set attribute: passwd')
     entry.lstchg = 0
     self.assertEqual(entry.lstchg,
                      0,
                      msg='Could not set attribute: lstchg')
     entry.min = 0
     self.assertEqual(entry.min, 0, msg='Could not set attribute: min')
     entry.max = 0
     self.assertEqual(entry.max, 0, msg='Could not set attribute: max')
     entry.warn = 0
     self.assertEqual(entry.warn, 0, msg='Could not set attribute: warn')
     entry.inact = 0
     self.assertEqual(entry.inact, 0, msg='Could not set attribute: inact')
     entry.expire = 0
     self.assertEqual(entry.expire,
                      0,
                      msg='Could not set attribute: expire')
     entry.flag = 0
     self.assertEqual(entry.flag, 0, msg='Could not set attribute: flag')
Esempio n. 4
0
 def Transform(self, obj):
   """Transforms an LDAP shadowAccont object into a shadow(5) entry."""
   shadow_ent = shadow.ShadowMapEntry()
   shadow_ent.name = obj['uid'][0]
   # TODO(jaq): does nss_ldap check the contents of the userPassword
   # attribute?
   shadow_ent.passwd = '*'
   if 'shadowLastChange' in obj:
     shadow_ent.lstchg = int(obj['shadowLastChange'][0])
   if 'shadowMin' in obj:
     shadow_ent.min = int(obj['shadowMin'][0])
   if 'shadowMax' in obj:
     shadow_ent.max = int(obj['shadowMax'][0])
   if 'shadowWarning' in obj:
     shadow_ent.warn = int(obj['shadowWarning'][0])
   if 'shadowInactive' in obj:
     shadow_ent.inact = int(obj['shadowInactive'][0])
   if 'shadowExpire' in obj:
     shadow_ent.expire = int(obj['shadowExpire'][0])
   if 'shadowFlag' in obj:
     shadow_ent.flag = int(obj['shadowFlag'][0])
   if shadow_ent.flag is None:
     shadow_ent.flag = 0
   if 'userPassword' in obj:
     passwd = obj['userPassword'][0]
     if passwd[:7].lower() == '{crypt}':
       shadow_ent.passwd = passwd[7:]
     else:
       logging.info('Ignored password that was not in crypt format')
   return shadow_ent
Esempio n. 5
0
    def ConvertValueToMapEntry(self, entry):
        """Convert a grent-like string into a ShadowMapEntry.

        Args:
          entry: A string containing a grent entry ala /etc/shadow

        Returns:
          A ShadowMapEntry instance
        """
        if isinstance(entry, bytes):
            entry = entry.decode('ascii')
        elif entry.endswith('\x00'):
            entry = entry[:-1]

        entry = entry.split(':')
        map_entry = shadow.ShadowMapEntry()
        # map entries expect strict typing, so convert as appropriate
        map_entry.name = entry[0]
        map_entry.passwd = entry[1]
        if entry[2]:
            map_entry.lstchg = int(entry[2])
        if entry[3]:
            map_entry.min = int(entry[3])
        if entry[4]:
            map_entry.max = int(entry[4])
        if entry[5]:
            map_entry.warn = int(entry[5])
        if entry[6]:
            map_entry.inact = int(entry[6])
        if entry[7]:
            map_entry.expire = int(entry[7])
        if entry[8]:
            map_entry.flag = int(entry[8])
        return map_entry
Esempio n. 6
0
    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)))
Esempio n. 7
0
 def setUp(self):
     self.good_entry = shadow.ShadowMapEntry()
     self.good_entry.name = 'foo'
     self.good_entry.passwd = '*'
     self.good_entry.lstchg = 17246
     self.good_entry.min = 0
     self.good_entry.max = 99999
     self.good_entry.warn = 7
     self.parser = s3source.S3ShadowMapParser()
Esempio n. 8
0
 def __init__(self, obj):
     """Set some default avalible data for testing."""
     super(TestShadowMap, self).__init__(obj)
     self._good_entry = shadow.ShadowMapEntry()
     self._good_entry.name = 'foo'
     self._good_entry.lstchg = None
     self._good_entry.min = None
     self._good_entry.max = None
     self._good_entry.warn = None
     self._good_entry.inact = None
     self._good_entry.expire = None
     self._good_entry.flag = None
Esempio n. 9
0
    def testWriteShadowEntry(self):
        """We correctly write a typical entry in /etc/shadow format."""
        cache = files.FilesShadowMapHandler(self.config)
        file_mock = self.mox.CreateMock(sys.stdout)
        file_mock.write('root:$1$zomgmd5support:::::::\n')

        map_entry = shadow.ShadowMapEntry()
        map_entry.name = 'root'
        map_entry.passwd = '$1$zomgmd5support'

        self.mox.ReplayAll()

        cache._WriteData(file_mock, map_entry)
Esempio n. 10
0
    def Transform(self, obj):
        """Transforms an LDAP shadowAccont object into a shadow(5) entry."""

        shadow_ent = shadow.ShadowMapEntry()

        if self.conf.get('ad'):
            shadow_ent.name = obj['sAMAccountName'][0]
        elif 'uidattr' in self.conf:
            shadow_ent.name = obj[self.conf['uidattr']][0]
        else:
            shadow_ent.name = obj['uid'][0]

        if hasattr(self, 'uidregex'):
            shadow_ent.name = ''.join(
                [x for x in self.uidregex.findall(shadow_end.name)])

        # TODO(jaq): does nss_ldap check the contents of the userPassword
        # attribute?
        shadow_ent.passwd = '*'
        if self.conf.get('ad'):
            # Time attributes of AD objects use interval date/time format with a value
            # that represents the number of 100-nanosecond intervals since January 1, 1601.
            # We need to calculate the difference between 1970-01-01 and 1601-01-01 in seconds wich is 11644473600
            # then abstract it from the pwdLastChange value in seconds, then devide it by 86400 to get the
            # days since Jan 1, 1970 the password wa changed.
            shadow_ent.lstchg = int(
                (int(obj['pwdLastSet'][0]) / 10000000 - 11644473600) / 86400)
        elif 'shadowLastChange' in obj:
            shadow_ent.lstchg = int(obj['shadowLastChange'][0])
        if 'shadowMin' in obj:
            shadow_ent.min = int(obj['shadowMin'][0])
        if 'shadowMax' in obj:
            shadow_ent.max = int(obj['shadowMax'][0])
        if 'shadowWarning' in obj:
            shadow_ent.warn = int(obj['shadowWarning'][0])
        if 'shadowInactive' in obj:
            shadow_ent.inact = int(obj['shadowInactive'][0])
        if 'shadowExpire' in obj:
            shadow_ent.expire = int(obj['shadowExpire'][0])
        if 'shadowFlag' in obj:
            shadow_ent.flag = int(obj['shadowFlag'][0])
        if shadow_ent.flag is None:
            shadow_ent.flag = 0
        if 'userPassword' in obj:
            passwd = obj['userPassword'][0]
            if passwd[:7].lower() == '{crypt}':
                shadow_ent.passwd = passwd[7:]
            else:
                logging.info('Ignored password that was not in crypt format')
        return shadow_ent
Esempio n. 11
0
    def _ReadEntry(self, name, entry):
        """Return a ShadowMapEntry from a record in the target cache."""

        map_entry = shadow.ShadowMapEntry()
        # maps expect strict typing, so convert to int as appropriate.
        map_entry.name = name
        map_entry.passwd = entry.get('passwd', '*')

        for attr in ['lstchg', 'min', 'max', 'warn', 'inact', 'expire']:
            try:
                setattr(map_entry, attr, int(entry[attr]))
            except (ValueError, KeyError):
                continue

        return map_entry
Esempio n. 12
0
    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)
Esempio n. 13
0
    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)
Esempio n. 14
0
    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()
Esempio n. 15
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)
Esempio n. 16
0
    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)
Esempio n. 17
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
Esempio n. 18
0
 def _ReadEntry(self, line):
     """Return a ShadowMapEntry from a record in the target cache."""
     line = line.split(':')
     map_entry = shadow.ShadowMapEntry()
     # map entries expect strict typing, so convert as appropriate
     map_entry.name = line[0]
     map_entry.passwd = line[1]
     if line[2]:
         map_entry.lstchg = int(line[2])
     if line[3]:
         map_entry.min = int(line[3])
     if line[4]:
         map_entry.max = int(line[4])
     if line[5]:
         map_entry.warn = int(line[5])
     if line[6]:
         map_entry.inact = int(line[6])
     if line[7]:
         map_entry.expire = int(line[7])
     if line[8]:
         map_entry.flag = int(line[8])
     return map_entry
Esempio n. 19
0
 def testKey(self):
     """Key() should return the value of the 'name' attribute."""
     entry = shadow.ShadowMapEntry()
     entry.name = 'foo'
     self.assertEqual(entry.Key(), entry.name)
Esempio n. 20
0
    def testVerify(self):
        """Test that the object can verify it's attributes and itself."""
        entry = shadow.ShadowMapEntry()

        # Emtpy object should bomb
        self.assertFalse(entry.Verify())