CVE-2019-3880 s3: rpc: winreg: Remove implementations of SaveKey/RestoreKey.
[kai/samba-autobuild/.git] / python / pyglue.c
index 938a9f0ecf473c1b94726b3e37636b68e3c6489c..70e211606ffba29bf598631a57a7ddb3cdabd30e 100644 (file)
 */
 
 #include <Python.h>
+#include "python/py3compat.h"
 #include "includes.h"
 #include "version.h"
 #include "param/pyparam.h"
 #include "lib/socket/netif.h"
+#include "lib/util/debug.h"
 
 void init_glue(void);
 static PyObject *PyExc_NTSTATUSError;
 static PyObject *PyExc_WERRORError;
 static PyObject *PyExc_HRESULTError;
+static PyObject *PyExc_DsExtendedError;
 
 static PyObject *py_generate_random_str(PyObject *self, PyObject *args)
 {
@@ -37,7 +40,7 @@ static PyObject *py_generate_random_str(PyObject *self, PyObject *args)
                return NULL;
 
        retstr = generate_random_str(NULL, len);
-       ret = PyString_FromString(retstr);
+       ret = PyStr_FromString(retstr);
        talloc_free(retstr);
        return ret;
 }
@@ -54,11 +57,55 @@ static PyObject *py_generate_random_password(PyObject *self, PyObject *args)
        if (retstr == NULL) {
                return NULL;
        }
-       ret = PyString_FromString(retstr);
+       ret = PyStr_FromString(retstr);
        talloc_free(retstr);
        return ret;
 }
 
+static PyObject *py_generate_random_machine_password(PyObject *self, PyObject *args)
+{
+       int min, max;
+       PyObject *ret;
+       char *retstr;
+       if (!PyArg_ParseTuple(args, "ii", &min, &max))
+               return NULL;
+
+       retstr = generate_random_machine_password(NULL, min, max);
+       if (retstr == NULL) {
+               return NULL;
+       }
+       ret = PyUnicode_FromString(retstr);
+       talloc_free(retstr);
+       return ret;
+}
+
+static PyObject *py_check_password_quality(PyObject *self, PyObject *args)
+{
+       char *pass;
+
+       if (!PyArg_ParseTuple(args, "s", &pass)) {
+               return NULL;
+       }
+
+       return PyBool_FromLong(check_password_quality(pass));
+}
+
+static PyObject *py_generate_random_bytes(PyObject *self, PyObject *args)
+{
+       int len;
+       PyObject *ret;
+       uint8_t *bytes = NULL;
+
+       if (!PyArg_ParseTuple(args, "i", &len))
+               return NULL;
+
+       bytes = talloc_zero_size(NULL, len);
+       generate_random_buffer(bytes, len);
+       ret = PyBytes_FromStringAndSize((const char *)bytes, len);
+       talloc_free(bytes);
+       return ret;
+}
+
 static PyObject *py_unix2nttime(PyObject *self, PyObject *args)
 {
        time_t t;
@@ -103,7 +150,7 @@ static PyObject *py_nttime2string(PyObject *self, PyObject *args)
        }
 
        string = nt_time_string(tmp_ctx, nt);
-       ret =  PyString_FromString(string);
+       ret =  PyStr_FromString(string);
 
        talloc_free(tmp_ctx);
 
@@ -115,13 +162,23 @@ static PyObject *py_set_debug_level(PyObject *self, PyObject *args)
        unsigned level;
        if (!PyArg_ParseTuple(args, "I", &level))
                return NULL;
-       (DEBUGLEVEL) = level;
+       debuglevel_set(level);
        Py_RETURN_NONE;
 }
 
 static PyObject *py_get_debug_level(PyObject *self)
 {
-       return PyInt_FromLong(DEBUGLEVEL);
+       return PyInt_FromLong(debuglevel_get());
+}
+
+static PyObject *py_fault_setup(PyObject *self)
+{
+       static bool done;
+       if (!done) {
+               fault_setup();
+               done = true;
+       }
+       Py_RETURN_NONE;
 }
 
 static PyObject *py_is_ntvfs_fileserver_built(PyObject *self)
@@ -133,6 +190,15 @@ static PyObject *py_is_ntvfs_fileserver_built(PyObject *self)
 #endif
 }
 
