LCOV - code coverage report
Current view: top level - python - pyglue.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 240 295 81.4 %
Date: 2023-11-21 12:31:41 Functions: 23 23 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
       4             :    Copyright (C) Matthias Dieter Wallnöfer          2009
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "lib/replace/system/python.h"
      21             : #include "python/py3compat.h"
      22             : #include "includes.h"
      23             : #include "python/modules.h"
      24             : #include "version.h"
      25             : #include "param/pyparam.h"
      26             : #include "lib/socket/netif.h"
      27             : #include "lib/util/debug.h"
      28             : #include "librpc/ndr/ndr_private.h"
      29             : #include "lib/cmdline/cmdline.h"
      30             : 
      31             : void init_glue(void);
      32             : static PyObject *PyExc_NTSTATUSError;
      33             : static PyObject *PyExc_WERRORError;
      34             : static PyObject *PyExc_HRESULTError;
      35             : static PyObject *PyExc_DsExtendedError;
      36             : 
      37           1 : static PyObject *py_generate_random_str(PyObject *self, PyObject *args)
      38             : {
      39           1 :         Py_ssize_t len;
      40           1 :         PyObject *ret;
      41           1 :         char *retstr;
      42             : 
      43           1 :         if (!PyArg_ParseTuple(args, "n", &len)) {
      44           0 :                 return NULL;
      45             :         }
      46           1 :         if (len < 0) {
      47           0 :                 PyErr_Format(PyExc_ValueError,
      48             :                              "random string length should be positive, not %zd",
      49             :                              len);
      50           0 :                 return NULL;
      51             :         }
      52           1 :         retstr = generate_random_str(NULL, len);
      53           1 :         if (retstr == NULL) {
      54           0 :                 return PyErr_NoMemory();
      55             :         }
      56           1 :         ret = PyUnicode_FromStringAndSize(retstr, len);
      57           1 :         talloc_free(retstr);
      58           1 :         return ret;
      59             : }
      60             : 
      61        3880 : static PyObject *py_generate_random_password(PyObject *self, PyObject *args)
      62             : {
      63          66 :         Py_ssize_t min, max;
      64          66 :         PyObject *ret;
      65          66 :         char *retstr;
      66             : 
      67        3880 :         if (!PyArg_ParseTuple(args, "nn", &min, &max)) {
      68           0 :                 return NULL;
      69             :         }
      70        3880 :         if (max < 0 || min < 0) {
      71             :                 /*
      72             :                  * The real range checks happens in generate_random_password().
      73             :                  * Here just filter out any negative numbers.
      74             :                  */
      75           0 :                 PyErr_Format(PyExc_ValueError,
      76             :                              "invalid range: %zd - %zd",
      77             :                              min, max);
      78           0 :                 return NULL;
      79             :         }
      80             : 
      81        3880 :         retstr = generate_random_password(NULL, min, max);
      82        3880 :         if (retstr == NULL) {
      83           0 :                 if (errno == EINVAL) {
      84           0 :                         return PyErr_Format(PyExc_ValueError,
      85             :                                             "invalid range: %zd - %zd",
      86             :                                             min, max);
      87             :                 }
      88           0 :                 return PyErr_NoMemory();
      89             :         }
      90        3880 :         ret = PyUnicode_FromString(retstr);
      91        3880 :         talloc_free(retstr);
      92        3880 :         return ret;
      93             : }
      94             : 
      95         482 : static PyObject *py_generate_random_machine_password(PyObject *self, PyObject *args)
      96             : {
      97          42 :         Py_ssize_t min, max;
      98          42 :         PyObject *ret;
      99          42 :         char *retstr;
     100             : 
     101         482 :         if (!PyArg_ParseTuple(args, "nn", &min, &max)) {
     102           0 :                 return NULL;
     103             :         }
     104         482 :         if (max < 0 || min < 0) {
     105             :                 /*
     106             :                  * The real range checks happens in
     107             :                  * generate_random_machine_password().
     108             :                  * Here we just filter out any negative numbers.
     109             :                  */
     110           0 :                 PyErr_Format(PyExc_ValueError,
     111             :                              "invalid range: %zd - %zd",
     112             :                              min, max);
     113           0 :                 return NULL;
     114             :         }
     115             : 
     116         482 :         retstr = generate_random_machine_password(NULL, min, max);
     117         482 :         if (retstr == NULL) {
     118           0 :                 if (errno == EINVAL) {
     119           0 :                         return PyErr_Format(PyExc_ValueError,
     120             :                                             "invalid range: %zd - %zd",
     121             :                                             min, max);
     122             :                 }
     123           0 :                 return PyErr_NoMemory();
     124             :         }
     125         482 :         ret = PyUnicode_FromString(retstr);
     126         482 :         talloc_free(retstr);
     127         482 :         return ret;
     128             : }
     129             : 
     130          69 : static PyObject *py_check_password_quality(PyObject *self, PyObject *args)
     131             : {
     132          17 :         char *pass;
     133             : 
     134          69 :         if (!PyArg_ParseTuple(args, "s", &pass)) {
     135           0 :                 return NULL;
     136             :         }
     137             : 
     138          69 :         return PyBool_FromLong(check_password_quality(pass));
     139             : }
     140             : 
     141       23787 : static PyObject *py_generate_random_bytes(PyObject *self, PyObject *args)
     142             : {
     143          23 :         Py_ssize_t len;
     144          23 :         PyObject *ret;
     145       23787 :         uint8_t *bytes = NULL;
     146             : 
     147       23787 :         if (!PyArg_ParseTuple(args, "n", &len)) {
     148           0 :                 return NULL;
     149             :         }
     150       23787 :         if (len < 0) {
     151           0 :                 PyErr_Format(PyExc_ValueError,
     152             :                              "random bytes length should be positive, not %zd",
     153             :                              len);
     154           0 :                 return NULL;
     155             :         }
     156       23787 :         bytes = talloc_zero_size(NULL, len);
     157       23787 :         if (bytes == NULL) {
     158           0 :                 PyErr_NoMemory();
     159           0 :                 return NULL;
     160             :         }
     161       23787 :         generate_random_buffer(bytes, len);
     162       23787 :         ret = PyBytes_FromStringAndSize((const char *)bytes, len);
     163       23787 :         talloc_free(bytes);
     164       23787 :         return ret;
     165             : }
     166             : 
     167         773 : static PyObject *py_unix2nttime(PyObject *self, PyObject *args)
     168             : {
     169          56 :         time_t t;
     170          56 :         unsigned int _t;
     171          56 :         NTTIME nt;
     172             : 
     173         773 :         if (!PyArg_ParseTuple(args, "I", &_t)) {
     174           0 :                 return NULL;
     175             :         }
     176         773 :         t = _t;
     177             : 
     178         773 :         unix_to_nt_time(&nt, t);
     179             : 
     180         773 :         return PyLong_FromLongLong((uint64_t)nt);
     181             : }
     182             : 
     183      198382 : static PyObject *py_nttime2unix(PyObject *self, PyObject *args)
     184             : {
     185         238 :         time_t t;
     186         238 :         NTTIME nt;
     187      198382 :         if (!PyArg_ParseTuple(args, "K", &nt))
     188           0 :                 return NULL;
     189             : 
     190      198382 :         t = nt_time_to_unix(nt);
     191             : 
     192      198382 :         return PyLong_FromLong((uint64_t)t);
     193             : }
     194             : 
     195           4 : static PyObject *py_float2nttime(PyObject *self, PyObject *args)
     196             : {
     197           4 :         double ft = 0;
     198           4 :         double ft_sec = 0;
     199           4 :         double ft_nsec = 0;
     200           4 :         struct timespec ts;
     201           4 :         NTTIME nt = 0;
     202             : 
     203           4 :         if (!PyArg_ParseTuple(args, "d", &ft)) {
     204           0 :                 return NULL;
     205             :         }
     206             : 
     207           4 :         ft_sec = (double)(int)ft;
     208           4 :         ft_nsec = (ft - ft_sec) * 1.0e+9;
     209             : 
     210           4 :         ts.tv_sec = (int)ft_sec;
     211           4 :         ts.tv_nsec = (int)ft_nsec;
     212             : 
     213           4 :         nt = full_timespec_to_nt_time(&ts);
     214             : 
     215           4 :         return PyLong_FromLongLong((uint64_t)nt);
     216             : }
     217             : 
     218         369 : static PyObject *py_nttime2float(PyObject *self, PyObject *args)
     219             : {
     220         369 :         double ft = 0;
     221           9 :         struct timespec ts;
     222         369 :         const struct timespec ts_zero = { .tv_sec = 0, };
     223         369 :         NTTIME nt = 0;
     224             : 
     225         369 :         if (!PyArg_ParseTuple(args, "K", &nt)) {
     226           0 :                 return NULL;
     227             :         }
     228             : 
     229         369 :         ts = nt_time_to_full_timespec(nt);
     230         369 :         if (is_omit_timespec(&ts)) {
     231           2 :                 return PyFloat_FromDouble(1.0);
     232             :         }
     233         367 :         ft = timespec_elapsed2(&ts_zero, &ts);
     234             : 
     235         367 :         return PyFloat_FromDouble(ft);
     236             : }
     237             : 
     238         241 : static PyObject *py_nttime2string(PyObject *self, PyObject *args)
     239             : {
     240           1 :         PyObject *ret;
     241           1 :         NTTIME nt;
     242           1 :         TALLOC_CTX *tmp_ctx;
     243           1 :         const char *string;
     244         241 :         if (!PyArg_ParseTuple(args, "K", &nt))
     245           0 :                 return NULL;
     246             : 
     247         241 :         tmp_ctx = talloc_new(NULL);
     248         241 :         if (tmp_ctx == NULL) {
     249           0 :                 PyErr_NoMemory();
     250           0 :                 return NULL;
     251             :         }
     252             : 
     253         241 :         string = nt_time_string(tmp_ctx, nt);
     254         241 :         ret =  PyUnicode_FromString(string);
     255             : 
     256         241 :         talloc_free(tmp_ctx);
     257             : 
     258         241 :         return ret;
     259             : }
     260             : 
     261        2029 : static PyObject *py_set_debug_level(PyObject *self, PyObject *args)
     262             : {
     263          14 :         unsigned level;
     264        2029 :         if (!PyArg_ParseTuple(args, "I", &level))
     265           0 :                 return NULL;
     266        2029 :         debuglevel_set(level);
     267        2029 :         Py_RETURN_NONE;
     268             : }
     269             : 
     270        2582 : static PyObject *py_get_debug_level(PyObject *self,
     271             :                 PyObject *Py_UNUSED(ignored))
     272             : {
     273        2582 :         return PyLong_FromLong(debuglevel_get());
     274             : }
     275             : 
     276       18308 : static PyObject *py_fault_setup(PyObject *self,
     277             :                 PyObject *Py_UNUSED(ignored))
     278             : {
     279         171 :         static bool done;
     280       18308 :         if (!done) {
     281        6905 :                 fault_setup();
     282        6905 :                 done = true;
     283             :         }
     284       18308 :         Py_RETURN_NONE;
     285             : }
     286             : 
     287        7372 : static PyObject *py_is_ntvfs_fileserver_built(PyObject *self,
     288             :                 PyObject *Py_UNUSED(ignored))
     289             : {
     290             : #ifdef WITH_NTVFS_FILESERVER
     291        6636 :         Py_RETURN_TRUE;
     292             : #else
     293         736 :         Py_RETURN_FALSE;
     294             : #endif
     295             : }
     296             : 
     297         237 : static PyObject *py_is_heimdal_built(PyObject *self,
     298             :                 PyObject *Py_UNUSED(ignored))
     299             : {
     300             : #ifdef SAMBA4_USES_HEIMDAL
     301         173 :         Py_RETURN_TRUE;
     302             : #else
     303          64 :         Py_RETURN_FALSE;
     304             : #endif
     305             : }
     306             : 
     307        1882 : static PyObject *py_is_ad_dc_built(PyObject *self,
     308             :                 PyObject *Py_UNUSED(ignored))
     309             : {
     310             : #ifdef AD_DC_BUILD_IS_ENABLED
     311        1698 :         Py_RETURN_TRUE;
     312             : #else
     313         184 :         Py_RETURN_FALSE;
     314             : #endif
     315             : }
     316             : 
     317        1843 : static PyObject *py_is_selftest_enabled(PyObject *self,
     318             :                 PyObject *Py_UNUSED(ignored))
     319             : {
     320             : #ifdef ENABLE_SELFTEST
     321        1843 :         Py_RETURN_TRUE;
     322             : #else
     323             :         Py_RETURN_FALSE;
     324             : #endif
     325             : }
     326             : 
     327           1 : static PyObject *py_ndr_token_max_list_size(PyObject *self,
     328             :                 PyObject *Py_UNUSED(ignored))
     329             : {
     330           1 :         return PyLong_FromLong(ndr_token_max_list_size());
     331             : }
     332             : 
     333             : /*
     334             :   return the list of interface IPs we have configured
     335             :   takes an loadparm context, returns a list of IPs in string form
     336             : 
     337             :   Does not return addresses on 127.0.0.0/8
     338             :  */
     339         537 : static PyObject *py_interface_ips(PyObject *self, PyObject *args)
     340             : {
     341          46 :         PyObject *pylist;
     342          46 :         int count;
     343          46 :         TALLOC_CTX *tmp_ctx;
     344          46 :         PyObject *py_lp_ctx;
     345          46 :         struct loadparm_context *lp_ctx;
     346          46 :         struct interface *ifaces;
     347          46 :         int i, ifcount;
     348         537 :         int all_interfaces = 1;
     349             : 
     350         537 :         if (!PyArg_ParseTuple(args, "O|i", &py_lp_ctx, &all_interfaces))
     351           0 :                 return NULL;
     352             : 
     353         537 :         tmp_ctx = talloc_new(NULL);
     354         537 :         if (tmp_ctx == NULL) {
     355           0 :                 PyErr_NoMemory();
     356           0 :                 return NULL;
     357             :         }
     358             : 
     359         537 :         lp_ctx = lpcfg_from_py_object(tmp_ctx, py_lp_ctx);
     360         537 :         if (lp_ctx == NULL) {
     361           0 :                 talloc_free(tmp_ctx);
     362           0 :                 return PyErr_NoMemory();
     363             :         }
     364             : 
     365         537 :         load_interface_list(tmp_ctx, lp_ctx, &ifaces);
     366             : 
     367         537 :         count = iface_list_count(ifaces);
     368             : 
     369             :         /* first count how many are not loopback addresses */
     370        2777 :         for (ifcount = i = 0; i<count; i++) {
     371        2194 :                 const char *ip = iface_list_n_ip(ifaces, i);
     372             : 
     373        2194 :                 if (all_interfaces) {
     374         284 :                         ifcount++;
     375         284 :                         continue;
     376             :                 }
     377             : 
     378        1910 :                 if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) {
     379           0 :                         continue;
     380             :                 }
     381             : 
     382        1910 :                 if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) {
     383           0 :                         continue;
     384             :                 }
     385             : 
     386        1910 :                 if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) {
     387           0 :                         continue;
     388             :                 }
     389             : 
     390        1910 :                 if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) {
     391           0 :                         continue;
     392             :                 }
     393             : 
     394        1910 :                 ifcount++;
     395             :         }
     396             : 
     397         537 :         pylist = PyList_New(ifcount);
     398        2777 :         for (ifcount = i = 0; i<count; i++) {
     399        2194 :                 const char *ip = iface_list_n_ip(ifaces, i);
     400             : 
     401        2194 :                 if (all_interfaces) {
     402         284 :                         PyList_SetItem(pylist, ifcount, PyUnicode_FromString(ip));
     403         284 :                         ifcount++;
     404         284 :                         continue;
     405             :                 }
     406             : 
     407        1910 :                 if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) {
     408           0 :                         continue;
     409             :                 }
     410             : 
     411        1910 :                 if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) {
     412           0 :                         continue;
     413             :                 }
     414             : 
     415        1910 :                 if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) {
     416           0 :                         continue;
     417             :                 }
     418             : 
     419        1910 :                 if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) {
     420           0 :                         continue;
     421             :                 }
     422             : 
     423        1910 :                 PyList_SetItem(pylist, ifcount, PyUnicode_FromString(ip));
     424        1910 :                 ifcount++;
     425             :         }
     426         537 :         talloc_free(tmp_ctx);
     427         537 :         return pylist;
     428             : }
     429             : 
     430          17 : static PyObject *py_strcasecmp_m(PyObject *self, PyObject *args)
     431             : {
     432          17 :         const char *s1 = NULL;
     433          17 :         const char *s2 = NULL;
     434          17 :         long cmp_result = 0;
     435          17 :         if (!PyArg_ParseTuple(args, PYARG_STR_UNI
     436             :                               PYARG_STR_UNI,
     437             :                               "utf8", &s1, "utf8", &s2)) {
     438           0 :                 return NULL;
     439             :         }
     440             : 
     441          17 :         cmp_result = strcasecmp_m(s1, s2);
     442          17 :         PyMem_Free(discard_const_p(char, s1));
     443          17 :         PyMem_Free(discard_const_p(char, s2));
     444          17 :         return PyLong_FromLong(cmp_result);
     445             : }
     446             : 
     447          28 : static PyObject *py_strstr_m(PyObject *self, PyObject *args)
     448             : {
     449          28 :         const char *s1 = NULL;
     450          28 :         const char *s2 = NULL;
     451          28 :         char *strstr_ret = NULL;
     452          28 :         PyObject *result = NULL;
     453          28 :         if (!PyArg_ParseTuple(args, PYARG_STR_UNI
     454             :                               PYARG_STR_UNI,
     455             :                               "utf8", &s1, "utf8", &s2))
     456           0 :                 return NULL;
     457             : 
     458          28 :         strstr_ret = strstr_m(s1, s2);
     459          28 :         if (!strstr_ret) {
     460          13 :                 PyMem_Free(discard_const_p(char, s1));
     461          13 :                 PyMem_Free(discard_const_p(char, s2));
     462          13 :                 Py_RETURN_NONE;
     463             :         }
     464          15 :         result = PyUnicode_FromString(strstr_ret);
     465          15 :         PyMem_Free(discard_const_p(char, s1));
     466          15 :         PyMem_Free(discard_const_p(char, s2));
     467          15 :         return result;
     468             : }
     469             : 
     470       18308 : static PyObject *py_get_burnt_commandline(PyObject *self, PyObject *args)
     471             : {
     472         171 :         PyObject *cmdline_as_list, *ret;
     473       18308 :         char *burnt_cmdline = NULL;
     474         171 :         Py_ssize_t i, argc;
     475       18308 :         char **argv = NULL;
     476       18308 :         TALLOC_CTX *frame = talloc_stackframe();
     477         171 :         bool burnt;
     478             : 
     479       18308 :         if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &cmdline_as_list))
     480             :         {
     481           0 :                 TALLOC_FREE(frame);
     482           0 :                 return NULL;
     483             :         }
     484             : 
     485       18308 :         argc = PyList_GET_SIZE(cmdline_as_list);
     486             : 
     487       18308 :         if (argc == 0) {
     488           0 :                 TALLOC_FREE(frame);
     489           0 :                 Py_RETURN_NONE;
     490             :         }
     491             : 
     492       18308 :         argv = PyList_AsStringList(frame, cmdline_as_list, "sys.argv");
     493       18308 :         if (argv == NULL) {
     494           0 :                 TALLOC_FREE(frame);
     495           0 :                 return NULL;
     496             :         }
     497             : 
     498       18308 :         burnt = samba_cmdline_burn(argc, argv);
     499       18308 :         if (!burnt) {
     500       15136 :                 TALLOC_FREE(frame);
     501       15136 :                 Py_RETURN_NONE;
     502             :         }
     503             : 
     504       17969 :         for (i = 0; i < argc; i++) {
     505       14797 :                 if (i == 0) {
     506        3172 :                         burnt_cmdline = talloc_strdup(frame,
     507        3172 :                                                       argv[i]);
     508             :                 } else {
     509          30 :                         burnt_cmdline
     510       11625 :                                 = talloc_asprintf_append(burnt_cmdline,
     511             :                                                          " %s",
     512       11625 :                                                          argv[i]);
     513             :                 }
     514       14797 :                 if (burnt_cmdline == NULL) {
     515           0 :                         PyErr_NoMemory();
     516           0 :                         TALLOC_FREE(frame);
     517           0 :                         return NULL;
     518             :                 }
     519             :         }
     520             : 
     521        3172 :         ret = PyUnicode_FromString(burnt_cmdline);
     522        3172 :         TALLOC_FREE(frame);
     523             : 
     524        3166 :         return ret;
     525             : }
     526             : 
     527             : static PyMethodDef py_misc_methods[] = {
     528             :         { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
     529             :                 "generate_random_str(len) -> string\n"
     530             :                 "Generate random string with specified length." },
     531             :         { "generate_random_password", (PyCFunction)py_generate_random_password,
     532             :                 METH_VARARGS, "generate_random_password(min, max) -> string\n"
     533             :                 "Generate random password (based on printable ascii characters) "
     534             :                 "with a length >= min and <= max." },
     535             :         { "generate_random_machine_password", (PyCFunction)py_generate_random_machine_password,
     536             :                 METH_VARARGS, "generate_random_machine_password(min, max) -> string\n"
     537             :                 "Generate random password "
     538             :                 "(based on random utf16 characters converted to utf8 or "
     539             :                 "random ascii characters if 'unix charset' is not 'utf8') "
     540             :                 "with a length >= min (at least 14) and <= max (at most 255)." },
     541             :         { "check_password_quality", (PyCFunction)py_check_password_quality,
     542             :                 METH_VARARGS, "check_password_quality(pass) -> bool\n"
     543             :                 "Check password quality against Samba's check_password_quality, "
     544             :                 "the implementation of Microsoft's rules: "
     545             :                 "http://msdn.microsoft.com/en-us/subscriptions/cc786468%28v=ws.10%29.aspx"
     546             :         },
     547             :         { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
     548             :                 "unix2nttime(timestamp) -> nttime" },
     549             :         { "nttime2unix", (PyCFunction)py_nttime2unix, METH_VARARGS,
     550             :                 "nttime2unix(nttime) -> timestamp" },
     551             :         { "float2nttime", (PyCFunction)py_float2nttime, METH_VARARGS,
     552             :                 "pytime2nttime(floattimestamp) -> nttime" },
     553             :         { "nttime2float", (PyCFunction)py_nttime2float, METH_VARARGS,
     554             :                 "nttime2pytime(nttime) -> floattimestamp" },
     555             :         { "nttime2string", (PyCFunction)py_nttime2string, METH_VARARGS,
     556             :                 "nttime2string(nttime) -> string" },
     557             :         { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
     558             :                 "set debug level" },
     559             :         { "get_debug_level", (PyCFunction)py_get_debug_level, METH_NOARGS,
     560             :                 "get debug level" },
     561             :         { "fault_setup", (PyCFunction)py_fault_setup, METH_NOARGS,
     562             :                 "setup the default samba panic handler" },
     563             :         { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
     564             :                 "interface_ips(lp_ctx[, all_interfaces) -> list_of_ifaces\n"
     565             :                 "\n"
     566             :                 "get interface IP address list"},
     567             :         { "strcasecmp_m", (PyCFunction)py_strcasecmp_m, METH_VARARGS,
     568             :                 "(for testing) compare two strings using Samba's strcasecmp_m()"},
     569             :         { "strstr_m", (PyCFunction)py_strstr_m, METH_VARARGS,
     570             :                 "(for testing) find one string in another with Samba's strstr_m()"},
     571             :         { "is_ntvfs_fileserver_built", (PyCFunction)py_is_ntvfs_fileserver_built, METH_NOARGS,
     572             :                 "is the NTVFS file server built in this installation?" },
     573             :         { "is_heimdal_built", (PyCFunction)py_is_heimdal_built, METH_NOARGS,
     574             :                 "is Samba built with Heimdal Kerberbos?" },
     575             :         { "generate_random_bytes",
     576             :                 (PyCFunction)py_generate_random_bytes,
     577             :                 METH_VARARGS,
     578             :                 "generate_random_bytes(len) -> bytes\n"
     579             :                 "Generate random bytes with specified length." },
     580             :         { "is_ad_dc_built", (PyCFunction)py_is_ad_dc_built, METH_NOARGS,
     581             :                 "is Samba built with AD DC?" },
     582             :         { "is_selftest_enabled", (PyCFunction)py_is_selftest_enabled,
     583             :                 METH_NOARGS, "is Samba built with selftest enabled?" },
     584             :         { "ndr_token_max_list_size", (PyCFunction)py_ndr_token_max_list_size,
     585             :                 METH_NOARGS, "How many NDR internal tokens is too many for this build?" },
     586             :         { "get_burnt_commandline", (PyCFunction)py_get_burnt_commandline,
     587             :                 METH_VARARGS, "Return a redacted commandline to feed to setproctitle (None if no redaction required)" },
     588             :         {0}
     589             : };
     590             : 
     591             : static struct PyModuleDef moduledef = {
     592             :     PyModuleDef_HEAD_INIT,
     593             :     .m_name = "_glue",
     594             :     .m_doc = "Python bindings for miscellaneous Samba functions.",
     595             :     .m_size = -1,
     596             :     .m_methods = py_misc_methods,
     597             : };
     598             : 
     599       12541 : MODULE_INIT_FUNC(_glue)
     600             : {
     601         531 :         PyObject *m;
     602             : 
     603       12541 :         debug_setup_talloc_log();
     604             : 
     605       12541 :         m = PyModule_Create(&moduledef);
     606       12541 :         if (m == NULL)
     607           0 :                 return NULL;
     608             : 
     609       12541 :         PyModule_AddObject(m, "version",
     610             :                                            PyUnicode_FromString(SAMBA_VERSION_STRING));
     611       12541 :         PyExc_NTSTATUSError = PyErr_NewException(discard_const_p(char, "samba.NTSTATUSError"), PyExc_RuntimeError, NULL);
     612       12541 :         if (PyExc_NTSTATUSError != NULL) {
     613       12541 :                 Py_INCREF(PyExc_NTSTATUSError);
     614       12541 :                 PyModule_AddObject(m, "NTSTATUSError", PyExc_NTSTATUSError);
     615             :         }
     616             : 
     617       12541 :         PyExc_WERRORError = PyErr_NewException(discard_const_p(char, "samba.WERRORError"), PyExc_RuntimeError, NULL);
     618       12541 :         if (PyExc_WERRORError != NULL) {
     619       12541 :                 Py_INCREF(PyExc_WERRORError);
     620       12541 :                 PyModule_AddObject(m, "WERRORError", PyExc_WERRORError);
     621             :         }
     622             : 
     623       12541 :         PyExc_HRESULTError = PyErr_NewException(discard_const_p(char, "samba.HRESULTError"), PyExc_RuntimeError, NULL);
     624       12541 :         if (PyExc_HRESULTError != NULL) {
     625       12541 :                 Py_INCREF(PyExc_HRESULTError);
     626       12541 :                 PyModule_AddObject(m, "HRESULTError", PyExc_HRESULTError);
     627             :         }
     628             : 
     629       12541 :         PyExc_DsExtendedError = PyErr_NewException(discard_const_p(char, "samba.DsExtendedError"), PyExc_RuntimeError, NULL);
     630       12541 :         if (PyExc_DsExtendedError != NULL) {
     631       12541 :                 Py_INCREF(PyExc_DsExtendedError);
     632       12541 :                 PyModule_AddObject(m, "DsExtendedError", PyExc_DsExtendedError);
     633             :         }
     634             : 
     635       12010 :         return m;
     636             : }

Generated by: LCOV version 1.14