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
;
71 typedef int (*foreachfunc
)(int, char *, int, char *, int, char *);
73 struct ypcallback_data
{
79 nis_foreach (int instatus
, char *inkey
, int inkeylen
, char *inval
,
80 int invallen
, struct ypcallback_data
*indata
)
82 if (instatus
== YP_TRUE
) {
88 if (inkeylen
> 0 && inkey
[inkeylen
-1] == '\0')
90 if (invallen
> 0 && inval
[invallen
-1] == '\0')
93 key
= PyString_FromStringAndSize(inkey
, inkeylen
);
94 val
= PyString_FromStringAndSize(inval
, invallen
);
95 if (key
== NULL
|| val
== NULL
) {
96 /* XXX error -- don't know how to handle */
102 err
= PyDict_SetItem(indata
->dict
, key
, val
);
115 nis_match (PyObject
*self
, PyObject
*args
)
125 if (!PyArg_ParseTuple(args
, "t#s:match", &key
, &keylen
, &map
))
127 if ((err
= yp_get_default_domain(&domain
)) != 0)
128 return nis_error(err
);
129 map
= nis_mapname (map
, &fix
);
132 Py_BEGIN_ALLOW_THREADS
133 err
= yp_match (domain
, map
, key
, keylen
, &match
, &len
);
138 return nis_error(err
);
139 res
= PyString_FromStringAndSize (match
, len
);
145 nis_cat (PyObject
*self
, PyObject
*args
)
149 struct ypall_callback cb
;
150 struct ypcallback_data data
;
154 if (!PyArg_ParseTuple(args
, "s:cat", &map
))
156 if ((err
= yp_get_default_domain(&domain
)) != 0)
157 return nis_error(err
);
158 dict
= PyDict_New ();
161 cb
.foreach
= (foreachfunc
)nis_foreach
;
163 map
= nis_mapname (map
, &data
.fix
);
164 cb
.data
= (char *)&data
;
165 Py_BEGIN_ALLOW_THREADS
166 err
= yp_all (domain
, map
, &cb
);
170 return nis_error(err
);
175 /* These should be u_long on Sun h/w but not on 64-bit h/w.
176 This is not portable to machines with 16-bit ints and no prototypes */
177 #ifndef YPPROC_MAPLIST
178 #define YPPROC_MAPLIST 11
181 #define YPPROG 100004
187 typedef char *domainname
;
188 typedef char *mapname
;
203 typedef enum nisstat nisstat
;
207 struct nismaplist
*next
;
209 typedef struct nismaplist nismaplist
;
211 struct nisresp_maplist
{
215 typedef struct nisresp_maplist nisresp_maplist
;
217 static struct timeval TIMEOUT
= { 25, 0 };
221 nis_xdr_domainname(XDR
*xdrs
, domainname
*objp
)
223 if (!xdr_string(xdrs
, objp
, YPMAXDOMAIN
)) {
231 nis_xdr_mapname(XDR
*xdrs
, mapname
*objp
)
233 if (!xdr_string(xdrs
, objp
, YPMAXMAP
)) {
241 nis_xdr_ypmaplist(XDR
*xdrs
, nismaplist
*objp
)
243 if (!nis_xdr_mapname(xdrs
, &objp
->map
)) {
246 if (!xdr_pointer(xdrs
, (char **)&objp
->next
,
247 sizeof(nismaplist
), (xdrproc_t
)nis_xdr_ypmaplist
))
256 nis_xdr_ypstat(XDR
*xdrs
, nisstat
*objp
)
258 if (!xdr_enum(xdrs
, (enum_t
*)objp
)) {
267 nis_xdr_ypresp_maplist(XDR
*xdrs
, nisresp_maplist
*objp
)
269 if (!nis_xdr_ypstat(xdrs
, &objp
->stat
)) {
272 if (!xdr_pointer(xdrs
, (char **)&objp
->maps
,
273 sizeof(nismaplist
), (xdrproc_t
)nis_xdr_ypmaplist
))
283 nisproc_maplist_2(domainname
*argp
, CLIENT
*clnt
)
285 static nisresp_maplist res
;
287 memset(&res
, 0, sizeof(res
));
288 if (clnt_call(clnt
, YPPROC_MAPLIST
,
289 (xdrproc_t
)nis_xdr_domainname
, (caddr_t
)argp
,
290 (xdrproc_t
)nis_xdr_ypresp_maplist
, (caddr_t
)&res
,
291 TIMEOUT
) != RPC_SUCCESS
)
302 nisresp_maplist
*list
;
309 if ((err
= yp_get_default_domain (&dom
)) != 0) {
314 while (!server
&& aliases
[mapi
].map
!= 0L) {
315 yp_master (dom
, aliases
[mapi
].map
, &server
);
319 PyErr_SetString(NisError
, "No NIS master found for any map");
322 cl
= clnt_create(server
, YPPROG
, YPVERS
, "tcp");
324 PyErr_SetString(NisError
, clnt_spcreateerror(server
));
327 list
= nisproc_maplist_2 (&dom
, cl
);
331 if (list
->stat
!= NIS_TRUE
)
343 nis_maps (PyObject
*self
)
348 if ((maps
= nis_maplist ()) == NULL
)
350 if ((list
= PyList_New(0)) == NULL
)
352 for (maps
= maps
; maps
; maps
= maps
->next
) {
353 PyObject
*str
= PyString_FromString(maps
->map
);
354 if (!str
|| PyList_Append(list
, str
) < 0)
362 /* XXX Shouldn't we free the list of maps now? */
366 static PyMethodDef nis_methods
[] = {
367 {"match", nis_match
, METH_VARARGS
},
368 {"cat", nis_cat
, METH_VARARGS
},
369 {"maps", (PyCFunction
)nis_maps
, METH_NOARGS
},
370 {NULL
, NULL
} /* Sentinel */
377 m
= Py_InitModule("nis", nis_methods
);
378 d
= PyModule_GetDict(m
);
379 NisError
= PyErr_NewException("nis.error", NULL
, NULL
);
380 if (NisError
!= NULL
)
381 PyDict_SetItemString(d
, "error", NisError
);