mirror of https://github.com/python/cpython
gh-104773: PEP 594: Remove the spwd module (#104871)
Remove spwd from the configure script and Modules/Setup.
This commit is contained in:
parent
160321e530
commit
684e99d01d
|
@ -63,7 +63,3 @@ It defines the following items:
|
||||||
|
|
||||||
Module :mod:`pwd`
|
Module :mod:`pwd`
|
||||||
An interface to the user database, similar to this.
|
An interface to the user database, similar to this.
|
||||||
|
|
||||||
Module :mod:`spwd`
|
|
||||||
An interface to the shadow password database, similar to this.
|
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,7 @@ raised if the entry asked for cannot be found.
|
||||||
*pw_passwd* field only contains an asterisk (``'*'``) or the letter ``'x'``
|
*pw_passwd* field only contains an asterisk (``'*'``) or the letter ``'x'``
|
||||||
where the encrypted password is stored in a file :file:`/etc/shadow` which is
|
where the encrypted password is stored in a file :file:`/etc/shadow` which is
|
||||||
not world readable. Whether the *pw_passwd* field contains anything useful is
|
not world readable. Whether the *pw_passwd* field contains anything useful is
|
||||||
system-dependent. If available, the :mod:`spwd` module should be used where
|
system-dependent.
|
||||||
access to the encrypted password is required.
|
|
||||||
|
|
||||||
It defines the following items:
|
It defines the following items:
|
||||||
|
|
||||||
|
@ -72,7 +71,3 @@ It defines the following items:
|
||||||
|
|
||||||
Module :mod:`grp`
|
Module :mod:`grp`
|
||||||
An interface to the group database, similar to this.
|
An interface to the group database, similar to this.
|
||||||
|
|
||||||
Module :mod:`spwd`
|
|
||||||
An interface to the shadow password database, similar to this.
|
|
||||||
|
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
:mod:`spwd` --- The shadow password database
|
|
||||||
============================================
|
|
||||||
|
|
||||||
.. module:: spwd
|
|
||||||
:platform: Unix
|
|
||||||
:synopsis: The shadow password database (getspnam() and friends).
|
|
||||||
:deprecated:
|
|
||||||
|
|
||||||
.. deprecated-removed:: 3.11 3.13
|
|
||||||
The :mod:`spwd` module is deprecated
|
|
||||||
(see :pep:`PEP 594 <594#spwd>` for details and alternatives).
|
|
||||||
|
|
||||||
--------------
|
|
||||||
|
|
||||||
This module provides access to the Unix shadow password database. It is
|
|
||||||
available on various Unix versions.
|
|
||||||
|
|
||||||
.. include:: ../includes/wasm-notavail.rst
|
|
||||||
|
|
||||||
You must have enough privileges to access the shadow password database (this
|
|
||||||
usually means you have to be root).
|
|
||||||
|
|
||||||
Shadow password database entries are reported as a tuple-like object, whose
|
|
||||||
attributes correspond to the members of the ``spwd`` structure (Attribute field
|
|
||||||
below, see ``<shadow.h>``):
|
|
||||||
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| Index | Attribute | Meaning |
|
|
||||||
+=======+===============+=================================+
|
|
||||||
| 0 | ``sp_namp`` | Login name |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| 1 | ``sp_pwdp`` | Encrypted password |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| 2 | ``sp_lstchg`` | Date of last change |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| 3 | ``sp_min`` | Minimal number of days between |
|
|
||||||
| | | changes |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| 4 | ``sp_max`` | Maximum number of days between |
|
|
||||||
| | | changes |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| 5 | ``sp_warn`` | Number of days before password |
|
|
||||||
| | | expires to warn user about it |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| 6 | ``sp_inact`` | Number of days after password |
|
|
||||||
| | | expires until account is |
|
|
||||||
| | | disabled |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| 7 | ``sp_expire`` | Number of days since 1970-01-01 |
|
|
||||||
| | | when account expires |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
| 8 | ``sp_flag`` | Reserved |
|
|
||||||
+-------+---------------+---------------------------------+
|
|
||||||
|
|
||||||
The sp_namp and sp_pwdp items are strings, all others are integers.
|
|
||||||
:exc:`KeyError` is raised if the entry asked for cannot be found.
|
|
||||||
|
|
||||||
The following functions are defined:
|
|
||||||
|
|
||||||
|
|
||||||
.. function:: getspnam(name)
|
|
||||||
|
|
||||||
Return the shadow password database entry for the given user name.
|
|
||||||
|
|
||||||
.. versionchanged:: 3.6
|
|
||||||
Raises a :exc:`PermissionError` instead of :exc:`KeyError` if the user
|
|
||||||
doesn't have privileges.
|
|
||||||
|
|
||||||
.. function:: getspall()
|
|
||||||
|
|
||||||
Return a list of all available shadow password database entries, in arbitrary
|
|
||||||
order.
|
|
||||||
|
|
||||||
|
|
||||||
.. seealso::
|
|
||||||
|
|
||||||
Module :mod:`grp`
|
|
||||||
An interface to the group database, similar to this.
|
|
||||||
|
|
||||||
Module :mod:`pwd`
|
|
||||||
An interface to the normal password database, similar to this.
|
|
||||||
|
|
|
@ -19,6 +19,5 @@ backwards compatibility. They have been superseded by other modules.
|
||||||
nis.rst
|
nis.rst
|
||||||
nntplib.rst
|
nntplib.rst
|
||||||
optparse.rst
|
optparse.rst
|
||||||
spwd.rst
|
|
||||||
uu.rst
|
uu.rst
|
||||||
xdrlib.rst
|
xdrlib.rst
|
||||||
|
|
|
@ -1542,7 +1542,7 @@ complete list of changes, or look through the SVN logs for all the details.
|
||||||
:meth:`getproto` accessor methods to retrieve the family, type, and protocol
|
:meth:`getproto` accessor methods to retrieve the family, type, and protocol
|
||||||
values for the socket.
|
values for the socket.
|
||||||
|
|
||||||
* New module: the :mod:`spwd` module provides functions for accessing the shadow
|
* New module: the :mod:`!spwd` module provides functions for accessing the shadow
|
||||||
password database on systems that support shadow passwords.
|
password database on systems that support shadow passwords.
|
||||||
|
|
||||||
* The :mod:`struct` is now faster because it compiles format strings into
|
* The :mod:`struct` is now faster because it compiles format strings into
|
||||||
|
|
|
@ -1735,7 +1735,7 @@ Modules
|
||||||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||||
| :mod:`audioop` | :mod:`crypt` | :mod:`nis` | :mod:`!sndhdr` | :mod:`uu` |
|
| :mod:`audioop` | :mod:`crypt` | :mod:`nis` | :mod:`!sndhdr` | :mod:`uu` |
|
||||||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||||
| :mod:`!cgi` | :mod:`imghdr` | :mod:`nntplib` | :mod:`spwd` | :mod:`xdrlib` |
|
| :mod:`!cgi` | :mod:`imghdr` | :mod:`nntplib` | :mod:`!spwd` | :mod:`xdrlib` |
|
||||||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||||
| :mod:`!cgitb` | :mod:`!mailcap` | :mod:`!ossaudiodev` | :mod:`!sunau` | |
|
| :mod:`!cgitb` | :mod:`!mailcap` | :mod:`!ossaudiodev` | :mod:`!sunau` | |
|
||||||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||||
|
|
|
@ -900,7 +900,7 @@ Modules (see :pep:`594`):
|
||||||
* :mod:`!ossaudiodev`
|
* :mod:`!ossaudiodev`
|
||||||
* :mod:`!pipes`
|
* :mod:`!pipes`
|
||||||
* :mod:`!sndhdr`
|
* :mod:`!sndhdr`
|
||||||
* :mod:`spwd`
|
* :mod:`!spwd`
|
||||||
* :mod:`!sunau`
|
* :mod:`!sunau`
|
||||||
* :mod:`!telnetlib`
|
* :mod:`!telnetlib`
|
||||||
* :mod:`uu`
|
* :mod:`uu`
|
||||||
|
|
|
@ -168,6 +168,11 @@ Removed
|
||||||
The :mod:`mimetypes` module provides an alternative.
|
The :mod:`mimetypes` module provides an alternative.
|
||||||
(Contributed by Victor Stinner in :gh:`104773`.)
|
(Contributed by Victor Stinner in :gh:`104773`.)
|
||||||
|
|
||||||
|
* :pep:`594`: Remove the :mod:`!spwd` module, deprecated in Python 3.11:
|
||||||
|
the `python-pam project <https://pypi.org/project/python-pam/>`_ can be used
|
||||||
|
instead.
|
||||||
|
(Contributed by Victor Stinner in :gh:`104773`.)
|
||||||
|
|
||||||
|
|
||||||
Porting to Python 3.13
|
Porting to Python 3.13
|
||||||
======================
|
======================
|
||||||
|
|
|
@ -2211,7 +2211,7 @@ Changes in the Python API
|
||||||
the exception will stop a single-threaded server. (Contributed by
|
the exception will stop a single-threaded server. (Contributed by
|
||||||
Martin Panter in :issue:`23430`.)
|
Martin Panter in :issue:`23430`.)
|
||||||
|
|
||||||
* :func:`spwd.getspnam` now raises a :exc:`PermissionError` instead of
|
* :func:`!spwd.getspnam` now raises a :exc:`PermissionError` instead of
|
||||||
:exc:`KeyError` if the user doesn't have privileges.
|
:exc:`KeyError` if the user doesn't have privileges.
|
||||||
|
|
||||||
* The :meth:`socket.socket.close` method now raises an exception if
|
* The :meth:`socket.socket.close` method now raises an exception if
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
import os
|
|
||||||
import unittest
|
|
||||||
from test.support import import_helper
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
|
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.simplefilter("ignore", DeprecationWarning)
|
|
||||||
spwd = import_helper.import_module('spwd')
|
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0,
|
|
||||||
'root privileges required')
|
|
||||||
class TestSpwdRoot(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_getspall(self):
|
|
||||||
entries = spwd.getspall()
|
|
||||||
self.assertIsInstance(entries, list)
|
|
||||||
for entry in entries:
|
|
||||||
self.assertIsInstance(entry, spwd.struct_spwd)
|
|
||||||
|
|
||||||
def test_getspnam(self):
|
|
||||||
entries = spwd.getspall()
|
|
||||||
if not entries:
|
|
||||||
self.skipTest('empty shadow password database')
|
|
||||||
random_name = entries[0].sp_namp
|
|
||||||
entry = spwd.getspnam(random_name)
|
|
||||||
self.assertIsInstance(entry, spwd.struct_spwd)
|
|
||||||
self.assertEqual(entry.sp_namp, random_name)
|
|
||||||
self.assertEqual(entry.sp_namp, entry[0])
|
|
||||||
self.assertEqual(entry.sp_namp, entry.sp_nam)
|
|
||||||
self.assertIsInstance(entry.sp_pwdp, str)
|
|
||||||
self.assertEqual(entry.sp_pwdp, entry[1])
|
|
||||||
self.assertEqual(entry.sp_pwdp, entry.sp_pwd)
|
|
||||||
self.assertIsInstance(entry.sp_lstchg, int)
|
|
||||||
self.assertEqual(entry.sp_lstchg, entry[2])
|
|
||||||
self.assertIsInstance(entry.sp_min, int)
|
|
||||||
self.assertEqual(entry.sp_min, entry[3])
|
|
||||||
self.assertIsInstance(entry.sp_max, int)
|
|
||||||
self.assertEqual(entry.sp_max, entry[4])
|
|
||||||
self.assertIsInstance(entry.sp_warn, int)
|
|
||||||
self.assertEqual(entry.sp_warn, entry[5])
|
|
||||||
self.assertIsInstance(entry.sp_inact, int)
|
|
||||||
self.assertEqual(entry.sp_inact, entry[6])
|
|
||||||
self.assertIsInstance(entry.sp_expire, int)
|
|
||||||
self.assertEqual(entry.sp_expire, entry[7])
|
|
||||||
self.assertIsInstance(entry.sp_flag, int)
|
|
||||||
self.assertEqual(entry.sp_flag, entry[8])
|
|
||||||
with self.assertRaises(KeyError) as cx:
|
|
||||||
spwd.getspnam('invalid user name')
|
|
||||||
self.assertEqual(str(cx.exception), "'getspnam(): name not found'")
|
|
||||||
self.assertRaises(TypeError, spwd.getspnam)
|
|
||||||
self.assertRaises(TypeError, spwd.getspnam, 0)
|
|
||||||
self.assertRaises(TypeError, spwd.getspnam, random_name, 0)
|
|
||||||
try:
|
|
||||||
bytes_name = os.fsencode(random_name)
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.assertRaises(TypeError, spwd.getspnam, bytes_name)
|
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() != 0,
|
|
||||||
'non-root user required')
|
|
||||||
class TestSpwdNonRoot(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_getspnam_exception(self):
|
|
||||||
name = 'bin'
|
|
||||||
try:
|
|
||||||
with self.assertRaises(PermissionError) as cm:
|
|
||||||
spwd.getspnam(name)
|
|
||||||
except KeyError as exc:
|
|
||||||
self.skipTest("spwd entry %r doesn't exist: %s" % (name, exc))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
|
@ -1296,7 +1296,7 @@ Port _struct extension module to multiphase initialization (:pep:`489`)
|
||||||
.. nonce: 6F9o6L
|
.. nonce: 6F9o6L
|
||||||
.. section: C API
|
.. section: C API
|
||||||
|
|
||||||
Port :mod:`spwd` extension module to multiphase initialization (:pep:`489`)
|
Port :mod:`!spwd` extension module to multiphase initialization (:pep:`489`)
|
||||||
|
|
||||||
..
|
..
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
:pep:`594`: Remove the :mod:`!spwd` module, deprecated in Python 3.11: the
|
||||||
|
`python-pam project <https://pypi.org/project/python-pam/>`_ can be used
|
||||||
|
instead. Patch by Victor Stinner.
|
|
@ -185,7 +185,6 @@ PYTHONPATH=$(COREPYTHONPATH)
|
||||||
#fcntl fcntlmodule.c
|
#fcntl fcntlmodule.c
|
||||||
#grp grpmodule.c
|
#grp grpmodule.c
|
||||||
#resource resource.c
|
#resource resource.c
|
||||||
#spwd spwdmodule.c
|
|
||||||
#syslog syslogmodule.c
|
#syslog syslogmodule.c
|
||||||
#termios termios.c
|
#termios termios.c
|
||||||
|
|
||||||
|
|
|
@ -119,8 +119,6 @@
|
||||||
@MODULE_RESOURCE_TRUE@resource resource.c
|
@MODULE_RESOURCE_TRUE@resource resource.c
|
||||||
@MODULE_SELECT_TRUE@select selectmodule.c
|
@MODULE_SELECT_TRUE@select selectmodule.c
|
||||||
@MODULE__SOCKET_TRUE@_socket socketmodule.c
|
@MODULE__SOCKET_TRUE@_socket socketmodule.c
|
||||||
# AIX has shadow passwords, but does not provide getspent API
|
|
||||||
@MODULE_SPWD_TRUE@spwd spwdmodule.c
|
|
||||||
@MODULE_SYSLOG_TRUE@syslog syslogmodule.c
|
@MODULE_SYSLOG_TRUE@syslog syslogmodule.c
|
||||||
@MODULE_TERMIOS_TRUE@termios termios.c
|
@MODULE_TERMIOS_TRUE@termios termios.c
|
||||||
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*[clinic input]
|
|
||||||
preserve
|
|
||||||
[clinic start generated code]*/
|
|
||||||
|
|
||||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
|
||||||
# include "pycore_gc.h" // PyGC_Head
|
|
||||||
# include "pycore_runtime.h" // _Py_ID()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_GETSPNAM)
|
|
||||||
|
|
||||||
PyDoc_STRVAR(spwd_getspnam__doc__,
|
|
||||||
"getspnam($module, arg, /)\n"
|
|
||||||
"--\n"
|
|
||||||
"\n"
|
|
||||||
"Return the shadow password database entry for the given user name.\n"
|
|
||||||
"\n"
|
|
||||||
"See `help(spwd)` for more on shadow password database entries.");
|
|
||||||
|
|
||||||
#define SPWD_GETSPNAM_METHODDEF \
|
|
||||||
{"getspnam", (PyCFunction)spwd_getspnam, METH_O, spwd_getspnam__doc__},
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
spwd_getspnam_impl(PyObject *module, PyObject *arg);
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
spwd_getspnam(PyObject *module, PyObject *arg_)
|
|
||||||
{
|
|
||||||
PyObject *return_value = NULL;
|
|
||||||
PyObject *arg;
|
|
||||||
|
|
||||||
if (!PyUnicode_Check(arg_)) {
|
|
||||||
_PyArg_BadArgument("getspnam", "argument", "str", arg_);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (PyUnicode_READY(arg_) == -1) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
arg = arg_;
|
|
||||||
return_value = spwd_getspnam_impl(module, arg);
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(HAVE_GETSPNAM) */
|
|
||||||
|
|
||||||
#if defined(HAVE_GETSPENT)
|
|
||||||
|
|
||||||
PyDoc_STRVAR(spwd_getspall__doc__,
|
|
||||||
"getspall($module, /)\n"
|
|
||||||
"--\n"
|
|
||||||
"\n"
|
|
||||||
"Return a list of all available shadow password database entries, in arbitrary order.\n"
|
|
||||||
"\n"
|
|
||||||
"See `help(spwd)` for more on shadow password database entries.");
|
|
||||||
|
|
||||||
#define SPWD_GETSPALL_METHODDEF \
|
|
||||||
{"getspall", (PyCFunction)spwd_getspall, METH_NOARGS, spwd_getspall__doc__},
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
spwd_getspall_impl(PyObject *module);
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
spwd_getspall(PyObject *module, PyObject *Py_UNUSED(ignored))
|
|
||||||
{
|
|
||||||
return spwd_getspall_impl(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(HAVE_GETSPENT) */
|
|
||||||
|
|
||||||
#ifndef SPWD_GETSPNAM_METHODDEF
|
|
||||||
#define SPWD_GETSPNAM_METHODDEF
|
|
||||||
#endif /* !defined(SPWD_GETSPNAM_METHODDEF) */
|
|
||||||
|
|
||||||
#ifndef SPWD_GETSPALL_METHODDEF
|
|
||||||
#define SPWD_GETSPALL_METHODDEF
|
|
||||||
#endif /* !defined(SPWD_GETSPALL_METHODDEF) */
|
|
||||||
/*[clinic end generated code: output=dd61827a7b708e11 input=a9049054013a1b77]*/
|
|
|
@ -1,268 +0,0 @@
|
||||||
|
|
||||||
/* UNIX shadow password file access module */
|
|
||||||
/* A lot of code has been taken from pwdmodule.c */
|
|
||||||
/* For info also see http://www.unixpapa.com/incnote/passwd.html */
|
|
||||||
|
|
||||||
#include "Python.h"
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#ifdef HAVE_SHADOW_H
|
|
||||||
#include <shadow.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "clinic/spwdmodule.c.h"
|
|
||||||
|
|
||||||
/*[clinic input]
|
|
||||||
module spwd
|
|
||||||
[clinic start generated code]*/
|
|
||||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c0b841b90a6a07ce]*/
|
|
||||||
|
|
||||||
PyDoc_STRVAR(spwd__doc__,
|
|
||||||
"This module provides access to the Unix shadow password database.\n\
|
|
||||||
It is available on various Unix versions.\n\
|
|
||||||
\n\
|
|
||||||
Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\
|
|
||||||
containing the following items from the password database (see `<shadow.h>'):\n\
|
|
||||||
sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\
|
|
||||||
The sp_namp and sp_pwdp are strings, the rest are integers.\n\
|
|
||||||
An exception is raised if the entry asked for cannot be found.\n\
|
|
||||||
You have to be root to be able to use this module.");
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT)
|
|
||||||
|
|
||||||
static PyStructSequence_Field struct_spwd_type_fields[] = {
|
|
||||||
{"sp_namp", "login name"},
|
|
||||||
{"sp_pwdp", "encrypted password"},
|
|
||||||
{"sp_lstchg", "date of last change"},
|
|
||||||
{"sp_min", "min #days between changes"},
|
|
||||||
{"sp_max", "max #days between changes"},
|
|
||||||
{"sp_warn", "#days before pw expires to warn user about it"},
|
|
||||||
{"sp_inact", "#days after pw expires until account is disabled"},
|
|
||||||
{"sp_expire", "#days since 1970-01-01 when account expires"},
|
|
||||||
{"sp_flag", "reserved"},
|
|
||||||
{"sp_nam", "login name; deprecated"}, /* Backward compatibility */
|
|
||||||
{"sp_pwd", "encrypted password; deprecated"}, /* Backward compatibility */
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
PyDoc_STRVAR(struct_spwd__doc__,
|
|
||||||
"spwd.struct_spwd: Results from getsp*() routines.\n\n\
|
|
||||||
This object may be accessed either as a 9-tuple of\n\
|
|
||||||
(sp_namp,sp_pwdp,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\
|
|
||||||
or via the object attributes as named in the above tuple.");
|
|
||||||
|
|
||||||
static PyStructSequence_Desc struct_spwd_type_desc = {
|
|
||||||
"spwd.struct_spwd",
|
|
||||||
struct_spwd__doc__,
|
|
||||||
struct_spwd_type_fields,
|
|
||||||
9,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyTypeObject *StructSpwdType;
|
|
||||||
} spwdmodulestate;
|
|
||||||
|
|
||||||
static inline spwdmodulestate*
|
|
||||||
get_spwd_state(PyObject *module)
|
|
||||||
{
|
|
||||||
void *state = PyModule_GetState(module);
|
|
||||||
assert(state != NULL);
|
|
||||||
return (spwdmodulestate *)state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct PyModuleDef spwdmodule;
|
|
||||||
|
|
||||||
static void
|
|
||||||
sets(PyObject *v, int i, const char* val)
|
|
||||||
{
|
|
||||||
if (val) {
|
|
||||||
PyObject *o = PyUnicode_DecodeFSDefault(val);
|
|
||||||
PyStructSequence_SET_ITEM(v, i, o);
|
|
||||||
} else {
|
|
||||||
PyStructSequence_SET_ITEM(v, i, Py_None);
|
|
||||||
Py_INCREF(Py_None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *mkspent(PyObject *module, struct spwd *p)
|
|
||||||
{
|
|
||||||
int setIndex = 0;
|
|
||||||
PyObject *v = PyStructSequence_New(get_spwd_state(module)->StructSpwdType);
|
|
||||||
if (v == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
|
|
||||||
#define SETS(i,val) sets(v, i, val)
|
|
||||||
|
|
||||||
SETS(setIndex++, p->sp_namp);
|
|
||||||
SETS(setIndex++, p->sp_pwdp);
|
|
||||||
SETI(setIndex++, p->sp_lstchg);
|
|
||||||
SETI(setIndex++, p->sp_min);
|
|
||||||
SETI(setIndex++, p->sp_max);
|
|
||||||
SETI(setIndex++, p->sp_warn);
|
|
||||||
SETI(setIndex++, p->sp_inact);
|
|
||||||
SETI(setIndex++, p->sp_expire);
|
|
||||||
SETI(setIndex++, p->sp_flag);
|
|
||||||
SETS(setIndex++, p->sp_namp); /* Backward compatibility for sp_nam */
|
|
||||||
SETS(setIndex++, p->sp_pwdp); /* Backward compatibility for sp_pwd */
|
|
||||||
|
|
||||||
#undef SETS
|
|
||||||
#undef SETI
|
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
|
||||||
Py_DECREF(v);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_GETSPNAM || HAVE_GETSPENT */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_GETSPNAM
|
|
||||||
|
|
||||||
/*[clinic input]
|
|
||||||
spwd.getspnam
|
|
||||||
|
|
||||||
arg: unicode
|
|
||||||
/
|
|
||||||
|
|
||||||
Return the shadow password database entry for the given user name.
|
|
||||||
|
|
||||||
See `help(spwd)` for more on shadow password database entries.
|
|
||||||
[clinic start generated code]*/
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
spwd_getspnam_impl(PyObject *module, PyObject *arg)
|
|
||||||
/*[clinic end generated code: output=701250cf57dc6ebe input=dd89429e6167a00f]*/
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
struct spwd *p;
|
|
||||||
PyObject *bytes, *retval = NULL;
|
|
||||||
|
|
||||||
if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
|
|
||||||
return NULL;
|
|
||||||
/* check for embedded null bytes */
|
|
||||||
if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
|
|
||||||
goto out;
|
|
||||||
if ((p = getspnam(name)) == NULL) {
|
|
||||||
if (errno != 0)
|
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
|
||||||
else
|
|
||||||
PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
retval = mkspent(module, p);
|
|
||||||
out:
|
|
||||||
Py_DECREF(bytes);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_GETSPNAM */
|
|
||||||
|
|
||||||
#ifdef HAVE_GETSPENT
|
|
||||||
|
|
||||||
/*[clinic input]
|
|
||||||
spwd.getspall
|
|
||||||
|
|
||||||
Return a list of all available shadow password database entries, in arbitrary order.
|
|
||||||
|
|
||||||
See `help(spwd)` for more on shadow password database entries.
|
|
||||||
[clinic start generated code]*/
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
spwd_getspall_impl(PyObject *module)
|
|
||||||
/*[clinic end generated code: output=4fda298d6bf6d057 input=b2c84b7857d622bd]*/
|
|
||||||
{
|
|
||||||
PyObject *d;
|
|
||||||
struct spwd *p;
|
|
||||||
if ((d = PyList_New(0)) == NULL)
|
|
||||||
return NULL;
|
|
||||||
setspent();
|
|
||||||
while ((p = getspent()) != NULL) {
|
|
||||||
PyObject *v = mkspent(module, p);
|
|
||||||
if (v == NULL || PyList_Append(d, v) != 0) {
|
|
||||||
Py_XDECREF(v);
|
|
||||||
Py_DECREF(d);
|
|
||||||
endspent();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Py_DECREF(v);
|
|
||||||
}
|
|
||||||
endspent();
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_GETSPENT */
|
|
||||||
|
|
||||||
static PyMethodDef spwd_methods[] = {
|
|
||||||
#ifdef HAVE_GETSPNAM
|
|
||||||
SPWD_GETSPNAM_METHODDEF
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GETSPENT
|
|
||||||
SPWD_GETSPALL_METHODDEF
|
|
||||||
#endif
|
|
||||||
{NULL, NULL} /* sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
spwdmodule_exec(PyObject *module)
|
|
||||||
{
|
|
||||||
spwdmodulestate *state = get_spwd_state(module);
|
|
||||||
|
|
||||||
state->StructSpwdType = PyStructSequence_NewType(&struct_spwd_type_desc);
|
|
||||||
if (state->StructSpwdType == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (PyModule_AddType(module, state->StructSpwdType) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyModuleDef_Slot spwdmodule_slots[] = {
|
|
||||||
{Py_mod_exec, spwdmodule_exec},
|
|
||||||
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
|
|
||||||
{0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int spwdmodule_traverse(PyObject *m, visitproc visit, void *arg) {
|
|
||||||
Py_VISIT(get_spwd_state(m)->StructSpwdType);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int spwdmodule_clear(PyObject *m) {
|
|
||||||
Py_CLEAR(get_spwd_state(m)->StructSpwdType);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void spwdmodule_free(void *m) {
|
|
||||||
spwdmodule_clear((PyObject *)m);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct PyModuleDef spwdmodule = {
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
.m_name = "spwd",
|
|
||||||
.m_doc = spwd__doc__,
|
|
||||||
.m_size = sizeof(spwdmodulestate),
|
|
||||||
.m_methods = spwd_methods,
|
|
||||||
.m_slots = spwdmodule_slots,
|
|
||||||
.m_traverse = spwdmodule_traverse,
|
|
||||||
.m_clear = spwdmodule_clear,
|
|
||||||
.m_free = spwdmodule_free,
|
|
||||||
};
|
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
PyInit_spwd(void)
|
|
||||||
{
|
|
||||||
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
|
||||||
"'spwd' is deprecated and slated for removal in "
|
|
||||||
"Python 3.13",
|
|
||||||
7)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PyModuleDef_Init(&spwdmodule);
|
|
||||||
}
|
|
|
@ -235,7 +235,6 @@ static const char* _Py_stdlib_module_names[] = {
|
||||||
"smtplib",
|
"smtplib",
|
||||||
"socket",
|
"socket",
|
||||||
"socketserver",
|
"socketserver",
|
||||||
"spwd",
|
|
||||||
"sqlite3",
|
"sqlite3",
|
||||||
"sre_compile",
|
"sre_compile",
|
||||||
"sre_constants",
|
"sre_constants",
|
||||||
|
|
|
@ -716,8 +716,6 @@ MODULE_TERMIOS_FALSE
|
||||||
MODULE_TERMIOS_TRUE
|
MODULE_TERMIOS_TRUE
|
||||||
MODULE_SYSLOG_FALSE
|
MODULE_SYSLOG_FALSE
|
||||||
MODULE_SYSLOG_TRUE
|
MODULE_SYSLOG_TRUE
|
||||||
MODULE_SPWD_FALSE
|
|
||||||
MODULE_SPWD_TRUE
|
|
||||||
MODULE__SCPROXY_FALSE
|
MODULE__SCPROXY_FALSE
|
||||||
MODULE__SCPROXY_TRUE
|
MODULE__SCPROXY_TRUE
|
||||||
MODULE_RESOURCE_FALSE
|
MODULE_RESOURCE_FALSE
|
||||||
|
@ -25651,7 +25649,6 @@ case $ac_sys_system in #(
|
||||||
|
|
||||||
|
|
||||||
py_cv_module__scproxy=n/a
|
py_cv_module__scproxy=n/a
|
||||||
py_cv_module_spwd=n/a
|
|
||||||
;; #(
|
;; #(
|
||||||
VxWorks*) :
|
VxWorks*) :
|
||||||
|
|
||||||
|
@ -25660,11 +25657,6 @@ case $ac_sys_system in #(
|
||||||
py_cv_module__crypt=n/a
|
py_cv_module__crypt=n/a
|
||||||
py_cv_module_termios=n/a
|
py_cv_module_termios=n/a
|
||||||
py_cv_module_grp=n/a
|
py_cv_module_grp=n/a
|
||||||
;; #(
|
|
||||||
Darwin) :
|
|
||||||
|
|
||||||
|
|
||||||
py_cv_module_spwd=n/a
|
|
||||||
;; #(
|
;; #(
|
||||||
CYGWIN*) :
|
CYGWIN*) :
|
||||||
|
|
||||||
|
@ -25682,7 +25674,6 @@ case $ac_sys_system in #(
|
||||||
|
|
||||||
|
|
||||||
py_cv_module__scproxy=n/a
|
py_cv_module__scproxy=n/a
|
||||||
py_cv_module_spwd=n/a
|
|
||||||
;; #(
|
;; #(
|
||||||
Emscripten|WASI) :
|
Emscripten|WASI) :
|
||||||
|
|
||||||
|
@ -25703,7 +25694,6 @@ case $ac_sys_system in #(
|
||||||
py_cv_module_nis=n/a
|
py_cv_module_nis=n/a
|
||||||
py_cv_module_pwd=n/a
|
py_cv_module_pwd=n/a
|
||||||
py_cv_module_resource=n/a
|
py_cv_module_resource=n/a
|
||||||
py_cv_module_spwd=n/a
|
|
||||||
py_cv_module_syslog=n/a
|
py_cv_module_syslog=n/a
|
||||||
py_cv_module_=n/a
|
py_cv_module_=n/a
|
||||||
|
|
||||||
|
@ -26594,40 +26584,6 @@ fi
|
||||||
$as_echo "$py_cv_module__scproxy" >&6; }
|
$as_echo "$py_cv_module__scproxy" >&6; }
|
||||||
|
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module spwd" >&5
|
|
||||||
$as_echo_n "checking for stdlib extension module spwd... " >&6; }
|
|
||||||
if test "$py_cv_module_spwd" != "n/a"; then :
|
|
||||||
|
|
||||||
if true; then :
|
|
||||||
if test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes; then :
|
|
||||||
py_cv_module_spwd=yes
|
|
||||||
else
|
|
||||||
py_cv_module_spwd=missing
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
py_cv_module_spwd=disabled
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
as_fn_append MODULE_BLOCK "MODULE_SPWD_STATE=$py_cv_module_spwd$as_nl"
|
|
||||||
if test "x$py_cv_module_spwd" = xyes; then :
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fi
|
|
||||||
if test "$py_cv_module_spwd" = yes; then
|
|
||||||
MODULE_SPWD_TRUE=
|
|
||||||
MODULE_SPWD_FALSE='#'
|
|
||||||
else
|
|
||||||
MODULE_SPWD_TRUE='#'
|
|
||||||
MODULE_SPWD_FALSE=
|
|
||||||
fi
|
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_spwd" >&5
|
|
||||||
$as_echo "$py_cv_module_spwd" >&6; }
|
|
||||||
|
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module syslog" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module syslog" >&5
|
||||||
$as_echo_n "checking for stdlib extension module syslog... " >&6; }
|
$as_echo_n "checking for stdlib extension module syslog... " >&6; }
|
||||||
if test "$py_cv_module_syslog" != "n/a"; then :
|
if test "$py_cv_module_syslog" != "n/a"; then :
|
||||||
|
@ -28335,10 +28291,6 @@ if test -z "${MODULE__SCPROXY_TRUE}" && test -z "${MODULE__SCPROXY_FALSE}"; then
|
||||||
as_fn_error $? "conditional \"MODULE__SCPROXY\" was never defined.
|
as_fn_error $? "conditional \"MODULE__SCPROXY\" was never defined.
|
||||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
if test -z "${MODULE_SPWD_TRUE}" && test -z "${MODULE_SPWD_FALSE}"; then
|
|
||||||
as_fn_error $? "conditional \"MODULE_SPWD\" was never defined.
|
|
||||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
|
||||||
fi
|
|
||||||
if test -z "${MODULE_SYSLOG_TRUE}" && test -z "${MODULE_SYSLOG_FALSE}"; then
|
if test -z "${MODULE_SYSLOG_TRUE}" && test -z "${MODULE_SYSLOG_FALSE}"; then
|
||||||
as_fn_error $? "conditional \"MODULE_SYSLOG\" was never defined.
|
as_fn_error $? "conditional \"MODULE_SYSLOG\" was never defined.
|
||||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||||
|
|
|
@ -7082,15 +7082,13 @@ AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
|
||||||
|
|
||||||
# stdlib not available
|
# stdlib not available
|
||||||
dnl Modules that are not available on some platforms
|
dnl Modules that are not available on some platforms
|
||||||
dnl AIX has shadow passwords, but access is not via getspent()
|
|
||||||
dnl VxWorks does not provide crypt() function
|
dnl VxWorks does not provide crypt() function
|
||||||
AS_CASE([$ac_sys_system],
|
AS_CASE([$ac_sys_system],
|
||||||
[AIX], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])],
|
[AIX], [PY_STDLIB_MOD_SET_NA([_scproxy])],
|
||||||
[VxWorks*], [PY_STDLIB_MOD_SET_NA([_scproxy], [_crypt], [termios], [grp])],
|
[VxWorks*], [PY_STDLIB_MOD_SET_NA([_scproxy], [_crypt], [termios], [grp])],
|
||||||
[Darwin], [PY_STDLIB_MOD_SET_NA([spwd])],
|
|
||||||
[CYGWIN*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])],
|
[CYGWIN*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])],
|
||||||
[QNX*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])],
|
[QNX*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])],
|
||||||
[FreeBSD*], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])],
|
[FreeBSD*], [PY_STDLIB_MOD_SET_NA([_scproxy])],
|
||||||
[Emscripten|WASI], [
|
[Emscripten|WASI], [
|
||||||
dnl subprocess and multiprocessing are not supported (no fork syscall).
|
dnl subprocess and multiprocessing are not supported (no fork syscall).
|
||||||
dnl curses and tkinter user interface are not available.
|
dnl curses and tkinter user interface are not available.
|
||||||
|
@ -7113,7 +7111,6 @@ AS_CASE([$ac_sys_system],
|
||||||
[nis],
|
[nis],
|
||||||
[pwd],
|
[pwd],
|
||||||
[resource],
|
[resource],
|
||||||
[spwd],
|
|
||||||
[syslog],
|
[syslog],
|
||||||
)
|
)
|
||||||
AS_CASE([$ac_sys_system/$ac_sys_emscripten_target],
|
AS_CASE([$ac_sys_system/$ac_sys_emscripten_target],
|
||||||
|
@ -7264,7 +7261,6 @@ PY_STDLIB_MOD([resource], [], [test "$ac_cv_header_sys_resource_h" = yes])
|
||||||
PY_STDLIB_MOD([_scproxy],
|
PY_STDLIB_MOD([_scproxy],
|
||||||
[test "$ac_sys_system" = "Darwin"], [],
|
[test "$ac_sys_system" = "Darwin"], [],
|
||||||
[], [-framework SystemConfiguration -framework CoreFoundation])
|
[], [-framework SystemConfiguration -framework CoreFoundation])
|
||||||
PY_STDLIB_MOD([spwd], [], [test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes])
|
|
||||||
PY_STDLIB_MOD([syslog], [], [test "$ac_cv_header_syslog_h" = yes])
|
PY_STDLIB_MOD([syslog], [], [test "$ac_cv_header_syslog_h" = yes])
|
||||||
PY_STDLIB_MOD([termios], [], [test "$ac_cv_header_termios_h" = yes])
|
PY_STDLIB_MOD([termios], [], [test "$ac_cv_header_termios_h" = yes])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue