1 /***********************************************************
3 Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
5 Faculteit der Informatica,
9 ******************************************************************/
11 /* NIS module implementation */
16 #include <sys/types.h>
18 #include <rpcsvc/yp_prot.h>
19 #include <rpcsvc/ypclnt.h>
22 /* This is missing from rpcsvc/ypclnt.h */
23 extern int yp_get_default_domain(char **);
26 static PyObject
*NisError
;
31 PyErr_SetString(NisError
, yperr_string(err
));
35 static struct nis_map
{
40 {"passwd", "passwd.byname", 0},
41 {"group", "group.byname", 0},
42 {"networks", "networks.byaddr", 0},
43 {"hosts", "hosts.byname", 0},
44 {"protocols", "protocols.bynumber", 0},
45 {"services", "services.byname", 0},
46 {"aliases", "mail.aliases", 1}, /* created with 'makedbm -a' */
47 {"ethers", "ethers.byname", 0},
52 nis_mapname (char *map
, int *pfix
)
57 for (i
=0; aliases
[i
].alias
!= 0L; i
++) {
58 if (!strcmp (aliases
[i
].alias
, map
)) {
59 *pfix
= aliases
[i
].fix
;
60 return aliases
[i
].map
;
62 if (!strcmp (aliases
[i
].map
, map
)) {
63 *pfix
= aliases
[i
].fix
;
64 return aliases
[i
].map
;
72 typedef int (*foreachfunc
)(unsigned long, char *, int, char *, int, void *);
74 typedef int (*foreachfunc
)(int, char *, int, char *, int, char *);
77 struct ypcallback_data
{
83 nis_foreach (int instatus
, char *inkey
, int inkeylen
, char *inval
,
84 int invallen
, struct ypcallback_data
*indata
)
86 if (instatus
== YP_TRUE
) {
92 if (inkeylen
> 0 && inkey
[inkeylen
-1] == '\0')
94 if (invallen
> 0 && inval
[invallen
-1] == '\0')
97 key
= PyString_FromStringAndSize(inkey
, inkeylen
);
98 val
= PyString_FromStringAndSize(inval
, invallen
);
99 if (key
== NULL
|| val
== NULL
) {
100 /* XXX error -- don't know how to handle */
106 err
= PyDict_SetItem(indata
->dict
, key
, val
);
119 nis_match (PyObject
*self
, PyObject
*args
)
129 if (!PyArg_ParseTuple(args
, "t#s:match", &key
, &keylen
, &map
))
131 if ((err
= yp_get_default_domain(&domain
)) != 0)
132 return nis_error(err
);
133 map
= nis_mapname (map
, &fix
);
136 Py_BEGIN_ALLOW_THREADS
137 err
= yp_match (domain
, map
, key
, keylen
, &match
, &len
);
142 return nis_error(err
);
143 res
= PyString_FromStringAndSize (match
, len
);
149 nis_cat (PyObject
*self
, PyObject
*args
)
153 struct ypall_callback cb
;
154 struct ypcallback_data data
;
158 if (!PyArg_ParseTuple(args
, "s:cat", &map
))
160 if ((err
= yp_get_default_domain(&domain
)) != 0)
161 return nis_error(err
);
162 dict
= PyDict_New ();
165 cb
.foreach
= (foreachfunc
)nis_foreach
;
167 map
= nis_mapname (map
, &data
.fix
);
168 cb
.data
= (char *)&data
;
169 Py_BEGIN_ALLOW_THREADS
170 err
= yp_all (domain
, map
, &cb
);
174 return nis_error(err
);
179 /* These should be u_long on Sun h/w but not on 64-bit h/w.
180 This is not portable to machines with 16-bit ints and no prototypes */
181 #ifndef YPPROC_MAPLIST
182 #define YPPROC_MAPLIST 11
185 #define YPPROG 100004
191 typedef char *domainname
;
192 typedef char *mapname
;
207 typedef enum nisstat nisstat
;
211 struct nismaplist
*next
;
213 typedef struct nismaplist nismaplist
;
215 struct nisresp_maplist
{
219 typedef struct nisresp_maplist nisresp_maplist
;
221 static struct timeval TIMEOUT
= { 25, 0 };
225 nis_xdr_domainname(XDR
*xdrs
, domainname
*objp
)
227 if (!xdr_string(xdrs
, objp
, YPMAXDOMAIN
)) {
235 nis_xdr_mapname(XDR
*xdrs
, mapname
*objp
)
237 if (!xdr_string(xdrs
, objp
, YPMAXMAP
)) {
245 nis_xdr_ypmaplist(XDR
*xdrs
, nismaplist
*objp
)
247 if (!nis_xdr_mapname(xdrs
, &objp
->map
)) {
250 if (!xdr_pointer(xdrs
, (char **)&objp
->next
,
251 sizeof(nismaplist
), (xdrproc_t
)nis_xdr_ypmaplist
))
260 nis_xdr_ypstat(XDR
*xdrs
, nisstat
*objp
)
262 if (!xdr_enum(xdrs
, (enum_t
*)objp
)) {
271 nis_xdr_ypresp_maplist(XDR
*xdrs
, nisresp_maplist
*objp
)
273 if (!nis_xdr_ypstat(xdrs
, &objp
->stat
)) {
276 if (!xdr_pointer(xdrs
, (char **)&objp
->maps
,
277 sizeof(nismaplist
), (xdrproc_t
)nis_xdr_ypmaplist
))
287 nisproc_maplist_2(domainname
*argp
, CLIENT
*clnt
)
289 static nisresp_maplist res
;
291 memset(&res
, 0, sizeof(res
));
292 if (clnt_call(clnt
, YPPROC_MAPLIST
,
293 (xdrproc_t
)nis_xdr_domainname
, (caddr_t
)argp
,
294 (xdrproc_t
)nis_xdr_ypresp_maplist
, (caddr_t
)&res
,
295 TIMEOUT
) != RPC_SUCCESS
)
306 nisresp_maplist
*list
;
313 if ((err
= yp_get_default_domain (&dom
)) != 0) {
318 while (!server
&& aliases
[mapi
].map
!= 0L) {
319 yp_master (dom
, aliases
[mapi
].map
, &server
);
323 PyErr_SetString(NisError
, "No NIS master found for any map");
326 cl
= clnt_create(server
, YPPROG
, YPVERS
, "tcp");
328 PyErr_SetString(NisError
, clnt_spcreateerror(server
));
331 list
= nisproc_maplist_2 (&dom
, cl
);
335 if (list
->stat
!= NIS_TRUE
)
347 nis_maps (PyObject
*self
)
352 if ((maps
= nis_maplist ()) == NULL
)
354 if ((list
= PyList_New(0)) == NULL
)
356 for (maps
= maps
; maps
; maps
= maps
->next
) {
357 PyObject
*str
= PyString_FromString(maps
->map
);
358 if (!str
|| PyList_Append(list
, str
) < 0)
366 /* XXX Shouldn't we free the list of maps now? */
370 static PyMethodDef nis_methods
[] = {
371 {"match", nis_match
, METH_VARARGS
},
372 {"cat", nis_cat
, METH_VARARGS
},
373 {"maps", (PyCFunction
)nis_maps
, METH_NOARGS
},
374 {NULL
, NULL
} /* Sentinel */
381 m
= Py_InitModule("nis", nis_methods
);
382 d
= PyModule_GetDict(m
);
383 NisError
= PyErr_NewException("nis.error", NULL
, NULL
);
384 if (NisError
!= NULL
)
385 PyDict_SetItemString(d
, "error", NisError
);