LCOV - code coverage report
Current view: top level - python - pyglue.c (source / functions) Hit Total Coverage
Test: coverage report for recycleplus df22b230 Lines: 154 253 60.9 %
Date: 2024-02-14 10:14:15 Functions: 18 23 78.3 %

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

Generated by: LCOV version 1.14