17df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchakaimport os
27df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchakaimport unittest
37df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchakafrom test import support
47df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka
57df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchakaspwd = support.import_module('spwd')
67df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka
77df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka
87df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0,
97df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka                     'root privileges required')
107df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchakaclass TestSpwdRoot(unittest.TestCase):
117df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka
127df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka    def test_getspall(self):
137df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        entries = spwd.getspall()
147df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entries, list)
157df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        for entry in entries:
167df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka            self.assertIsInstance(entry, spwd.struct_spwd)
177df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka
187df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka    def test_getspnam(self):
197df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        entries = spwd.getspall()
207df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        if not entries:
217df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka            self.skipTest('empty shadow password database')
227df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        random_name = entries[0].sp_namp
237df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        entry = spwd.getspnam(random_name)
247df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry, spwd.struct_spwd)
257df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_namp, random_name)
267df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_namp, entry[0])
277df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_namp, entry.sp_nam)
287df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry.sp_pwdp, str)
297df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_pwdp, entry[1])
307df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_pwdp, entry.sp_pwd)
317df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry.sp_lstchg, int)
327df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_lstchg, entry[2])
337df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry.sp_min, int)
347df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_min, entry[3])
357df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry.sp_max, int)
367df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_max, entry[4])
377df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry.sp_warn, int)
387df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_warn, entry[5])
397df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry.sp_inact, int)
407df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_inact, entry[6])
417df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry.sp_expire, int)
427df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_expire, entry[7])
437df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertIsInstance(entry.sp_flag, int)
447df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(entry.sp_flag, entry[8])
457df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        with self.assertRaises(KeyError) as cx:
467df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka            spwd.getspnam('invalid user name')
477df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertEqual(str(cx.exception), "'getspnam(): name not found'")
487df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertRaises(TypeError, spwd.getspnam)
497df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertRaises(TypeError, spwd.getspnam, 0)
507df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        self.assertRaises(TypeError, spwd.getspnam, random_name, 0)
517df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        try:
527df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka            bytes_name = os.fsencode(random_name)
537df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        except UnicodeEncodeError:
547df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka            pass
557df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka        else:
567df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka            self.assertRaises(TypeError, spwd.getspnam, bytes_name)
577df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka
587df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka
593c3d7f4b99b1f62567592ef57216e07677f17d7fBerker Peksag@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() != 0,
603c3d7f4b99b1f62567592ef57216e07677f17d7fBerker Peksag                     'non-root user required')
613c3d7f4b99b1f62567592ef57216e07677f17d7fBerker Peksagclass TestSpwdNonRoot(unittest.TestCase):
623c3d7f4b99b1f62567592ef57216e07677f17d7fBerker Peksag
633c3d7f4b99b1f62567592ef57216e07677f17d7fBerker Peksag    def test_getspnam_exception(self):
640069aef51a176ec90fb93f4601636e8763e07c42Victor Stinner        name = 'bin'
650069aef51a176ec90fb93f4601636e8763e07c42Victor Stinner        try:
660069aef51a176ec90fb93f4601636e8763e07c42Victor Stinner            with self.assertRaises(PermissionError) as cm:
670069aef51a176ec90fb93f4601636e8763e07c42Victor Stinner                spwd.getspnam(name)
680069aef51a176ec90fb93f4601636e8763e07c42Victor Stinner        except KeyError as exc:
690069aef51a176ec90fb93f4601636e8763e07c42Victor Stinner            self.skipTest("spwd entry %r doesn't exist: %s" % (name, exc))
700069aef51a176ec90fb93f4601636e8763e07c42Victor Stinner        else:
710069aef51a176ec90fb93f4601636e8763e07c42Victor Stinner            self.assertEqual(str(cm.exception), '[Errno 13] Permission denied')
723c3d7f4b99b1f62567592ef57216e07677f17d7fBerker Peksag
733c3d7f4b99b1f62567592ef57216e07677f17d7fBerker Peksag
747df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchakaif __name__ == "__main__":
757df417d50a6c849987d745453fcf6d0786d41ca4Serhiy Storchaka    unittest.main()
76