+static PyObject *py_is_heimdal_built(PyObject *self)
+{
+#ifdef SAMBA4_USES_HEIMDAL
+       Py_RETURN_TRUE;
+#else
+       Py_RETURN_FALSE;
+#endif
+}
+
 /*
   return the list of interface IPs we have configured
   takes an loadparm context, returns a list of IPs in string form
@@ -202,7 +268,7 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args)
                const char *ip = iface_list_n_ip(ifaces, i);
 
                if (all_interfaces) {
-                       PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
+                       PyList_SetItem(pylist, ifcount, PyStr_FromString(ip));
                        ifcount++;
                        continue;
                }
@@ -223,7 +289,7 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args)
                        continue;
                }
 
-               PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
+               PyList_SetItem(pylist, ifcount, PyStr_FromString(ip));
                ifcount++;
        }
        talloc_free(tmp_ctx);
@@ -232,26 +298,42 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args)
 
 static PyObject *py_strcasecmp_m(PyObject *self, PyObject *args)
 {
-       char *s1, *s2;
-
-       if (!PyArg_ParseTuple(args, "ss", &s1, &s2))
+       const char *s1 = NULL;
+       const char *s2 = NULL;
+       long cmp_result = 0;
+       if (!PyArg_ParseTuple(args, PYARG_STR_UNI
+                             PYARG_STR_UNI,
+                             "utf8", &s1, "utf8", &s2)) {
                return NULL;
+       }
 
-       return PyInt_FromLong(strcasecmp_m(s1, s2));
+       cmp_result = strcasecmp_m(s1, s2);
+       PyMem_Free(discard_const_p(char, s1));
+       PyMem_Free(discard_const_p(char, s2));
+       return PyInt_FromLong(cmp_result);
 }
 
 static PyObject *py_strstr_m(PyObject *self, PyObject *args)
 {
-       char *s1, *s2, *ret;
-
-       if (!PyArg_ParseTuple(args, "ss", &s1, &s2))
+       const char *s1 = NULL;
+       const char *s2 = NULL;
+       char *strstr_ret = NULL;
+       PyObject *result = NULL;
+       if (!PyArg_ParseTuple(args, PYARG_STR_UNI
+                             PYARG_STR_UNI,
+                             "utf8", &s1, "utf8", &s2))
                return NULL;
 
-       ret = strstr_m(s1, s2);
-       if (!ret) {
+       strstr_ret = strstr_m(s1, s2);
+       if (!strstr_ret) {
+               PyMem_Free(discard_const_p(char, s1));
+               PyMem_Free(discard_const_p(char, s2));
                Py_RETURN_NONE;
        }
-       return PyString_FromString(ret);
+       result = PyUnicode_FromString(strstr_ret);
+       PyMem_Free(discard_const_p(char, s1));
+       PyMem_Free(discard_const_p(char, s2));
+       return result;
 }
 
 static PyMethodDef py_misc_methods[] = {
@@ -260,7 +342,20 @@ static PyMethodDef py_misc_methods[] = {
                "Generate random string with specified length." },
        { "generate_random_password", (PyCFunction)py_generate_random_password,
                METH_VARARGS, "generate_random_password(min, max) -> string\n"
-               "Generate random password with a length >= min and <= max." },
+               "Generate random password (based on printable ascii characters) "
+               "with a length >= min and <= max." },
+       { "generate_random_machine_password", (PyCFunction)py_generate_random_machine_password,
+               METH_VARARGS, "generate_random_machine_password(min, max) -> string\n"
+               "Generate random password "
+               "(based on random utf16 characters converted to utf8 or "
+               "random ascii characters if 'unix charset' is not 'utf8')"
+               "with a length >= min (at least 14) and <= max (at most 255)." },
+       { "check_password_quality", (PyCFunction)py_check_password_quality,
+               METH_VARARGS, "check_password_quality(pass) -> bool\n"
+               "Check password quality against Samba's check_password_quality,"
+               "the implementation of Microsoft's rules:"
+               "http://msdn.microsoft.com/en-us/subscriptions/cc786468%28v=ws.10%29.aspx"
+       },
        { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
                "unix2nttime(timestamp) -> nttime" },
        { "nttime2unix", (PyCFunction)py_nttime2unix, METH_VARARGS,
@@ -271,6 +366,8 @@ static PyMethodDef py_misc_methods[] = {
                "set debug level" },
        { "get_debug_level", (PyCFunction)py_get_debug_level, METH_NOARGS,
                "get debug level" },
+       { "fault_setup", (PyCFunction)py_fault_setup, METH_NOARGS,
+               "setup the default samba panic handler" },
        { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
                "interface_ips(lp_ctx[, all_interfaces) -> list_of_ifaces\n"
                "\n"
@@ -281,22 +378,36 @@ static PyMethodDef py_misc_methods[] = {
                "(for testing) find one string in another with Samba's strstr_m()"},
        { "is_ntvfs_fileserver_built", (PyCFunction)py_is_ntvfs_fileserver_built, METH_NOARGS,
                "is the NTVFS file server built in this installation?" },
+       { "is_heimdal_built", (PyCFunction)py_is_heimdal_built, METH_NOARGS,
+               "is Samba built with Heimdal Kerberbos?" },
+       { "generate_random_bytes",
+               (PyCFunction)py_generate_random_bytes,
+               METH_VARARGS,
+               "generate_random_bytes(len) -> bytes\n"
+               "Generate random bytes with specified length." },
        { NULL }
 };
 
-void init_glue(void)
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "_glue",
+    .m_doc = "Python bindings for miscellaneous Samba functions.",
+    .m_size = -1,
+    .m_methods = py_misc_methods,
+};
+
+MODULE_INIT_FUNC(_glue)
 {
        PyObject *m;
 
        debug_setup_talloc_log();
 
-       m = Py_InitModule3("_glue", py_misc_methods, 
-                          "Python bindings for miscellaneous Samba functions.");
+       m = PyModule_Create(&moduledef);
        if (m == NULL)
-               return;
+               return NULL;
 
        PyModule_AddObject(m, "version",
-                                          PyString_FromString(SAMBA_VERSION_STRING));
+                                          PyStr_FromString(SAMBA_VERSION_STRING));
        PyExc_NTSTATUSError = PyErr_NewException(discard_const_p(char, "samba.NTSTATUSError"), PyExc_RuntimeError, NULL);
        if (PyExc_NTSTATUSError != NULL) {
                Py_INCREF(PyExc_NTSTATUSError);
@@ -314,5 +425,13 @@ void init_glue(void)
                Py_INCREF(PyExc_HRESULTError);
                PyModule_AddObject(m, "HRESULTError", PyExc_HRESULTError);
        }
+
+       PyExc_DsExtendedError = PyErr_NewException(discard_const_p(char, "samba.DsExtendedError"), PyExc_RuntimeError, NULL);
+       if (PyExc_DsExtendedError != NULL) {
+               Py_INCREF(PyExc_DsExtendedError);
+               PyModule_AddObject(m, "DsExtendedError", PyExc_DsExtendedError);
+       }
+
+       return m;
 }