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

Generated by: LCOV version 1.14