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
) {
91 key
= PyString_FromStringAndSize(inkey
, inkeylen
);
92 val
= PyString_FromStringAndSize(inval
, invallen
);
93 if (key
== NULL
|| val
== NULL
) {
94 /* XXX error -- don't know how to handle */
100 err
= PyDict_SetItem(indata
->dict
, key
, val
);
113 nis_match (PyObject
*self
, PyObject
*args
)
123 if (!PyArg_Parse(args
, "(t#s)", &key
, &keylen
, &map
))
125 if ((err
= yp_get_default_domain(&domain
)) != 0)
126 return nis_error(err
);
127 map
= nis_mapname (map
, &fix
);
130 Py_BEGIN_ALLOW_THREADS
131 err
= yp_match (domain
, map
, key
, keylen
, &match
, &len
);
136 return nis_error(err
);
137 res
= PyString_FromStringAndSize (match
, len
);
143 nis_cat (PyObject
*self
, PyObject
*args
)
147 struct ypall_callback cb
;
148 struct ypcallback_data data
;
152 if (!PyArg_Parse(args
, "s", &map
))
154 if ((err
= yp_get_default_domain(&domain
)) != 0)
155 return nis_error(err
);
156 dict
= PyDict_New ();
159 cb
.foreach
= (foreachfunc
)nis_foreach
;
161 map
= nis_mapname (map
, &data
.fix
);
162 cb
.data
= (char *)&data
;
163 Py_BEGIN_ALLOW_THREADS
164 err
= yp_all (domain
, map
, &cb
);
168 return nis_error(err
);
173 /* These should be u_long on Sun h/w but not on 64-bit h/w.
174 This is not portable to machines with 16-bit ints and no prototypes */
175 #ifndef YPPROC_MAPLIST
176 #define YPPROC_MAPLIST 11
179 #define YPPROG 100004
185 typedef char *domainname
;
186 typedef char *mapname
;
201 typedef enum nisstat nisstat
;
205 struct nismaplist
*next
;
207 typedef struct nismaplist nismaplist
;
209 struct nisresp_maplist
{
213 typedef struct nisresp_maplist nisresp_maplist
;
215 static struct timeval TIMEOUT
= { 25, 0 };
219 nis_xdr_domainname(XDR
*xdrs
, domainname
*objp
)
221 if (!xdr_string(xdrs
, objp
, YPMAXDOMAIN
)) {
229 nis_xdr_mapname(XDR
*xdrs
, mapname
*objp
)
231 if (!xdr_string(xdrs
, objp
, YPMAXMAP
)) {
239 nis_xdr_ypmaplist(XDR
*xdrs
, nismaplist
*objp
)
241 if (!nis_xdr_mapname(xdrs
, &objp
->map
)) {
244 if (!xdr_pointer(xdrs
, (char **)&objp
->next
,
245 sizeof(nismaplist
), (xdrproc_t
)nis_xdr_ypmaplist
))
254 nis_xdr_ypstat(XDR
*xdrs
, nisstat
*objp
)
256 if (!xdr_enum(xdrs
, (enum_t
*)objp
)) {
265 nis_xdr_ypresp_maplist(XDR
*xdrs
, nisresp_maplist
*objp
)
267 if (!nis_xdr_ypstat(xdrs
, &objp
->stat
)) {
270 if (!xdr_pointer(xdrs
, (char **)&objp
->maps
,
271 sizeof(nismaplist
), (xdrproc_t
)nis_xdr_ypmaplist
))
281 nisproc_maplist_2(domainname
*argp
, CLIENT
*clnt
)
283 static nisresp_maplist res
;
285 memset(&res
, 0, sizeof(res
));
286 if (clnt_call(clnt
, YPPROC_MAPLIST
,
287 (xdrproc_t
)nis_xdr_domainname
, (caddr_t
)argp
,
288 (xdrproc_t
)nis_xdr_ypresp_maplist
, (caddr_t
)&res
,
289 TIMEOUT
) != RPC_SUCCESS
)
300 nisresp_maplist
*list
;
302 CLIENT
*cl
, *clnt_create();
307 if ((err
= yp_get_default_domain (&dom
)) != 0) {
312 while (!server
&& aliases
[mapi
].map
!= 0L) {
313 yp_master (dom
, aliases
[mapi
].map
, &server
);
317 PyErr_SetString(NisError
, "No NIS master found for any map");
320 cl
= clnt_create(server
, YPPROG
, YPVERS
, "tcp");
322 PyErr_SetString(NisError
, clnt_spcreateerror(server
));
325 list
= nisproc_maplist_2 (&dom
, cl
);
329 if (list
->stat
!= NIS_TRUE
)
341 nis_maps (PyObject
*self
, PyObject
*args
)
346 if (!PyArg_NoArgs(args
))
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
},
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
);