mirror of
https://github.com/python/cpython
synced 2024-09-05 08:17:45 +00:00
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`
|
||||
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'``
|
||||
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
|
||||
system-dependent. If available, the :mod:`spwd` module should be used where
|
||||
access to the encrypted password is required.
|
||||
system-dependent.
|
||||
|
||||
It defines the following items:
|
||||
|
||||
|
@ -72,7 +71,3 @@ It defines the following items:
|
|||
|
||||
Module :mod:`grp`
|
||||
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
|
||||
nntplib.rst
|
||||
optparse.rst
|
||||
spwd.rst
|
||||
uu.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
|
||||
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.
|
||||
|
||||
* 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:`!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` | |
|
||||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||
|
|
|
@ -900,7 +900,7 @@ Modules (see :pep:`594`):
|
|||
* :mod:`!ossaudiodev`
|
||||
* :mod:`!pipes`
|
||||
* :mod:`!sndhdr`
|
||||
* :mod:`spwd`
|
||||
* :mod:`!spwd`
|
||||
* :mod:`!sunau`
|
||||
* :mod:`!telnetlib`
|
||||
* :mod:`uu`
|
||||
|
|
|
@ -168,6 +168,11 @@ Removed
|
|||
The :mod:`mimetypes` module provides an alternative.
|
||||
(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
|
||||
======================
|
||||
|
|
|
@ -2211,7 +2211,7 @@ Changes in the Python API
|
|||
the exception will stop a single-threaded server. (Contributed by
|
||||
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.
|
||||
|
||||
* 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
|
||||
.. 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
|
||||
#grp grpmodule.c
|
||||
#resource resource.c
|
||||
#spwd spwdmodule.c
|
||||
#syslog syslogmodule.c
|
||||
#termios termios.c
|
||||
|
||||
|
|
|
@ -119,8 +119,6 @@
|
|||
@MODULE_RESOURCE_TRUE@resource resource.c
|
||||
@MODULE_SELECT_TRUE@select selectmodule.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_TERMIOS_TRUE@termios termios.c
|
||||
|
||||
|
|
80
Modules/clinic/spwdmodule.c.h
generated
80
Modules/clinic/spwdmodule.c.h
generated
|
@ -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);
|
||||
}
|
1
Python/stdlib_module_names.h
generated
1
Python/stdlib_module_names.h
generated
|
@ -235,7 +235,6 @@ static const char* _Py_stdlib_module_names[] = {
|
|||
"smtplib",
|
||||
"socket",
|
||||
"socketserver",
|
||||
"spwd",
|
||||
"sqlite3",
|
||||
"sre_compile",
|
||||
"sre_constants",
|
||||
|
|
48
configure
generated
vendored
48
configure
generated
vendored
|
@ -716,8 +716,6 @@ MODULE_TERMIOS_FALSE
|
|||
MODULE_TERMIOS_TRUE
|
||||
MODULE_SYSLOG_FALSE
|
||||
MODULE_SYSLOG_TRUE
|
||||
MODULE_SPWD_FALSE
|
||||
MODULE_SPWD_TRUE
|
||||
MODULE__SCPROXY_FALSE
|
||||
MODULE__SCPROXY_TRUE
|
||||
MODULE_RESOURCE_FALSE
|
||||
|
@ -25651,7 +25649,6 @@ case $ac_sys_system in #(
|
|||
|
||||
|
||||
py_cv_module__scproxy=n/a
|
||||
py_cv_module_spwd=n/a
|
||||
;; #(
|
||||
VxWorks*) :
|
||||
|
||||
|
@ -25660,11 +25657,6 @@ case $ac_sys_system in #(
|
|||
py_cv_module__crypt=n/a
|
||||
py_cv_module_termios=n/a
|
||||
py_cv_module_grp=n/a
|
||||
;; #(
|
||||
Darwin) :
|
||||
|
||||
|
||||
py_cv_module_spwd=n/a
|
||||
;; #(
|
||||
CYGWIN*) :
|
||||
|
||||
|
@ -25682,7 +25674,6 @@ case $ac_sys_system in #(
|
|||
|
||||
|
||||
py_cv_module__scproxy=n/a
|
||||
py_cv_module_spwd=n/a
|
||||
;; #(
|
||||
Emscripten|WASI) :
|
||||
|
||||
|
@ -25703,7 +25694,6 @@ case $ac_sys_system in #(
|
|||
py_cv_module_nis=n/a
|
||||
py_cv_module_pwd=n/a
|
||||
py_cv_module_resource=n/a
|
||||
py_cv_module_spwd=n/a
|
||||
py_cv_module_syslog=n/a
|
||||
py_cv_module_=n/a
|
||||
|
||||
|
@ -26594,40 +26584,6 @@ fi
|
|||
$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_n "checking for stdlib extension module syslog... " >&6; }
|
||||
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.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
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
|
||||
as_fn_error $? "conditional \"MODULE_SYSLOG\" was never defined.
|
||||
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
|
||||
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
|
||||
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])],
|
||||
[Darwin], [PY_STDLIB_MOD_SET_NA([spwd])],
|
||||
[CYGWIN*], [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], [
|
||||
dnl subprocess and multiprocessing are not supported (no fork syscall).
|
||||
dnl curses and tkinter user interface are not available.
|
||||
|
@ -7113,7 +7111,6 @@ AS_CASE([$ac_sys_system],
|
|||
[nis],
|
||||
[pwd],
|
||||
[resource],
|
||||
[spwd],
|
||||
[syslog],
|
||||
)
|
||||
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],
|
||||
[test "$ac_sys_system" = "Darwin"], [],
|
||||
[], [-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([termios], [], [test "$ac_cv_header_termios_h" = yes])
|
||||
|
||||
|
|
Loading…
Reference in a new issue