Patch #579435: Shadow Password Support Module

This commit is contained in:
Martin v. Löwis 2005-01-23 09:27:24 +00:00
parent 4d394dfebb
commit c300175547
11 changed files with 466 additions and 429 deletions

View File

@ -164,6 +164,7 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
lib/libposix.tex \
lib/libposixpath.tex \
lib/libpwd.tex \
lib/libspwd.tex \
lib/libgrp.tex \
lib/libcrypt.tex \
lib/libdbm.tex \

View File

@ -193,6 +193,7 @@ and how to embed it in other applications.
\input{libunix} % UNIX Specific Services
\input{libposix}
\input{libpwd}
\input{libspwd}
\input{libgrp}
\input{libcrypt}
\input{libdl}

View File

@ -50,4 +50,5 @@ Return a list of all available password database entries, in arbitrary order.
\begin{seealso}
\seemodule{grp}{An interface to the group database, similar to this.}
\seemodule{spwd}{An interface to the shadow password database, similar to this.}
\end{seealso}

46
Doc/lib/libspwd.tex Normal file
View File

@ -0,0 +1,46 @@
\section{\module{spwd} ---
The shadow password database}
\declaremodule{builtin}{spwd}
\platform{Unix}
\modulesynopsis{The shadow password database (\function{getspnam()} and friends).}
This module provides access to the \UNIX{} shadow password database.
It is available on various Unix versions.
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 \code{spwd} structure
(Attribute field below, see \code{<shadow.h>}):
\begin{tableiii}{r|l|l}{textrm}{Index}{Attribute}{Meaning}
\lineiii{0}{\code{sp_nam}}{Login name}
\lineiii{1}{\code{sp_pwd}}{Encrypted password}
\lineiii{2}{\code{sp_lstchg}}{Date of last change}
\lineiii{3}{\code{sp_min}}{Minimal number of days between changes}
\lineiii{4}{\code{sp_max}}{Maximum number of days between changes}
\lineiii{5}{\code{sp_warn}}{Number of days before password expires to warn user about it}
\lineiii{6}{\code{sp_inact}}{Number of days after password expires until account is blocked}
\lineiii{7}{\code{sp_expire}}{Number of days since 1970-01-01 until account is disabled}
\lineiii{8}{\code{sp_flag}}{Reserved}
\end{tableiii}
The sp_nam and sp_pwd items are strings, all others are integers.
\exception{KeyError} is raised if the entry asked for cannot be found.
It defines the following items:
\begin{funcdesc}{getspnam}{name}
Return the shadow password database entry for the given user name.
\end{funcdesc}
\begin{funcdesc}{getspall}{}
Return a list of all available shadow password database entries, in arbitrary order.
\end{funcdesc}
\begin{seealso}
\seemodule{pwd}{An interface to the normal password database, similar to this.}
\end{seealso}

View File

@ -22,6 +22,8 @@ Core and builtins
Extension Modules
-----------------
- The spwd has been added, allowing access to the shadow password database.
- stat_float_times is now True.
- array.array objects are now picklable.

View File

@ -183,6 +183,7 @@ GLHACK=-Dclear=__GLclear
#fcntl fcntlmodule.c # fcntl(2) and ioctl(2)
#pwd pwdmodule.c # pwd(3)
#spwd spwdmodule.c # spwd(3)
#grp grpmodule.c # grp(3)
#select selectmodule.c # select(2); not on ancient System V

179
Modules/spwdmodule.c Normal file
View File

