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

Generated by: LCOV version 1.14