s3/util/py_net.c: fix samba-tool domain join&leave segfault
authorMichael Tokarev <mjt@tls.msk.ru>
Tue, 24 May 2022 13:25:41 +0000 (16:25 +0300)
committerAndreas Schneider <asn@cryptomilk.org>
Wed, 25 May 2022 06:19:32 +0000 (06:19 +0000)
We process python args using PyArg_ParseTupleAndKeywords(), and use "p"
type modifier there.  According to documentation, this type modifier,
while works for a boolean type, expects an argument of type int. But in
py_net_join_member() and  py_net_leave() we use argument of type uint8_t
(no_dns_update, keep_account, r->in.debug). So when PyArg_ParseTupleAndKeywords()
tries to assign a value to &no_dns_update, it updates subsequent, unrelated bytes
too, - which ones depends on the stack and structure layout used by the compiler.

Fix this by using int type for all relevant variables, and by introducing proxy
variable "debug" (of the same type) for r->in.debug.

While at it, also ensure all variables have sensible default values.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Wed May 25 06:19:32 UTC 2022 on sn-devel-184

source3/utils/py_net.c

index 0d774bcb805dfe108e2a0769d93acdc87b5d4f8d..6f20fdb08904f2a282f10fbcd0333865eb1c52aa 100644 (file)
@@ -68,7 +68,7 @@ static PyObject *py_net_join_member(py_net_Object *self, PyObject *args, PyObjec
        WERROR werr;
        PyObject *result;
        TALLOC_CTX *mem_ctx;
-       uint8_t no_dns_updates;
+       int no_dns_updates = false, debug = false;
        bool modify_config = lp_config_backend_is_registry();
        const char *kwnames[] = { "dnshostname", "createupn", "createcomputer",
                                  "osName", "osVer", "osServicePack",
@@ -97,7 +97,7 @@ static PyObject *py_net_join_member(py_net_Object *self, PyObject *args, PyObjec
                                         &r->in.os_version,
                                         &r->in.os_servicepack,
                                         &r->in.machine_password,
-                                        &r->in.debug,
+                                        &debug,
                                         &no_dns_updates)) {
                talloc_free(mem_ctx);
                PyErr_FromString(_("Invalid arguments\n"));
@@ -126,6 +126,7 @@ static PyObject *py_net_join_member(py_net_Object *self, PyObject *args, PyObjec
                                  WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
                                  WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED;
        r->in.msg_ctx           = cmdline_messaging_context(get_dyn_CONFIGFILE());
+       r->in.debug             = debug;
        c->opt_user_name = r->in.admin_account;
        c->opt_password = r->in.admin_password;
        c->opt_kerberos = r->in.use_kerberos;
@@ -184,7 +185,7 @@ static PyObject *py_net_leave(py_net_Object *self, PyObject *args, PyObject *kwa
        struct libnet_UnjoinCtx *r = NULL;
        WERROR werr;
        TALLOC_CTX *mem_ctx;
-       bool keep_account = false;
+       int keep_account = false, debug = false;
        const char *kwnames[] = { "keepAccount", "debug", NULL };
 
        mem_ctx = talloc_new(self->mem_ctx);
@@ -207,7 +208,7 @@ static PyObject *py_net_leave(py_net_Object *self, PyObject *args, PyObject *kwa
 
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|pp:Leave",
                                         discard_const_p(char *, kwnames),
-                                        &keep_account, &r->in.debug)) {
+                                        &keep_account, &debug)) {
                talloc_free(mem_ctx);
                PyErr_FromString(_("Invalid arguments\n"));
                return NULL;
@@ -219,6 +220,7 @@ static PyObject *py_net_leave(py_net_Object *self, PyObject *args, PyObject *kwa
        r->in.admin_account     = cli_credentials_get_username(self->creds);
        r->in.admin_password    = cli_credentials_get_password(self->creds);
        r->in.modify_config     = lp_config_backend_is_registry();
+       r->in.debug             = debug;
 
        /*
         * Try to delete it, but if that fails, disable it.  The