@ -0,0 +1,179 @@
/* 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 "structseq.h"
#include <sys/types.h>
#ifdef HAVE_SHADOW_H
#include <shadow.h>
#endif
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_nam", "login name"},
{"sp_pwd", "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 blocked"},
{"sp_expire", "#days since 1970-01-01 until account is disabled"},
{"sp_flag", "reserved"},
{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_nam,sp_pwd,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,
};
static PyTypeObject StructSpwdType;
static void
sets(PyObject *v, int i, char* val)
{
if (val)
PyStructSequence_SET_ITEM(v, i, PyString_FromString(val));
else {
PyStructSequence_SET_ITEM(v, i, Py_None);
Py_INCREF(Py_None);
}
}
static PyObject *mkspent(struct spwd *p)
{
int setIndex = 0;
PyObject *v = PyStructSequence_New(&StructSpwdType);
if (v == NULL)
return NULL;
#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_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);
#undef SETS
#undef SETI
if (PyErr_Occurred()) {
Py_XDECREF(v);
return NULL;
}
return v;
}
#endif /* HAVE_GETSPNAM || HAVE_GETSPENT */
#ifdef HAVE_GETSPNAM
PyDoc_STRVAR(spwd_getspnam__doc__,
"getspnam(name) -> (sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max,\n\
sp_warn, sp_inact, sp_expire, sp_flag)\n\
Return the shadow password database entry for the given user name.\n\
See spwd.__doc__ for more on shadow password database entries.");
static PyObject* spwd_getspnam(PyObject *self, PyObject *args)
{
char *name;
struct spwd *p;
if (!PyArg_ParseTuple(args, "s:getspnam", &name))
return NULL;
if ((p = getspnam(name)) == NULL) {
PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
return NULL;
}
return mkspent(p);
}
PyDoc_STRVAR(spwd_getspall__doc__,
"getspall() -> list_of_entries\n\
Return a list of all available shadow password database entries, \
in arbitrary order.\n\
See spwd.__doc__ for more on shadow password database entries.");
#endif /* HAVE_GETSPNAM */
#ifdef HAVE_GETSPENT
static PyObject *
spwd_getspall(PyObject *self, PyObject *args)
{
PyObject *d;
struct spwd *p;
// if (!PyArg_NoArgs(args))
// return NULL;
if ((d = PyList_New(0)) == NULL)
return NULL;
setspent();
while ((p = getspent()) != NULL) {
PyObject *v = mkspent(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
{"getspnam", spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__},
#endif
#ifdef HAVE_GETSPENT
{"getspall", spwd_getspall, METH_NOARGS, spwd_getspall__doc__},
#endif
{NULL, NULL} /* sentinel */
};
PyMODINIT_FUNC
initspwd(void)
{
PyObject *m;
m=Py_InitModule3("spwd", spwd_methods, spwd__doc__);
PyStructSequence_InitType(&StructSpwdType, &struct_spwd_type_desc);
Py_INCREF((PyObject *) &StructSpwdType);
PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
}

649
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -960,7 +960,7 @@ dnl AC_MSG_RESULT($cpp_type)
# checks for header files
AC_HEADER_STDC
AC_CHECK_HEADERS(curses.h dlfcn.h fcntl.h grp.h langinfo.h \
AC_CHECK_HEADERS(curses.h dlfcn.h fcntl.h grp.h shadow.h langinfo.h \
libintl.h ncurses.h poll.h pthread.h \
stropts.h termios.h thread.h \
unistd.h utime.h \
@ -2076,7 +2076,7 @@ AC_MSG_RESULT(MACHDEP_OBJS)
AC_CHECK_FUNCS(alarm bind_textdomain_codeset chown clock confstr ctermid \
execv fork fpathconf ftime ftruncate \
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
getpriority getpwent getsid getwd \
getpriority getpwent getspnam getspent getsid getwd \
kill killpg lchown lstat mkfifo mknod mktime \
mremap nice pathconf pause plock poll pthread_init \
putenv readlink realpath \

View File

@ -215,6 +215,12 @@
/* Define to 1 if you have the `getsid' function. */
#undef HAVE_GETSID
/* Define to 1 if you have the `getspent' function. */
#undef HAVE_GETSPENT
/* Define to 1 if you have the `getspnam' function. */
#undef HAVE_GETSPNAM
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
@ -419,6 +425,9 @@
/* Define to 1 if you have the `setvbuf' function. */
#undef HAVE_SETVBUF
/* Define to 1 if you have the <shadow.h> header file. */
#undef HAVE_SHADOW_H
/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION

View File

@ -388,6 +388,8 @@ class PyBuildExt(build_ext):
exts.append( Extension('pwd', ['pwdmodule.c']) )
# grp(3)
exts.append( Extension('grp', ['grpmodule.c']) )
# spwd, shadow passwords
exts.append( Extension('spwd', ['spwdmodule.c']) )
# select(2); not on ancient System V
exts.append( Extension('select', ['selectmodule.c']) )