Bug Summary

File:Modules/nismodule.c
Location:line 414, column 10
Description:Assigned value is always the same as the existing value

Annotated Source Code

1/***********************************************************
2 Written by:
3 Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
4 B&O group,
5 Faculteit der Informatica,
6 Universiteit Twente,
7 Enschede,
8 the Netherlands.
9******************************************************************/
10
11/* NIS module implementation */
12
13#include "Python.h"
14
15#include <sys/time.h>
16#include <sys/types.h>
17#include <rpc/rpc.h>
18#include <rpcsvc/yp_prot.h>
19#include <rpcsvc/ypclnt.h>
20
21#ifdef __sgi
22/* This is missing from rpcsvc/ypclnt.h */
23extern int yp_get_default_domain(char **);
24#endif
25
26PyDoc_STRVAR(get_default_domain__doc__,static char get_default_domain__doc__[] = "get_default_domain() -> str\nCorresponds to the C library yp_get_default_domain() call, returning\nthe default NIS domain.\n"
27"get_default_domain() -> str\n\static char get_default_domain__doc__[] = "get_default_domain() -> str\nCorresponds to the C library yp_get_default_domain() call, returning\nthe default NIS domain.\n"
28Corresponds to the C library yp_get_default_domain() call, returning\n\static char get_default_domain__doc__[] = "get_default_domain() -> str\nCorresponds to the C library yp_get_default_domain() call, returning\nthe default NIS domain.\n"
29the default NIS domain.\n")static char get_default_domain__doc__[] = "get_default_domain() -> str\nCorresponds to the C library yp_get_default_domain() call, returning\nthe default NIS domain.\n";
30
31PyDoc_STRVAR(match__doc__,static char match__doc__[] = "match(key, map, domain = defaultdomain)\nCorresponds to the C library yp_match() call, returning the value of\nkey in the given map. Optionally domain can be specified but it\ndefaults to the system default domain.\n"
32"match(key, map, domain = defaultdomain)\n\static char match__doc__[] = "match(key, map, domain = defaultdomain)\nCorresponds to the C library yp_match() call, returning the value of\nkey in the given map. Optionally domain can be specified but it\ndefaults to the system default domain.\n"
33Corresponds to the C library yp_match() call, returning the value of\n\static char match__doc__[] = "match(key, map, domain = defaultdomain)\nCorresponds to the C library yp_match() call, returning the value of\nkey in the given map. Optionally domain can be specified but it\ndefaults to the system default domain.\n"
34key in the given map. Optionally domain can be specified but it\n\static char match__doc__[] = "match(key, map, domain = defaultdomain)\nCorresponds to the C library yp_match() call, returning the value of\nkey in the given map. Optionally domain can be specified but it\ndefaults to the system default domain.\n"
35defaults to the system default domain.\n")static char match__doc__[] = "match(key, map, domain = defaultdomain)\nCorresponds to the C library yp_match() call, returning the value of\nkey in the given map. Optionally domain can be specified but it\ndefaults to the system default domain.\n";
36
37PyDoc_STRVAR(cat__doc__,static char cat__doc__[] = "cat(map, domain = defaultdomain)\nReturns the entire map as a dictionary. Optionally domain can be\nspecified but it defaults to the system default domain.\n"
38"cat(map, domain = defaultdomain)\n\static char cat__doc__[] = "cat(map, domain = defaultdomain)\nReturns the entire map as a dictionary. Optionally domain can be\nspecified but it defaults to the system default domain.\n"
39Returns the entire map as a dictionary. Optionally domain can be\n\static char cat__doc__[] = "cat(map, domain = defaultdomain)\nReturns the entire map as a dictionary. Optionally domain can be\nspecified but it defaults to the system default domain.\n"
40specified but it defaults to the system default domain.\n")static char cat__doc__[] = "cat(map, domain = defaultdomain)\nReturns the entire map as a dictionary. Optionally domain can be\nspecified but it defaults to the system default domain.\n";
41
42PyDoc_STRVAR(maps__doc__,static char maps__doc__[] = "maps(domain = defaultdomain)\nReturns an array of all available NIS maps within a domain. If domain\nis not specified it defaults to the system default domain.\n"
43"maps(domain = defaultdomain)\n\static char maps__doc__[] = "maps(domain = defaultdomain)\nReturns an array of all available NIS maps within a domain. If domain\nis not specified it defaults to the system default domain.\n"
44Returns an array of all available NIS maps within a domain. If domain\n\static char maps__doc__[] = "maps(domain = defaultdomain)\nReturns an array of all available NIS maps within a domain. If domain\nis not specified it defaults to the system default domain.\n"
45is not specified it defaults to the system default domain.\n")static char maps__doc__[] = "maps(domain = defaultdomain)\nReturns an array of all available NIS maps within a domain. If domain\nis not specified it defaults to the system default domain.\n";
46
47static PyObject *NisError;
48
49static PyObject *
50nis_error (int err)
51{
52 PyErr_SetString(NisError, yperr_string(err));
53 return NULL((void *)0);
54}
55
56static struct nis_map {
57 char *alias;
58 char *map;
59 int fix;
60} aliases [] = {
61 {"passwd", "passwd.byname", 0},
62 {"group", "group.byname", 0},
63 {"networks", "networks.byaddr", 0},
64 {"hosts", "hosts.byname", 0},
65 {"protocols", "protocols.bynumber", 0},
66 {"services", "services.byname", 0},
67 {"aliases", "mail.aliases", 1}, /* created with 'makedbm -a' */
68 {"ethers", "ethers.byname", 0},
69 {0L, 0L, 0}
70};
71
72static char *
73nis_mapname (char *map, int *pfix)
74{
75 int i;
76
77 *pfix = 0;
78 for (i=0; aliases[i].alias != 0L; i++) {
79 if (!strcmp (aliases[i].alias, map)) {
80 *pfix = aliases[i].fix;
81 return aliases[i].map;
82 }
83 if (!strcmp (aliases[i].map, map)) {
84 *pfix = aliases[i].fix;
85 return aliases[i].map;
86 }
87 }
88
89 return map;
90}
91
92#if defined(__APPLE__1) || defined(__OpenBSD__) || defined(__FreeBSD__)
93typedef int (*foreachfunc)(unsigned long, char *, int, char *, int, void *);
94#else
95typedef int (*foreachfunc)(int, char *, int, char *, int, char *);
96#endif
97
98struct ypcallback_data {
99 PyObject *dict;
100 int fix;
101 PyThreadState *state;
102};
103
104static int
105nis_foreach (int instatus, char *inkey, int inkeylen, char *inval,
106 int invallen, struct ypcallback_data *indata)
107{
108 if (instatus == YP_TRUE((long)1)) {
109 PyObject *key;
110 PyObject *val;
111 int err;
112
113 PyEval_RestoreThread(indata->state);
114 if (indata->fix) {
115 if (inkeylen > 0 && inkey[inkeylen-1] == '\0')
116 inkeylen--;
117 if (invallen > 0 && inval[invallen-1] == '\0')
118 invallen--;
119 }
120 key = PyUnicode_DecodeFSDefaultAndSizePyUnicodeUCS2_DecodeFSDefaultAndSize(inkey, inkeylen);
121 val = PyUnicode_DecodeFSDefaultAndSizePyUnicodeUCS2_DecodeFSDefaultAndSize(inval, invallen);
122 if (key == NULL((void *)0) || val == NULL((void *)0)) {
123 /* XXX error -- don't know how to handle */
124 PyErr_Clear();
125 Py_XDECREF(key)do { if ((key) == ((void *)0)) ; else do { if (_Py_RefTotal--
, --((PyObject*)(key))->ob_refcnt != 0) { if (((PyObject*
)key)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c"
, 125, (PyObject *)(key)); } else _Py_Dealloc((PyObject *)(key
)); } while (0); } while (0)
;
126 Py_XDECREF(val)do { if ((val) == ((void *)0)) ; else do { if (_Py_RefTotal--
, --((PyObject*)(val))->ob_refcnt != 0) { if (((PyObject*
)val)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c"
, 126, (PyObject *)(val)); } else _Py_Dealloc((PyObject *)(val
)); } while (0); } while (0)
;
127 indata->state = PyEval_SaveThread();
128 return 1;
129 }
130 err = PyDict_SetItem(indata->dict, key, val);
131 Py_DECREF(key)do { if (_Py_RefTotal-- , --((PyObject*)(key))->ob_refcnt !=
0) { if (((PyObject*)key)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c", 131,
(PyObject *)(key)); } else _Py_Dealloc((PyObject *)(key)); }
while (0)
;
132 Py_DECREF(val)do { if (_Py_RefTotal-- , --((PyObject*)(val))->ob_refcnt !=
0) { if (((PyObject*)val)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c", 132,
(PyObject *)(val)); } else _Py_Dealloc((PyObject *)(val)); }
while (0)
;
133 if (err != 0)
134 PyErr_Clear();
135 indata->state = PyEval_SaveThread();
136 if (err != 0)
137 return 1;
138 return 0;
139 }
140 return 1;
141}
142
143static PyObject *
144nis_get_default_domain (PyObject *self)
145{
146 char *domain;
147 int err;
148 PyObject *res;
149
150 if ((err = yp_get_default_domain(&domain)) != 0)
151 return nis_error(err);
152
153 res = PyUnicode_FromStringAndSizePyUnicodeUCS2_FromStringAndSize (domain, strlen(domain));
154 return res;
155}
156
157static PyObject *
158nis_match (PyObject *self, PyObject *args, PyObject *kwdict)
159{
160 char *match;
161 char *domain = NULL((void *)0);
162 Py_ssize_t keylen;
163 int len;
164 char *key, *map;
165 int err;
166 PyObject *ukey, *bkey, *res;
167 int fix;
168 static char *kwlist[] = {"key", "map", "domain", NULL((void *)0)};
169
170 if (!PyArg_ParseTupleAndKeywords(args, kwdict,
171 "Us|s:match", kwlist,
172 &ukey, &map, &domain))
173 return NULL((void *)0);
174 if ((bkey = PyUnicode_EncodeFSDefault(ukey)) == NULL((void *)0))
175 return NULL((void *)0);
176 if (PyBytes_AsStringAndSize(bkey, &key, &keylen) == -1) {
177 Py_DECREF(bkey)do { if (_Py_RefTotal-- , --((PyObject*)(bkey))->ob_refcnt
!= 0) { if (((PyObject*)bkey)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c", 177,
(PyObject *)(bkey)); } else _Py_Dealloc((PyObject *)(bkey));
} while (0)
;
178 return NULL((void *)0);
179 }
180 if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) {
181 Py_DECREF(bkey)do { if (_Py_RefTotal-- , --((PyObject*)(bkey))->ob_refcnt
!= 0) { if (((PyObject*)bkey)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c", 181,
(PyObject *)(bkey)); } else _Py_Dealloc((PyObject *)(bkey));
} while (0)
;
182 return nis_error(err);
183 }
184 map = nis_mapname (map, &fix);
185 if (fix)
186 keylen++;
187 Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread();
188 err = yp_match (domain, map, key, keylen, &match, &len);
189 Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); }
190 Py_DECREF(bkey)do { if (_Py_RefTotal-- , --((PyObject*)(bkey))->ob_refcnt
!= 0) { if (((PyObject*)bkey)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c", 190,
(PyObject *)(bkey)); } else _Py_Dealloc((PyObject *)(bkey));
} while (0)
;
191 if (fix)
192 len--;
193 if (err != 0)
194 return nis_error(err);
195 res = PyUnicode_DecodeFSDefaultAndSizePyUnicodeUCS2_DecodeFSDefaultAndSize(match, len);
196 free (match);
197 return res;
198}
199
200static PyObject *
201nis_cat (PyObject *self, PyObject *args, PyObject *kwdict)
202{
203 char *domain = NULL((void *)0);
204 char *map;
205 struct ypall_callback cb;
206 struct ypcallback_data data;
207 PyObject *dict;
208 int err;
209 static char *kwlist[] = {"map", "domain", NULL((void *)0)};
210
211 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|s:cat",
212 kwlist, &map, &domain))
213 return NULL((void *)0);
214 if (!domain && ((err = yp_get_default_domain(&domain)) != 0))
215 return nis_error(err);
216 dict = PyDict_New ();
217 if (dict == NULL((void *)0))
218 return NULL((void *)0);
219 cb.foreach = (foreachfunc)nis_foreach;
220 data.dict = dict;
221 map = nis_mapname (map, &data.fix);
222 cb.data = (char *)&data;
223 data.state = PyEval_SaveThread();
224 err = yp_all (domain, map, &cb);
225 PyEval_RestoreThread(data.state);
226 if (err != 0) {
227 Py_DECREF(dict)do { if (_Py_RefTotal-- , --((PyObject*)(dict))->ob_refcnt
!= 0) { if (((PyObject*)dict)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c", 227,
(PyObject *)(dict)); } else _Py_Dealloc((PyObject *)(dict));
} while (0)
;
228 return nis_error(err);
229 }
230 return dict;
231}
232
233/* These should be u_long on Sun h/w but not on 64-bit h/w.
234 This is not portable to machines with 16-bit ints and no prototypes */
235#ifndef YPPROC_MAPLIST((unsigned long)11)
236#define YPPROC_MAPLIST((unsigned long)11) 11
237#endif
238#ifndef YPPROG((unsigned long)100004)
239#define YPPROG((unsigned long)100004) 100004
240#endif
241#ifndef YPVERS((unsigned long)2)
242#define YPVERS((unsigned long)2) 2
243#endif
244
245typedef char *domainname;
246typedef char *mapname;
247
248enum nisstat {
249 NIS_TRUE = 1,
250 NIS_NOMORE = 2,
251 NIS_FALSE = 0,
252 NIS_NOMAP = -1,
253 NIS_NODOM = -2,
254 NIS_NOKEY = -3,
255 NIS_BADOP = -4,
256 NIS_BADDB = -5,
257 NIS_YPERR = -6,
258 NIS_BADARGS = -7,
259 NIS_VERS = -8
260};
261typedef enum nisstat nisstat;
262
263struct nismaplist {
264 mapname map;
265 struct nismaplist *next;
266};
267typedef struct nismaplist nismaplist;
268
269struct nisresp_maplist {
270 nisstat stat;
271 nismaplist *maps;
272};
273typedef struct nisresp_maplist nisresp_maplist;
274
275static struct timeval TIMEOUT = { 25, 0 };
276
277static
278bool_tint
279nis_xdr_domainname(XDR *xdrs, domainname *objp)
280{
281 if (!xdr_string(xdrs, objp, YPMAXDOMAIN((unsigned long)64))) {
282 return (FALSE(0));
283 }
284 return (TRUE(1));
285}
286
287static
288bool_tint
289nis_xdr_mapname(XDR *xdrs, mapname *objp)
290{
291 if (!xdr_string(xdrs, objp, YPMAXMAP((unsigned long)64))) {
292 return (FALSE(0));
293 }
294 return (TRUE(1));
295}
296
297static
298bool_tint
299nis_xdr_ypmaplist(XDR *xdrs, nismaplist *objp)
300{
301 if (!nis_xdr_mapname(xdrs, &objp->map)) {
302 return (FALSE(0));
303 }
304 if (!xdr_pointer(xdrs, (char **)&objp->next,
305 sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
306 {
307 return (FALSE(0));
308 }
309 return (TRUE(1));
310}
311
312static
313bool_tint
314nis_xdr_ypstat(XDR *xdrs, nisstat *objp)
315{
316 if (!xdr_enum(xdrs, (enum_tint *)objp)) {
317 return (FALSE(0));
318 }
319 return (TRUE(1));
320}
321
322
323static
324bool_tint
325nis_xdr_ypresp_maplist(XDR *xdrs, nisresp_maplist *objp)
326{
327 if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
328 return (FALSE(0));
329 }
330 if (!xdr_pointer(xdrs, (char **)&objp->maps,
331 sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
332 {
333 return (FALSE(0));
334 }
335 return (TRUE(1));
336}
337
338
339static
340nisresp_maplist *
341nisproc_maplist_2(domainname *argp, CLIENT *clnt)
342{
343 static nisresp_maplist res;
344
345 memset(&res, 0, sizeof(res))((__builtin_object_size (&res, 0) != (size_t) -1) ? __builtin___memset_chk
(&res, 0, sizeof(res), __builtin_object_size (&res, 0
)) : __inline_memset_chk (&res, 0, sizeof(res)))
;
346 if (clnt_call(clnt, YPPROC_MAPLIST,((*(clnt)->cl_ops->cl_call)(clnt, ((unsigned long)11), (
xdrproc_t)nis_xdr_domainname, (caddr_t)argp, (xdrproc_t)nis_xdr_ypresp_maplist
, (caddr_t)&res, TIMEOUT))
347 (xdrproc_t)nis_xdr_domainname, (caddr_t)argp,((*(clnt)->cl_ops->cl_call)(clnt, ((unsigned long)11), (
xdrproc_t)nis_xdr_domainname, (caddr_t)argp, (xdrproc_t)nis_xdr_ypresp_maplist
, (caddr_t)&res, TIMEOUT))
348 (xdrproc_t)nis_xdr_ypresp_maplist, (caddr_t)&res,((*(clnt)->cl_ops->cl_call)(clnt, ((unsigned long)11), (
xdrproc_t)nis_xdr_domainname, (caddr_t)argp, (xdrproc_t)nis_xdr_ypresp_maplist
, (caddr_t)&res, TIMEOUT))
349 TIMEOUT)((*(clnt)->cl_ops->cl_call)(clnt, ((unsigned long)11), (
xdrproc_t)nis_xdr_domainname, (caddr_t)argp, (xdrproc_t)nis_xdr_ypresp_maplist
, (caddr_t)&res, TIMEOUT))
!= RPC_SUCCESS)
350 {
351 return (NULL((void *)0));
352 }
353 return (&res);
354}
355
356static
357nismaplist *
358nis_maplist (char *dom)
359{
360 nisresp_maplist *list;
361 CLIENT *cl;
362 char *server = NULL((void *)0);
363 int mapi = 0;
364
365 while (!server && aliases[mapi].map != 0L) {
366 yp_master (dom, aliases[mapi].map, &server);
367 mapi++;
368 }
369 if (!server) {
370 PyErr_SetString(NisError, "No NIS master found for any map");
371 return NULL((void *)0);
372 }
373 cl = clnt_create(server, YPPROG((unsigned long)100004), YPVERS((unsigned long)2), "tcp");
374 if (cl == NULL((void *)0)) {
375 PyErr_SetString(NisError, clnt_spcreateerror(server));
376 goto finally;
377 }
378 list = nisproc_maplist_2 (&dom, cl);
379 clnt_destroy(cl)((*(cl)->cl_ops->cl_destroy)(cl));
380 if (list == NULL((void *)0))
381 goto finally;
382 if (list->stat != NIS_TRUE)
383 goto finally;
384
385 free(server);
386 return list->maps;
387
388 finally:
389 free(server);
390 return NULL((void *)0);
391}
392
393static PyObject *
394nis_maps (PyObject *self, PyObject *args, PyObject *kwdict)
395{
396 char *domain = NULL((void *)0);
397 nismaplist *maps;
398 PyObject *list;
399 int err;
400 static char *kwlist[] = {"domain", NULL((void *)0)};
401
402 if (!PyArg_ParseTupleAndKeywords(args, kwdict,
1
Taking false branch
403 "|s:maps", kwlist, &domain))
404 return NULL((void *)0);
405 if (!domain && ((err = yp_get_default_domain (&domain)) != 0)) {
2
Taking false branch
406 nis_error(err);
407 return NULL((void *)0);
408 }
409
410 if ((maps = nis_maplist (domain)) == NULL((void *)0))
3
Taking false branch
411 return NULL((void *)0);
412 if ((list = PyList_New(0)) == NULL((void *)0))
4
Taking false branch
413 return NULL((void *)0);
414 for (maps = maps; maps; maps = maps->next) {
5
Assigned value is always the same as the existing value
415 PyObject *str = PyUnicode_FromStringPyUnicodeUCS2_FromString(maps->map);
416 if (!str || PyList_Append(list, str) < 0)
417 {
418 Py_DECREF(list)do { if (_Py_RefTotal-- , --((PyObject*)(list))->ob_refcnt
!= 0) { if (((PyObject*)list)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c", 418,
(PyObject *)(list)); } else _Py_Dealloc((PyObject *)(list));
} while (0)
;
419 list = NULL((void *)0);
420 break;
421 }
422 Py_DECREF(str)do { if (_Py_RefTotal-- , --((PyObject*)(str))->ob_refcnt !=
0) { if (((PyObject*)str)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/nismodule.c", 422,
(PyObject *)(str)); } else _Py_Dealloc((PyObject *)(str)); }
while (0)
;
423 }
424 /* XXX Shouldn't we free the list of maps now? */
425 return list;
426}
427
428static PyMethodDef nis_methods[] = {
429 {"match", (PyCFunction)nis_match,
430 METH_VARARGS0x0001 | METH_KEYWORDS0x0002,
431 match__doc__},
432 {"cat", (PyCFunction)nis_cat,
433 METH_VARARGS0x0001 | METH_KEYWORDS0x0002,
434 cat__doc__},
435 {"maps", (PyCFunction)nis_maps,
436 METH_VARARGS0x0001 | METH_KEYWORDS0x0002,
437 maps__doc__},
438 {"get_default_domain", (PyCFunction)nis_get_default_domain,
439 METH_NOARGS0x0004,
440 get_default_domain__doc__},
441 {NULL((void *)0), NULL((void *)0)} /* Sentinel */
442};
443
444PyDoc_STRVAR(nis__doc__,static char nis__doc__[] = "This module contains functions for accessing NIS maps.\n"
445"This module contains functions for accessing NIS maps.\n")static char nis__doc__[] = "This module contains functions for accessing NIS maps.\n";
446
447static struct PyModuleDef nismodule = {
448 PyModuleDef_HEAD_INIT{ { 0, 0, 1, ((void *)0) }, ((void *)0), 0, ((void *)0), },
449 "nis",
450 nis__doc__,
451 -1,
452 nis_methods,
453 NULL((void *)0),
454 NULL((void *)0),
455 NULL((void *)0),
456 NULL((void *)0)
457};
458
459PyObject*
460PyInit_nis (void)
461{
462 PyObject *m, *d;
463 m = PyModule_Create(&nismodule)PyModule_Create2TraceRefs(&nismodule, 1013);
464 if (m == NULL((void *)0))
465 return NULL((void *)0);
466 d = PyModule_GetDict(m);
467 NisError = PyErr_NewException("nis.error", NULL((void *)0), NULL((void *)0));
468 if (NisError != NULL((void *)0))
469 PyDict_SetItemString(d, "error", NisError);
470 return m;
471}