mirror of https://github.com/python/cpython.git
Renamed, and bug fixed:
Two interesting problems in nis_maplist(). First, it is possible that clnt_create() will return NULL. This was being caught, but no Python error was being set. I use clnt_spcreateerror() to generate the value of the exception. But why would clnt_create() fail? It's because no server was being found. And why was this? It was because nis_maplist() tried only to get the NIS master for the first map in the aliases list, which is passwd.byname, and guess what? That's the one NIS map CNRI does *not* export! So the yp_master() call was failing to return a valid server. I now cycle through all the map aliases until I find a valid master. If not, a different exception is set. I'm not sure this is the completely correct way to do all this, but short of rewriting the entire nismodule.c (to expose the proper API to Python), it should do the trick.
This commit is contained in:
parent
3f236dee3a
commit
adbf4e66df
|
@ -10,9 +10,7 @@
|
||||||
|
|
||||||
/* NIS module implementation */
|
/* NIS module implementation */
|
||||||
|
|
||||||
#include "allobjects.h"
|
#include "Python.h"
|
||||||
#include "modsupport.h"
|
|
||||||
#include "ceval.h"
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -25,13 +23,13 @@
|
||||||
extern int yp_get_default_domain();
|
extern int yp_get_default_domain();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static object *NisError;
|
static PyObject *NisError;
|
||||||
|
|
||||||
static object *
|
static PyObject *
|
||||||
nis_error (err)
|
nis_error (err)
|
||||||
int err;
|
int err;
|
||||||
{
|
{
|
||||||
err_setstr(NisError, yperr_string(err));
|
PyErr_SetString(NisError, yperr_string(err));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +60,7 @@ nis_mapname (map)
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*foreachfunc) PROTO((int, char *, int, char *, int, char *));
|
typedef int (*foreachfunc) Py_PROTO((int, char *, int, char *, int, char *));
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
|
nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
|
||||||
|
@ -71,24 +69,24 @@ nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
|
||||||
int inkeylen;
|
int inkeylen;
|
||||||
char *inval;
|
char *inval;
|
||||||
int invallen;
|
int invallen;
|
||||||
object *indata;
|
PyObject *indata;
|
||||||
{
|
{
|
||||||
if (instatus == YP_TRUE) {
|
if (instatus == YP_TRUE) {
|
||||||
object *key = newsizedstringobject(inkey, inkeylen);
|
PyObject *key = PyString_FromStringAndSize(inkey, inkeylen);
|
||||||
object *val = newsizedstringobject(inval, invallen);
|
PyObject *val = PyString_FromStringAndSize(inval, invallen);
|
||||||
int err;
|
int err;
|
||||||
if (key == NULL || val == NULL) {
|
if (key == NULL || val == NULL) {
|
||||||
/* XXX error -- don't know how to handle */
|
/* XXX error -- don't know how to handle */
|
||||||
err_clear();
|
PyErr_Clear();
|
||||||
XDECREF(key);
|
Py_XDECREF(key);
|
||||||
XDECREF(val);
|
Py_XDECREF(val);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
err = mappinginsert(indata, key, val);
|
err = PyDict_SetItem(indata, key, val);
|
||||||
DECREF(key);
|
Py_DECREF(key);
|
||||||
DECREF(val);
|
Py_DECREF(val);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
err_clear();
|
PyErr_Clear();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -96,59 +94,59 @@ nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static object *
|
static PyObject *
|
||||||
nis_match (self, args)
|
nis_match (self, args)
|
||||||
object *self;
|
PyObject *self;
|
||||||
object *args;
|
PyObject *args;
|
||||||
{
|
{
|
||||||
char *match;
|
char *match;
|
||||||
char *domain;
|
char *domain;
|
||||||
int keylen, len;
|
int keylen, len;
|
||||||
char *key, *map;
|
char *key, *map;
|
||||||
int err;
|
int err;
|
||||||
object *res;
|
PyObject *res;
|
||||||
|
|
||||||
if (!getargs(args, "(s#s)", &key, &keylen, &map))
|
if (!PyArg_Parse(args, "(s#s)", &key, &keylen, &map))
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((err = yp_get_default_domain(&domain)) != 0)
|
if ((err = yp_get_default_domain(&domain)) != 0)
|
||||||
return nis_error(err);
|
return nis_error(err);
|
||||||
BGN_SAVE
|
Py_BEGIN_ALLOW_THREADS
|
||||||
map = nis_mapname (map);
|
map = nis_mapname (map);
|
||||||
err = yp_match (domain, map, key, keylen, &match, &len);
|
err = yp_match (domain, map, key, keylen, &match, &len);
|
||||||
END_SAVE
|
Py_END_ALLOW_THREADS
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
return nis_error(err);
|
return nis_error(err);
|
||||||
res = newsizedstringobject (match, len);
|
res = PyString_FromStringAndSize (match, len);
|
||||||
free (match);
|
free (match);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static object *
|
static PyObject *
|
||||||
nis_cat (self, args)
|
nis_cat (self, args)
|
||||||
object *self;
|
PyObject *self;
|
||||||
object *args;
|
PyObject *args;
|
||||||
{
|
{
|
||||||
char *domain;
|
char *domain;
|
||||||
char *map;
|
char *map;
|
||||||
struct ypall_callback cb;
|
struct ypall_callback cb;
|
||||||
object *cat;
|
PyObject *cat;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!getstrarg(args, &map))
|
if (!PyArg_Parse(args, "s", &map))
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((err = yp_get_default_domain(&domain)) != 0)
|
if ((err = yp_get_default_domain(&domain)) != 0)
|
||||||
return nis_error(err);
|
return nis_error(err);
|
||||||
cat = newdictobject ();
|
cat = PyDict_New ();
|
||||||
if (cat == NULL)
|
if (cat == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
cb.foreach = (foreachfunc)nis_foreach;
|
cb.foreach = (foreachfunc)nis_foreach;
|
||||||
cb.data = (char *)cat;
|
cb.data = (char *)cat;
|
||||||
BGN_SAVE
|
Py_BEGIN_ALLOW_THREADS
|
||||||
map = nis_mapname (map);
|
map = nis_mapname (map);
|
||||||
err = yp_all (domain, map, &cb);
|
err = yp_all (domain, map, &cb);
|
||||||
END_SAVE
|
Py_END_ALLOW_THREADS
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
DECREF(cat);
|
Py_DECREF(cat);
|
||||||
return nis_error(err);
|
return nis_error(err);
|
||||||
}
|
}
|
||||||
return cat;
|
return cat;
|
||||||
|
@ -170,23 +168,23 @@ typedef char *domainname;
|
||||||
typedef char *mapname;
|
typedef char *mapname;
|
||||||
|
|
||||||
enum nisstat {
|
enum nisstat {
|
||||||
NIS_TRUE = 1,
|
NIS_TRUE = 1,
|
||||||
NIS_NOMORE = 2,
|
NIS_NOMORE = 2,
|
||||||
NIS_FALSE = 0,
|
NIS_FALSE = 0,
|
||||||
NIS_NOMAP = -1,
|
NIS_NOMAP = -1,
|
||||||
NIS_NODOM = -2,
|
NIS_NODOM = -2,
|
||||||
NIS_NOKEY = -3,
|
NIS_NOKEY = -3,
|
||||||
NIS_BADOP = -4,
|
NIS_BADOP = -4,
|
||||||
NIS_BADDB = -5,
|
NIS_BADDB = -5,
|
||||||
NIS_YPERR = -6,
|
NIS_YPERR = -6,
|
||||||
NIS_BADARGS = -7,
|
NIS_BADARGS = -7,
|
||||||
NIS_VERS = -8
|
NIS_VERS = -8
|
||||||
};
|
};
|
||||||
typedef enum nisstat nisstat;
|
typedef enum nisstat nisstat;
|
||||||
|
|
||||||
struct nismaplist {
|
struct nismaplist {
|
||||||
mapname map;
|
mapname map;
|
||||||
struct nismaplist *next;
|
struct nismaplist *next;
|
||||||
};
|
};
|
||||||
typedef struct nismaplist nismaplist;
|
typedef struct nismaplist nismaplist;
|
||||||
|
|
||||||
|
@ -201,86 +199,90 @@ static struct timeval TIMEOUT = { 25, 0 };
|
||||||
static
|
static
|
||||||
bool_t
|
bool_t
|
||||||
nis_xdr_domainname(xdrs, objp)
|
nis_xdr_domainname(xdrs, objp)
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
domainname *objp;
|
domainname *objp;
|
||||||
{
|
{
|
||||||
if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
|
if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool_t
|
bool_t
|
||||||
nis_xdr_mapname(xdrs, objp)
|
nis_xdr_mapname(xdrs, objp)
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
mapname *objp;
|
mapname *objp;
|
||||||
{
|
{
|
||||||
if (!xdr_string(xdrs, objp, YPMAXMAP)) {
|
if (!xdr_string(xdrs, objp, YPMAXMAP)) {
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool_t
|
bool_t
|
||||||
nis_xdr_ypmaplist(xdrs, objp)
|
nis_xdr_ypmaplist(xdrs, objp)
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
nismaplist *objp;
|
nismaplist *objp;
|
||||||
{
|
{
|
||||||
if (!nis_xdr_mapname(xdrs, &objp->map)) {
|
if (!nis_xdr_mapname(xdrs, &objp->map)) {
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof(nismaplist), nis_xdr_ypmaplist)) {
|
if (!xdr_pointer(xdrs, (char **)&objp->next,
|
||||||
return (FALSE);
|
sizeof(nismaplist), nis_xdr_ypmaplist))
|
||||||
}
|
{
|
||||||
return (TRUE);
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool_t
|
bool_t
|
||||||
nis_xdr_ypstat(xdrs, objp)
|
nis_xdr_ypstat(xdrs, objp)
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
nisstat *objp;
|
nisstat *objp;
|
||||||
{
|
{
|
||||||
if (!xdr_enum(xdrs, (enum_t *)objp)) {
|
if (!xdr_enum(xdrs, (enum_t *)objp)) {
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool_t
|
bool_t
|
||||||
nis_xdr_ypresp_maplist(xdrs, objp)
|
nis_xdr_ypresp_maplist(xdrs, objp)
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
nisresp_maplist *objp;
|
nisresp_maplist *objp;
|
||||||
{
|
{
|
||||||
if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
|
if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (!xdr_pointer(xdrs, (char **)&objp->maps, sizeof(nismaplist), nis_xdr_ypmaplist)) {
|
if (!xdr_pointer(xdrs, (char **)&objp->maps,
|
||||||
return (FALSE);
|
sizeof(nismaplist), nis_xdr_ypmaplist))
|
||||||
}
|
{
|
||||||
return (TRUE);
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
nisresp_maplist *
|
nisresp_maplist *
|
||||||
nisproc_maplist_2(argp, clnt)
|
nisproc_maplist_2(argp, clnt)
|
||||||
domainname *argp;
|
domainname *argp;
|
||||||
CLIENT *clnt;
|
CLIENT *clnt;
|
||||||
{
|
{
|
||||||
static nisresp_maplist res;
|
static nisresp_maplist res;
|
||||||
|
|
||||||
memset(&res, 0, sizeof(res));
|
memset(&res, 0, sizeof(res));
|
||||||
if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, (caddr_t)argp,
|
if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, (caddr_t)argp,
|
||||||
nis_xdr_ypresp_maplist, (caddr_t)&res, TIMEOUT)
|
nis_xdr_ypresp_maplist, (caddr_t)&res, TIMEOUT)
|
||||||
!= RPC_SUCCESS) {
|
!= RPC_SUCCESS) {
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
return (&res);
|
return (&res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -290,13 +292,21 @@ nis_maplist ()
|
||||||
nisresp_maplist *list;
|
nisresp_maplist *list;
|
||||||
char *dom;
|
char *dom;
|
||||||
CLIENT *cl, *clnt_create();
|
CLIENT *cl, *clnt_create();
|
||||||
char *server;
|
char *server = "";
|
||||||
|
int mapi = 0;
|
||||||
|
|
||||||
yp_get_default_domain (&dom);
|
yp_get_default_domain (&dom);
|
||||||
yp_master (dom, aliases[0].map, &server);
|
while (!strcmp("", server) && aliases[mapi].map != 0L) {
|
||||||
|
yp_master (dom, aliases[mapi].map, &server);
|
||||||
|
mapi++;
|
||||||
|
}
|
||||||
|
if (!strcmp("", server)) {
|
||||||
|
PyErr_SetString(NisError, "No NIS master found for any map");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
cl = clnt_create(server, YPPROG, YPVERS, "tcp");
|
cl = clnt_create(server, YPPROG, YPVERS, "tcp");
|
||||||
if (cl == NULL) {
|
if (cl == NULL) {
|
||||||
clnt_pcreateerror(server);
|
PyErr_SetString(NisError, clnt_spcreateerror(server));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
list = nisproc_maplist_2 (&dom, cl);
|
list = nisproc_maplist_2 (&dom, cl);
|
||||||
|
@ -307,21 +317,22 @@ nis_maplist ()
|
||||||
return list->maps;
|
return list->maps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static object *
|
static PyObject *
|
||||||
nis_maps (self, args)
|
nis_maps (self, args)
|
||||||
object *self;
|
PyObject *self;
|
||||||
object *args;
|
PyObject *args;
|
||||||
{
|
{
|
||||||
nismaplist *maps;
|
nismaplist *maps;
|
||||||
object *list;
|
PyObject *list;
|
||||||
|
|
||||||
if ((maps = nis_maplist ()) == NULL)
|
if ((maps = nis_maplist ()) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((list = newlistobject(0)) == NULL)
|
if ((list = PyList_New(0)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (maps = maps->next; maps; maps = maps->next) {
|
for (maps = maps->next; maps; maps = maps->next) {
|
||||||
if (addlistitem (list, newstringobject (maps->map)) < 0) {
|
if (PyList_Append (list, PyString_FromString (maps->map)) < 0)
|
||||||
DECREF(list);
|
{
|
||||||
|
Py_DECREF(list);
|
||||||
list = NULL;
|
list = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -330,7 +341,7 @@ nis_maps (self, args)
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct methodlist nis_methods[] = {
|
static PyMethodDef nis_methods[] = {
|
||||||
{"match", nis_match},
|
{"match", nis_match},
|
||||||
{"cat", nis_cat},
|
{"cat", nis_cat},
|
||||||
{"maps", nis_maps},
|
{"maps", nis_maps},
|
||||||
|
@ -340,10 +351,11 @@ static struct methodlist nis_methods[] = {
|
||||||
void
|
void
|
||||||
initnis ()
|
initnis ()
|
||||||
{
|
{
|
||||||
object *m, *d;
|
PyObject *m, *d;
|
||||||
m = initmodule("nis", nis_methods);
|
m = Py_InitModule("nis", nis_methods);
|
||||||
d = getmoduledict(m);
|
d = PyModule_GetDict(m);
|
||||||
NisError = newstringobject("nis.error");
|
NisError = PyString_FromString("nis.error");
|
||||||
if (NisError == NULL || dictinsert(d, "error", NisError) != 0)
|
if (NisError == NULL ||
|
||||||
fatal("Cannot define nis.error");
|
PyDict_SetItemString(d, "error", NisError) != 0)
|
||||||
|
Py_FatalError("Cannot define nis.error");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue