LCOV - code coverage report
Current view: top level - Modules - nismodule.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 32 190 16.8 %
Date: 2022-07-20 13:12:14 Functions: 8 20 40.0 %
Branches: 10 110 9.1 %

           Branch data     Line data    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 <stdlib.h>               // free()
      16                 :            : #include <sys/time.h>
      17                 :            : #include <sys/types.h>
      18                 :            : #include <rpc/rpc.h>
      19                 :            : #include <rpcsvc/yp_prot.h>
      20                 :            : #include <rpcsvc/ypclnt.h>
      21                 :            : 
      22                 :            : #ifdef __sgi
      23                 :            : /* This is missing from rpcsvc/ypclnt.h */
      24                 :            : extern int yp_get_default_domain(char **);
      25                 :            : #endif
      26                 :            : 
      27                 :            : PyDoc_STRVAR(get_default_domain__doc__,
      28                 :            : "get_default_domain() -> str\n\
      29                 :            : Corresponds to the C library yp_get_default_domain() call, returning\n\
      30                 :            : the default NIS domain.\n");
      31                 :            : 
      32                 :            : PyDoc_STRVAR(match__doc__,
      33                 :            : "match(key, map, domain = defaultdomain)\n\
      34                 :            : Corresponds to the C library yp_match() call, returning the value of\n\
      35                 :            : key in the given map. Optionally domain can be specified but it\n\
      36                 :            : defaults to the system default domain.\n");
      37                 :            : 
      38                 :            : PyDoc_STRVAR(cat__doc__,
      39                 :            : "cat(map, domain = defaultdomain)\n\
      40                 :            : Returns the entire map as a dictionary. Optionally domain can be\n\
      41                 :            : specified but it defaults to the system default domain.\n");
      42                 :            : 
      43                 :            : PyDoc_STRVAR(maps__doc__,
      44                 :            : "maps(domain = defaultdomain)\n\
      45                 :            : Returns an array of all available NIS maps within a domain. If domain\n\
      46                 :            : is not specified it defaults to the system default domain.\n");
      47                 :            : 
      48                 :            : typedef struct {
      49                 :            :     PyObject *nis_error;
      50                 :            : } nis_state;
      51                 :            : 
      52                 :            : static inline nis_state*
      53                 :         65 : get_nis_state(PyObject *module)
      54                 :            : {
      55                 :         65 :     void *state = PyModule_GetState(module);
      56                 :            :     assert(state != NULL);
      57                 :         65 :     return (nis_state *)state;
      58                 :            : }
      59                 :            : 
      60                 :            : static int
      61                 :          4 : nis_clear(PyObject *m)
      62                 :            : {
      63         [ +  + ]:          4 :     Py_CLEAR(get_nis_state(m)->nis_error);
      64                 :          4 :     return 0;
      65                 :            : }
      66                 :            : 
      67                 :            : static int
      68                 :         28 : nis_traverse(PyObject *m, visitproc visit, void *arg)
      69                 :            : {
      70   [ +  -  -  + ]:         28 :     Py_VISIT(get_nis_state(m)->nis_error);
      71                 :         28 :     return 0;
      72                 :            : }
      73                 :            : 
      74                 :            : static void
      75                 :          2 : nis_free(void *m)
      76                 :            : {
      77                 :          2 :     nis_clear((PyObject *) m);
      78                 :          2 : }
      79                 :            : 
      80                 :            : static PyObject *
      81                 :          1 : nis_error(nis_state *state, int err)
      82                 :            : {
      83                 :          1 :     PyErr_SetString(state->nis_error, yperr_string(err));
      84                 :          1 :     return NULL;
      85                 :            : }
      86                 :            : 
      87                 :            : static struct nis_map {
      88                 :            :     char *alias;
      89                 :            :     char *map;
      90                 :            :     int  fix;
      91                 :            : } aliases [] = {
      92                 :            :     {"passwd",          "passwd.byname",        0},
      93                 :            :     {"group",           "group.byname",         0},
      94                 :            :     {"networks",        "networks.byaddr",      0},
      95                 :            :     {"hosts",           "hosts.byname",         0},
      96                 :            :     {"protocols",       "protocols.bynumber",   0},
      97                 :            :     {"services",        "services.byname",      0},
      98                 :            :     {"aliases",         "mail.aliases",         1}, /* created with 'makedbm -a' */
      99                 :            :     {"ethers",          "ethers.byname",        0},
     100                 :            :     {0L,                0L,                     0}
     101                 :            : };
     102                 :            : 
     103                 :            : static char *
     104                 :          0 : nis_mapname(char *map, int *pfix)
     105                 :            : {
     106                 :            :     int i;
     107                 :            : 
     108                 :          0 :     *pfix = 0;
     109         [ #  # ]:          0 :     for (i=0; aliases[i].alias != 0L; i++) {
     110   [ #  #  #  # ]:          0 :         if (!strcmp (aliases[i].alias, map) || !strcmp (aliases[i].map, map)) {
     111                 :          0 :             *pfix = aliases[i].fix;
     112                 :          0 :             return aliases[i].map;
     113                 :            :         }
     114                 :            :     }
     115                 :            : 
     116                 :          0 :     return map;
     117                 :            : }
     118                 :            : 
     119                 :            : #if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__)
     120                 :            : typedef int (*foreachfunc)(unsigned long, char *, int, char *, int, void *);
     121                 :            : #else
     122                 :            : typedef int (*foreachfunc)(int, char *, int, char *, int, char *);
     123                 :            : #endif
     124                 :            : 
     125                 :            : struct ypcallback_data {
     126                 :            :     PyObject            *dict;
     127                 :            :     int                         fix;
     128                 :            :     PyThreadState *state;
     129                 :            : };
     130                 :            : 
     131                 :            : static int
     132                 :          0 : nis_foreach(int instatus, char *inkey, int inkeylen, char *inval,
     133                 :            :              int invallen, struct ypcallback_data *indata)
     134                 :            : {
     135         [ #  # ]:          0 :     if (instatus == YP_TRUE) {
     136                 :            :         PyObject *key;
     137                 :            :         PyObject *val;
     138                 :            :         int err;
     139                 :            : 
     140                 :          0 :         PyEval_RestoreThread(indata->state);
     141         [ #  # ]:          0 :         if (indata->fix) {
     142   [ #  #  #  # ]:          0 :             if (inkeylen > 0 && inkey[inkeylen-1] == '\0')
     143                 :          0 :             inkeylen--;
     144   [ #  #  #  # ]:          0 :             if (invallen > 0 && inval[invallen-1] == '\0')
     145                 :          0 :             invallen--;
     146                 :            :         }
     147                 :          0 :         key = PyUnicode_DecodeFSDefaultAndSize(inkey, inkeylen);
     148                 :          0 :         val = PyUnicode_DecodeFSDefaultAndSize(inval, invallen);
     149   [ #  #  #  # ]:          0 :         if (key == NULL || val == NULL) {
     150                 :            :             /* XXX error -- don't know how to handle */
     151                 :          0 :             PyErr_Clear();
     152                 :          0 :             Py_XDECREF(key);
     153                 :          0 :             Py_XDECREF(val);
     154                 :          0 :             indata->state = PyEval_SaveThread();
     155                 :          0 :             return 1;
     156                 :            :         }
     157                 :          0 :         err = PyDict_SetItem(indata->dict, key, val);
     158                 :          0 :         Py_DECREF(key);
     159                 :          0 :         Py_DECREF(val);
     160         [ #  # ]:          0 :         if (err != 0)
     161                 :          0 :             PyErr_Clear();
     162                 :          0 :         indata->state = PyEval_SaveThread();
     163         [ #  # ]:          0 :         if (err != 0)
     164                 :          0 :             return 1;
     165                 :          0 :         return 0;
     166                 :            :     }
     167                 :          0 :     return 1;
     168                 :            : }
     169                 :            : 
     170                 :            : static PyObject *
     171                 :          0 : nis_get_default_domain(PyObject *module, PyObject *Py_UNUSED(ignored))
     172                 :            : {
     173                 :            :     char *domain;
     174                 :            :     int err;
     175                 :            :     PyObject *res;
     176                 :          0 :     nis_state *state = get_nis_state(module);
     177         [ #  # ]:          0 :     if ((err = yp_get_default_domain(&domain)) != 0) {
     178                 :          0 :         return nis_error(state, err);
     179                 :            :     }
     180                 :            : 
     181                 :          0 :     res = PyUnicode_FromStringAndSize (domain, strlen(domain));
     182                 :          0 :     return res;
     183                 :            : }
     184                 :            : 
     185                 :            : static PyObject *
     186                 :          0 : nis_match(PyObject *module, PyObject *args, PyObject *kwdict)
     187                 :            : {
     188                 :            :     char *match;
     189                 :          0 :     char *domain = NULL;
     190                 :            :     Py_ssize_t keylen;
     191                 :            :     int len;
     192                 :            :     char *key, *map;
     193                 :            :     int err;
     194                 :            :     PyObject *ukey, *bkey, *res;
     195                 :            :     int fix;
     196                 :            :     static char *kwlist[] = {"key", "map", "domain", NULL};
     197                 :            : 
     198         [ #  # ]:          0 :     if (!PyArg_ParseTupleAndKeywords(args, kwdict,
     199                 :            :                                      "Us|s:match", kwlist,
     200                 :            :                                      &ukey, &map, &domain)) {
     201                 :          0 :         return NULL;
     202                 :            :     }
     203         [ #  # ]:          0 :     if ((bkey = PyUnicode_EncodeFSDefault(ukey)) == NULL) {
     204                 :          0 :         return NULL;
     205                 :            :     }
     206                 :            :     /* check for embedded null bytes */
     207         [ #  # ]:          0 :     if (PyBytes_AsStringAndSize(bkey, &key, &keylen) == -1) {
     208                 :          0 :         Py_DECREF(bkey);
     209                 :          0 :         return NULL;
     210                 :            :     }
     211                 :            : 
     212                 :          0 :     nis_state *state = get_nis_state(module);
     213   [ #  #  #  # ]:          0 :     if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) {
     214                 :          0 :         Py_DECREF(bkey);
     215                 :          0 :         return nis_error(state, err);
     216                 :            :     }
     217                 :          0 :     map = nis_mapname (map, &fix);
     218         [ #  # ]:          0 :     if (fix)
     219                 :          0 :         keylen++;
     220                 :          0 :     Py_BEGIN_ALLOW_THREADS
     221                 :          0 :     err = yp_match (domain, map, key, keylen, &match, &len);
     222                 :          0 :     Py_END_ALLOW_THREADS
     223                 :          0 :     Py_DECREF(bkey);
     224         [ #  # ]:          0 :     if (fix)
     225                 :          0 :         len--;
     226         [ #  # ]:          0 :     if (err != 0) {
     227                 :          0 :         return nis_error(state, err);
     228                 :            :     }
     229                 :          0 :     res = PyUnicode_DecodeFSDefaultAndSize(match, len);
     230                 :          0 :     free (match);
     231                 :          0 :     return res;
     232                 :            : }
     233                 :            : 
     234                 :            : static PyObject *
     235                 :          0 : nis_cat(PyObject *module, PyObject *args, PyObject *kwdict)
     236                 :            : {
     237                 :          0 :     char *domain = NULL;
     238                 :            :     char *map;
     239                 :            :     struct ypall_callback cb;
     240                 :            :     struct ypcallback_data data;
     241                 :            :     PyObject *dict;
     242                 :            :     int err;
     243                 :            :     static char *kwlist[] = {"map", "domain", NULL};
     244                 :            : 
     245         [ #  # ]:          0 :     if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|s:cat",
     246                 :            :                                      kwlist, &map, &domain)) {
     247                 :          0 :         return NULL;
     248                 :            :     }
     249                 :          0 :     nis_state *state = get_nis_state(module);
     250   [ #  #  #  # ]:          0 :     if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) {
     251                 :          0 :         return nis_error(state, err);
     252                 :            :     }
     253                 :          0 :     dict = PyDict_New ();
     254         [ #  # ]:          0 :     if (dict == NULL)
     255                 :          0 :         return NULL;
     256                 :          0 :     cb.foreach = (foreachfunc)nis_foreach;
     257                 :          0 :     data.dict = dict;
     258                 :          0 :     map = nis_mapname (map, &data.fix);
     259                 :          0 :     cb.data = (char *)&data;
     260                 :          0 :     data.state = PyEval_SaveThread();
     261                 :          0 :     err = yp_all (domain, map, &cb);
     262                 :          0 :     PyEval_RestoreThread(data.state);
     263         [ #  # ]:          0 :     if (err != 0) {
     264                 :          0 :         Py_DECREF(dict);
     265                 :          0 :         return nis_error(state, err);
     266                 :            :     }
     267                 :          0 :     return dict;
     268                 :            : }
     269                 :            : 
     270                 :            : /* These should be u_long on Sun h/w but not on 64-bit h/w.
     271                 :            :    This is not portable to machines with 16-bit ints and no prototypes */
     272                 :            : #ifndef YPPROC_MAPLIST
     273                 :            : #define YPPROC_MAPLIST  11
     274                 :            : #endif
     275                 :            : #ifndef YPPROG
     276                 :            : #define YPPROG          100004
     277                 :            : #endif
     278                 :            : #ifndef YPVERS
     279                 :            : #define YPVERS          2
     280                 :            : #endif
     281                 :            : 
     282                 :            : typedef char *domainname;
     283                 :            : typedef char *mapname;
     284                 :            : 
     285                 :            : enum nisstat {
     286                 :            :     NIS_TRUE = 1,
     287                 :            :     NIS_NOMORE = 2,
     288                 :            :     NIS_FALSE = 0,
     289                 :            :     NIS_NOMAP = -1,
     290                 :            :     NIS_NODOM = -2,
     291                 :            :     NIS_NOKEY = -3,
     292                 :            :     NIS_BADOP = -4,
     293                 :            :     NIS_BADDB = -5,
     294                 :            :     NIS_YPERR = -6,
     295                 :            :     NIS_BADARGS = -7,
     296                 :            :     NIS_VERS = -8
     297                 :            : };
     298                 :            : typedef enum nisstat nisstat;
     299                 :            : 
     300                 :            : struct nismaplist {
     301                 :            :     mapname map;
     302                 :            :     struct nismaplist *next;
     303                 :            : };
     304                 :            : typedef struct nismaplist nismaplist;
     305                 :            : 
     306                 :            : struct nisresp_maplist {
     307                 :            :     nisstat stat;
     308                 :            :     nismaplist *maps;
     309                 :            : };
     310                 :            : typedef struct nisresp_maplist nisresp_maplist;
     311                 :            : 
     312                 :            : static struct timeval TIMEOUT = { 25, 0 };
     313                 :            : 
     314                 :            : static
     315                 :            : bool_t
     316                 :          0 : nis_xdr_domainname(XDR *xdrs, domainname *objp)
     317                 :            : {
     318         [ #  # ]:          0 :     if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
     319                 :          0 :         return (FALSE);
     320                 :            :     }
     321                 :          0 :     return (TRUE);
     322                 :            : }
     323                 :            : 
     324                 :            : static
     325                 :            : bool_t
     326                 :          0 : nis_xdr_mapname(XDR *xdrs, mapname *objp)
     327                 :            : {
     328         [ #  # ]:          0 :     if (!xdr_string(xdrs, objp, YPMAXMAP)) {
     329                 :          0 :         return (FALSE);
     330                 :            :     }
     331                 :          0 :     return (TRUE);
     332                 :            : }
     333                 :            : 
     334                 :            : static
     335                 :            : bool_t
     336                 :          0 : nis_xdr_ypmaplist(XDR *xdrs, nismaplist *objp)
     337                 :            : {
     338         [ #  # ]:          0 :     if (!nis_xdr_mapname(xdrs, &objp->map)) {
     339                 :          0 :         return (FALSE);
     340                 :            :     }
     341         [ #  # ]:          0 :     if (!xdr_pointer(xdrs, (char **)&objp->next,
     342                 :            :                      sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
     343                 :            :     {
     344                 :          0 :         return (FALSE);
     345                 :            :     }
     346                 :          0 :     return (TRUE);
     347                 :            : }
     348                 :            : 
     349                 :            : static
     350                 :            : bool_t
     351                 :          0 : nis_xdr_ypstat(XDR *xdrs, nisstat *objp)
     352                 :            : {
     353         [ #  # ]:          0 :     if (!xdr_enum(xdrs, (enum_t *)objp)) {
     354                 :          0 :         return (FALSE);
     355                 :            :     }
     356                 :          0 :     return (TRUE);
     357                 :            : }
     358                 :            : 
     359                 :            : 
     360                 :            : static
     361                 :            : bool_t
     362                 :          0 : nis_xdr_ypresp_maplist(XDR *xdrs, nisresp_maplist *objp)
     363                 :            : {
     364         [ #  # ]:          0 :     if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
     365                 :          0 :         return (FALSE);
     366                 :            :     }
     367         [ #  # ]:          0 :     if (!xdr_pointer(xdrs, (char **)&objp->maps,
     368                 :            :                      sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
     369                 :            :     {
     370                 :          0 :         return (FALSE);
     371                 :            :     }
     372                 :          0 :     return (TRUE);
     373                 :            : }
     374                 :            : 
     375                 :            : 
     376                 :            : static
     377                 :            : nisresp_maplist *
     378                 :          0 : nisproc_maplist_2(domainname *argp, CLIENT *clnt)
     379                 :            : {
     380                 :            :     static nisresp_maplist res;
     381                 :            : 
     382                 :          0 :     memset(&res, 0, sizeof(res));
     383         [ #  # ]:          0 :     if (clnt_call(clnt, YPPROC_MAPLIST,
     384                 :            :                   (xdrproc_t)nis_xdr_domainname, (caddr_t)argp,
     385                 :            :                   (xdrproc_t)nis_xdr_ypresp_maplist, (caddr_t)&res,
     386                 :            :                   TIMEOUT) != RPC_SUCCESS)
     387                 :            :     {
     388                 :          0 :         return (NULL);
     389                 :            :     }
     390                 :          0 :     return (&res);
     391                 :            : }
     392                 :            : 
     393                 :            : static
     394                 :            : nismaplist *
     395                 :          0 : nis_maplist(nis_state *state, char *dom)
     396                 :            : {
     397                 :            :     nisresp_maplist *list;
     398                 :            :     CLIENT *cl;
     399                 :          0 :     char *server = NULL;
     400                 :          0 :     int mapi = 0;
     401                 :            : 
     402   [ #  #  #  # ]:          0 :     while (!server && aliases[mapi].map != 0L) {
     403                 :          0 :         yp_master (dom, aliases[mapi].map, &server);
     404                 :          0 :         mapi++;
     405                 :            :     }
     406         [ #  # ]:          0 :     if (!server) {
     407                 :          0 :         PyErr_SetString(state->nis_error, "No NIS master found for any map");
     408                 :          0 :         return NULL;
     409                 :            :     }
     410                 :          0 :     cl = clnt_create(server, YPPROG, YPVERS, "tcp");
     411         [ #  # ]:          0 :     if (cl == NULL) {
     412                 :          0 :         PyErr_SetString(state->nis_error, clnt_spcreateerror(server));
     413                 :          0 :         goto finally;
     414                 :            :     }
     415                 :          0 :     list = nisproc_maplist_2 (&dom, cl);
     416                 :          0 :     clnt_destroy(cl);
     417         [ #  # ]:          0 :     if (list == NULL)
     418                 :          0 :         goto finally;
     419         [ #  # ]:          0 :     if (list->stat != NIS_TRUE)
     420                 :          0 :         goto finally;
     421                 :            : 
     422                 :          0 :     free(server);
     423                 :          0 :     return list->maps;
     424                 :            : 
     425                 :          0 :   finally:
     426                 :          0 :     free(server);
     427                 :          0 :     return NULL;
     428                 :            : }
     429                 :            : 
     430                 :            : static PyObject *
     431                 :          1 : nis_maps (PyObject *module, PyObject *args, PyObject *kwdict)
     432                 :            : {
     433                 :          1 :     char *domain = NULL;
     434                 :            :     nismaplist *maps;
     435                 :            :     PyObject *list;
     436                 :            :     int err;
     437                 :            :     static char *kwlist[] = {"domain", NULL};
     438                 :            : 
     439         [ -  + ]:          1 :     if (!PyArg_ParseTupleAndKeywords(args, kwdict,
     440                 :            :                                      "|s:maps", kwlist, &domain)) {
     441                 :          0 :         return NULL;
     442                 :            :     }
     443                 :            : 
     444                 :          1 :     nis_state *state = get_nis_state(module);
     445   [ +  -  +  - ]:          1 :     if (!domain && ((err = yp_get_default_domain (&domain)) != 0)) {
     446                 :          1 :         nis_error(state, err);
     447                 :          1 :         return NULL;
     448                 :            :     }
     449                 :            : 
     450         [ #  # ]:          0 :     if ((maps = nis_maplist(state, domain)) == NULL) {
     451                 :          0 :         return NULL;
     452                 :            :     }
     453         [ #  # ]:          0 :     if ((list = PyList_New(0)) == NULL) {
     454                 :          0 :         return NULL;
     455                 :            :     }
     456         [ #  # ]:          0 :     for (; maps; maps = maps->next) {
     457                 :          0 :         PyObject *str = PyUnicode_FromString(maps->map);
     458   [ #  #  #  # ]:          0 :         if (!str || PyList_Append(list, str) < 0)
     459                 :            :         {
     460                 :          0 :             Py_XDECREF(str);
     461                 :          0 :             Py_DECREF(list);
     462                 :          0 :             list = NULL;
     463                 :          0 :             break;
     464                 :            :         }
     465                 :          0 :         Py_DECREF(str);
     466                 :            :     }
     467                 :            :     /* XXX Shouldn't we free the list of maps now? */
     468                 :          0 :     return list;
     469                 :            : }
     470                 :            : 
     471                 :            : static PyMethodDef nis_methods[] = {
     472                 :            :     {"match",                   _PyCFunction_CAST(nis_match),
     473                 :            :                                     METH_VARARGS | METH_KEYWORDS,
     474                 :            :                                     match__doc__},
     475                 :            :     {"cat",                     _PyCFunction_CAST(nis_cat),
     476                 :            :                                     METH_VARARGS | METH_KEYWORDS,
     477                 :            :                                     cat__doc__},
     478                 :            :     {"maps",                    _PyCFunction_CAST(nis_maps),
     479                 :            :                                     METH_VARARGS | METH_KEYWORDS,
     480                 :            :                                     maps__doc__},
     481                 :            :     {"get_default_domain",      nis_get_default_domain,
     482                 :            :                                     METH_NOARGS,
     483                 :            :                                     get_default_domain__doc__},
     484                 :            :     {NULL,                      NULL}            /* Sentinel */
     485                 :            : };
     486                 :            : 
     487                 :            : static int
     488                 :          2 : nis_exec(PyObject *module)
     489                 :            : {
     490                 :          2 :     nis_state* state = get_nis_state(module);
     491                 :          2 :     state->nis_error = PyErr_NewException("nis.error", NULL, NULL);
     492         [ -  + ]:          2 :     if (state->nis_error == NULL) {
     493                 :          0 :         return -1;
     494                 :            :     }
     495                 :            : 
     496                 :          2 :     Py_INCREF(state->nis_error);
     497         [ -  + ]:          2 :     if (PyModule_AddObject(module, "error", state->nis_error) < 0) {
     498                 :          0 :         Py_DECREF(state->nis_error);
     499                 :          0 :         return -1;
     500                 :            :     }
     501                 :          2 :     return 0;
     502                 :            : }
     503                 :            : 
     504                 :            : static PyModuleDef_Slot nis_slots[] = {
     505                 :            :     {Py_mod_exec, nis_exec},
     506                 :            :     {0, NULL}
     507                 :            : };
     508                 :            : 
     509                 :            : PyDoc_STRVAR(nis__doc__,
     510                 :            : "This module contains functions for accessing NIS maps.\n");
     511                 :            : 
     512                 :            : static struct PyModuleDef nismodule = {
     513                 :            :     PyModuleDef_HEAD_INIT,
     514                 :            :     .m_name = "nis",
     515                 :            :     .m_doc = nis__doc__,
     516                 :            :     .m_size = sizeof(nis_state),
     517                 :            :     .m_methods = nis_methods,
     518                 :            :     .m_traverse = nis_traverse,
     519                 :            :     .m_clear = nis_clear,
     520                 :            :     .m_free = nis_free,
     521                 :            :     .m_slots = nis_slots,
     522                 :            : };
     523                 :            : 
     524                 :            : PyMODINIT_FUNC
     525                 :          2 : PyInit_nis(void)
     526                 :            : {
     527         [ -  + ]:          2 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
     528                 :            :                      "'nis' is deprecated and slated for removal in "
     529                 :            :                      "Python 3.13",
     530                 :            :                      7)) {
     531                 :          0 :         return NULL;
     532                 :            :     }
     533                 :          2 :     return PyModuleDef_Init(&nismodule);
     534                 :            : }

Generated by: LCOV version 1.14