The branch, master has been updated
       via  0c15c4b1db9 Make sure results from GetAttrString are decref'ed 
where needed
       via  8d3f736bba3 Fix instances of PyDict_SetItem to decref the value
       via  5dad03b83cd Fix mem leak with PyBytes_FromStringAndSize 
Reviewed-by: Andrew Bartlett [email protected]
      from  30d505e91bb selftest: Only set clockskew to 5 seconds for MIT 
Kerberos

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 0c15c4b1db9ef12cc02683bbf24e0a2d10d1b991
Author: Noel Power <[email protected]>
Date:   Mon Jan 28 16:57:17 2019 +0000

    Make sure results from GetAttrString are decref'ed where needed
    
    Signed-off-by: Noel Power <[email protected]>
    Reviewed-by: Andrew Bartlett [email protected]
    
    Autobuild-User(master): Noel Power <[email protected]>
    Autobuild-Date(master): Wed Feb 13 14:51:12 CET 2019 on sn-devel-144

commit 8d3f736bba3367ed615f97d292f86c447a25b8d5
Author: Noel Power <[email protected]>
Date:   Mon Jan 28 15:23:59 2019 +0000

    Fix instances of PyDict_SetItem to decref the value
    
    Although it would be better to use the BuildValue approach to
    create the dictionares here, unfortunately the dictionaries created
    here have key/values that are created dynamically (based on input params).
    
    Signed-off-by: Noel Power <[email protected]>
    Reviewed-by: Andrew Bartlett [email protected]

commit 5dad03b83cd014277e2712ab04ad8a714d78a24c
Author: Noel Power <[email protected]>
Date:   Mon Jan 28 15:23:48 2019 +0000

    Fix mem leak with PyBytes_FromStringAndSize
    Reviewed-by: Andrew Bartlett [email protected]

-----------------------------------------------------------------------

Summary of changes:
 lib/ldb/pyldb.c                |   5 +-
 source4/auth/gensec/pygensec.c |   9 +-
 source4/libnet/py_net.c        |   9 +-
 source4/param/provision.c      | 370 +++++++++++++++++++++++++++++------------
 4 files changed, 278 insertions(+), 115 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c
index 3deb393e467..10a4b6cb55d 100644
--- a/lib/ldb/pyldb.c
+++ b/lib/ldb/pyldb.c
@@ -4106,6 +4106,7 @@ static PyObject *py_register_module(PyObject *module, 
PyObject *args)
        int ret;
        struct ldb_module_ops *ops;
        PyObject *input;
+       PyObject *tmp;
 
        if (!PyArg_ParseTuple(args, "O", &input))
                return NULL;
@@ -4116,8 +4117,10 @@ static PyObject *py_register_module(PyObject *module, 
PyObject *args)
                return NULL;
        }
 
-       ops->name = talloc_strdup(ops, 
PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
+       tmp = PyObject_GetAttrString(input, discard_const_p(char, "name"));
+       ops->name = talloc_strdup(ops, PyStr_AsUTF8(tmp));
 
+       Py_XDECREF(tmp);
        Py_INCREF(input);
        ops->private_data = input;
        ops->init_context = py_module_init;
diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c
index d8f782f8d19..72981a22263 100644
--- a/source4/auth/gensec/pygensec.c
+++ b/source4/auth/gensec/pygensec.c
@@ -453,7 +453,7 @@ static PyObject *py_gensec_update(PyObject *self, PyObject 
*args)
        NTSTATUS status;
        TALLOC_CTX *mem_ctx;
        DATA_BLOB in, out;
-       PyObject *ret, *py_in;
+       PyObject *py_bytes, *result, *py_in;
        struct gensec_security *security = pytalloc_get_type(self, struct 
gensec_security);
        PyObject *finished_processing;
 
@@ -477,7 +477,8 @@ static PyObject *py_gensec_update(PyObject *self, PyObject 
*args)
                talloc_free(mem_ctx);
                return NULL;
        }
-       ret = PyBytes_FromStringAndSize((const char *)out.data, out.length);
+       py_bytes = PyBytes_FromStringAndSize((const char *)out.data,
+                                            out.length);
        talloc_free(mem_ctx);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -486,7 +487,9 @@ static PyObject *py_gensec_update(PyObject *self, PyObject 
*args)
                finished_processing = Py_True;
        }
 
-       return PyTuple_Pack(2, finished_processing, ret);
+       result = PyTuple_Pack(2, finished_processing, py_bytes);
+       Py_XDECREF(py_bytes);
+       return result;
 }
 
 static PyObject *py_gensec_wrap(PyObject *self, PyObject *args)
diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c
index 3d95854e732..cacd695e50d 100644
--- a/source4/libnet/py_net.c
+++ b/source4/libnet/py_net.c
@@ -103,10 +103,15 @@ static void PyErr_SetDsExtendedError(enum 
drsuapi_DsExtendedError ext_err, const
                }
        }
        if (error) {
-               PyErr_SetObject(error,
+               PyObject *value =
                        Py_BuildValue(discard_const_p(char, "(i,s)"),
                                      ext_err,
-                                     error_description));
+                                     error_description);
+               PyErr_SetObject(error, value);
+               if (value) {
+                       Py_DECREF(value);
+               }
+               Py_DECREF(error);
        }
 }
 
diff --git a/source4/param/provision.c b/source4/param/provision.c
index ebcc0cd77da..47f296afcdd 100644
--- a/source4/param/provision.c
+++ b/source4/param/provision.c
@@ -31,6 +31,18 @@
 #include "param/pyparam.h"
 #include "dynconfig/dynconfig.h"
 
+static bool dict_insert(PyObject* dict,
+                       const char* key,
+                       PyObject* value)
+{
+       if (PyDict_SetItemString(dict, key, value) == -1) {
+               Py_XDECREF(value);
+               return false;
+       }
+       Py_XDECREF(value);
+       return true;
+}
+
 static PyObject *provision_module(void)
 {
        PyObject *name = PyStr_FromString("samba.provision");
@@ -77,10 +89,12 @@ static PyObject *PyLdb_FromLdbContext(struct ldb_context 
*ldb_ctx)
        ret = (PyLdbObject *)ldb_ctx_type->tp_alloc(ldb_ctx_type, 0);
        if (ret == NULL) {
                PyErr_NoMemory();
+               Py_XDECREF(ldb_ctx_type);
                return NULL;
        }
        ret->mem_ctx = talloc_new(NULL);
        ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
+       Py_XDECREF(ldb_ctx_type);
        return (PyObject *)ret;
 }
 
@@ -89,8 +103,12 @@ NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct 
loadparm_context *lp_ctx,
                        struct provision_result *result)
 {
        const char *configfile;
-       PyObject *provision_mod, *provision_dict, *provision_fn, *py_result, 
*parameters, *py_lp_ctx;
+       PyObject *provision_mod = NULL, *provision_dict = NULL;
+       PyObject *provision_fn = NULL, *py_result = NULL;
+       PyObject *parameters = NULL, *py_lp_ctx = NULL, *py_domaindn = NULL;
+
        struct ldb_context *samdb;
+       NTSTATUS status = NT_STATUS_OK;
        
        DEBUG(0,("Provision for Become-DC test using python\n"));
 
@@ -133,79 +151,157 @@ NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct 
loadparm_context *lp_ctx,
 
        configfile = lpcfg_configfile(lp_ctx);
        if (configfile != NULL) {
-               PyDict_SetItemString(parameters, "smbconf", 
-                                    PyStr_FromString(configfile));
-       }
-
-       PyDict_SetItemString(parameters, "rootdn", 
-                                                
PyStr_FromString(settings->root_dn_str));
-       if (settings->targetdir != NULL)
-               PyDict_SetItemString(parameters, "targetdir", 
-                                                        
PyStr_FromString(settings->targetdir));
-       PyDict_SetItemString(parameters, "hostname", 
-                                                
PyStr_FromString(settings->netbios_name));
-       PyDict_SetItemString(parameters, "domain", 
-                                                
PyStr_FromString(settings->domain));
-       PyDict_SetItemString(parameters, "realm", 
-                                                
PyStr_FromString(settings->realm));
-       if (settings->root_dn_str)
-               PyDict_SetItemString(parameters, "rootdn", 
-                                    PyStr_FromString(settings->root_dn_str));
-
-       if (settings->domain_dn_str) 
-               PyDict_SetItemString(parameters, "domaindn", 
-                                    PyStr_FromString(settings->domain_dn_str));
-
-       if (settings->schema_dn_str) 
-               PyDict_SetItemString(parameters, "schemadn", 
-                                    PyStr_FromString(settings->schema_dn_str));
-       
-       if (settings->config_dn_str) 
-               PyDict_SetItemString(parameters, "configdn", 
-                                    PyStr_FromString(settings->config_dn_str));
-       
-       if (settings->server_dn_str) 
-               PyDict_SetItemString(parameters, "serverdn", 
-                                    PyStr_FromString(settings->server_dn_str));
-       
-       if (settings->site_name) 
-               PyDict_SetItemString(parameters, "sitename", 
-                                    PyStr_FromString(settings->site_name));
+               if (!dict_insert(parameters, "smbconf",
+                                PyStr_FromString(configfile))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
 
-       PyDict_SetItemString(parameters, "machinepass", 
-                            PyStr_FromString(settings->machine_password));
+       if (!dict_insert(parameters,
+                        "rootdn",
+                        PyStr_FromString(settings->root_dn_str))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
+       if (settings->targetdir != NULL) {
+               if (!dict_insert(parameters,
+                                "targetdir",
+                                PyStr_FromString(settings->targetdir))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
+       if (!dict_insert(parameters,
+                        "hostname",
+                        PyStr_FromString(settings->netbios_name))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
+       if (!dict_insert(parameters,
+                        "domain",
+                        PyStr_FromString(settings->domain))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
+       if (!dict_insert(parameters,
+                        "realm",
+                        PyStr_FromString(settings->realm))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
+       if (settings->root_dn_str) {
+               if (!dict_insert(parameters,
+                                "rootdn",
+                                PyStr_FromString(settings->root_dn_str))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
 
-       
-       PyDict_SetItemString(parameters, "debuglevel", 
PyInt_FromLong(DEBUGLEVEL));
+       if (settings->domain_dn_str) {
+               if (!dict_insert(parameters,
+                                "domaindn",
+                                PyStr_FromString(settings->domain_dn_str))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
 
-       PyDict_SetItemString(parameters, "use_ntvfs", 
PyInt_FromLong(settings->use_ntvfs));
+       if (settings->schema_dn_str) {
+               if (!dict_insert(parameters,
+                                "schemadn",
+                                PyStr_FromString(settings->schema_dn_str))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
+       if (settings->config_dn_str) {
+               if (!dict_insert(parameters,
+                                "configdn",
+                                PyStr_FromString(settings->config_dn_str))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
+       if (settings->server_dn_str) {
+               if (!dict_insert(parameters,
+                                "serverdn",
+                                PyStr_FromString(settings->server_dn_str))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
+       if (settings->site_name) {
+               if (!dict_insert(parameters,
+                                "sitename",
+                                 PyStr_FromString(settings->site_name))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
 
-       py_result = PyEval_CallObjectWithKeywords(provision_fn, NULL, 
parameters);
+       if (!dict_insert(parameters,
+                        "machinepass",
+                        PyStr_FromString(settings->machine_password))){
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
 
-       Py_DECREF(parameters);
+       if (!dict_insert(parameters,
+                        "debuglevel",
+                        PyInt_FromLong(DEBUGLEVEL))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
+
+       if (!dict_insert(parameters,
+                        "use_ntvfs",
+                        PyInt_FromLong(settings->use_ntvfs))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
+
+       py_result = PyEval_CallObjectWithKeywords(provision_fn, NULL, 
parameters);
 
        if (py_result == NULL) {
-               PyErr_Print();
-               PyErr_Clear();
-               return NT_STATUS_UNSUCCESSFUL;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
 
-       result->domaindn = talloc_strdup(mem_ctx, 
PyStr_AsString(PyObject_GetAttrString(py_result, "domaindn")));
+       py_domaindn = PyObject_GetAttrString(py_result, "domaindn");
+       result->domaindn = talloc_strdup(mem_ctx, PyStr_AsString(py_domaindn));
 
        /* FIXME paths */
        py_lp_ctx = PyObject_GetAttrString(py_result, "lp");
        if (py_lp_ctx == NULL) {
                DEBUG(0, ("Missing 'lp' attribute"));
-               return NT_STATUS_UNSUCCESSFUL;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
        result->lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
+
        samdb = pyldb_Ldb_AsLdbContext(PyObject_GetAttrString(py_result, 
"samdb"));
        if (samdb == NULL) {
                DEBUG(0, ("Missing 'samdb' attribute"));
-               return NT_STATUS_UNSUCCESSFUL;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
        result->samdb = samdb;
-       return NT_STATUS_OK;
+       status = NT_STATUS_OK;
+out:
+       Py_CLEAR(parameters);
+       Py_CLEAR(provision_mod);
+       Py_CLEAR(provision_fn);
+       Py_CLEAR(provision_dict);
+       Py_CLEAR(py_result);
+       Py_CLEAR(py_lp_ctx);
+       Py_CLEAR(py_domaindn);
+       if (!NT_STATUS_IS_OK(status)) {
+               PyErr_Print();
+               PyErr_Clear();
+       }
+       return status;
 }
 
 static PyObject *py_dom_sid_FromSid(struct dom_sid *sid)
@@ -235,14 +331,18 @@ NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, 
struct loadparm_context
                                   const char **error_string)
 {
        int ret;
-       PyObject *provision_mod, *provision_dict, *provision_fn, *py_result, 
*parameters, *py_sid;
-       struct ldb_context *ldb;
+       PyObject *provision_mod = NULL, *provision_dict = NULL;
+       PyObject *provision_fn = NULL, *py_result = NULL;
+       PyObject *parameters = NULL, *py_sid = NULL;
+       struct ldb_context *ldb = NULL;
        TALLOC_CTX *tmp_mem = talloc_new(mem_ctx);
 
+       NTSTATUS status = NT_STATUS_OK;
        *error_string = NULL;
 
        if (!tmp_mem) {
-               return NT_STATUS_NO_MEMORY;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
 
        /* Open the secrets database */
@@ -251,8 +351,8 @@ NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, 
struct loadparm_context
                *error_string
                        = talloc_asprintf(mem_ctx, 
                                          "Could not open secrets database");
-               talloc_free(tmp_mem);
-               return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+               status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+               goto out;
        }
 
        ret = ldb_transaction_start(ldb);
@@ -261,8 +361,8 @@ NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, 
struct loadparm_context
                *error_string
                        = talloc_asprintf(mem_ctx, 
                                          "Could not start transaction on 
secrets database: %s", ldb_errstring(ldb));
-               talloc_free(tmp_mem);
-               return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+               status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+               goto out;
        }
 
        Py_Initialize();
@@ -270,11 +370,10 @@ NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, 
struct loadparm_context
        provision_mod = provision_module();
 
        if (provision_mod == NULL) {
-               PyErr_Print();
                *error_string
                        = talloc_asprintf(mem_ctx, "Unable to import provision 
Python module.");
-               talloc_free(tmp_mem);
-               return NT_STATUS_UNSUCCESSFUL;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
 
        provision_dict = PyModule_GetDict(provision_mod);
@@ -282,55 +381,86 @@ NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, 
struct loadparm_context
        if (provision_dict == NULL) {
                *error_string
                        = talloc_asprintf(mem_ctx, "Unable to get dictionary 
for provision module");
-               talloc_free(tmp_mem);
-               return NT_STATUS_UNSUCCESSFUL;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
 
        provision_fn = PyDict_GetItemString(provision_dict, 
"secretsdb_self_join");
        if (provision_fn == NULL) {
-               PyErr_Print();
                *error_string
                        = talloc_asprintf(mem_ctx, "Unable to get 
provision_become_dc function");
-               talloc_free(tmp_mem);
-               return NT_STATUS_UNSUCCESSFUL;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
-       
+
        parameters = PyDict_New();
 
-       PyDict_SetItemString(parameters, "secretsdb", 
-                            PyLdb_FromLdbContext(ldb));
-       PyDict_SetItemString(parameters, "domain", 
-                            PyStr_FromString(settings->domain_name));
+       if(!dict_insert(parameters,
+                       "secretsdb",
+                       PyLdb_FromLdbContext(ldb))){
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
+       if (!dict_insert(parameters,
+                        "domain",
+                        PyStr_FromString(settings->domain_name))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
        if (settings->realm != NULL) {
-               PyDict_SetItemString(parameters, "realm",
-                                    PyStr_FromString(settings->realm));
+               if (!dict_insert(parameters,
+                                "realm",
+                                PyStr_FromString(settings->realm))) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+                       goto out;
+               }
+       }
+       if (!dict_insert(parameters,
+                        "machinepass",
+                        PyStr_FromString(settings->machine_password))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
+       if (!dict_insert(parameters,
+                        "netbiosname",
+                        PyStr_FromString(settings->netbios_name))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
-       PyDict_SetItemString(parameters, "machinepass", 
-                            PyStr_FromString(settings->machine_password));
-       PyDict_SetItemString(parameters, "netbiosname", 
-                            PyStr_FromString(settings->netbios_name));
 
        py_sid = py_dom_sid_FromSid(settings->domain_sid);
        if (py_sid == NULL) {
-               Py_DECREF(parameters);
-               goto failure;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
 
-       PyDict_SetItemString(parameters, "domainsid", 
-                            py_sid);
+       if (!dict_insert(parameters,
+                        "domainsid",
+                        py_sid)) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
 
-       PyDict_SetItemString(parameters, "secure_channel_type", 
-                      PyInt_FromLong(settings->secure_channel_type));
+       if (!dict_insert(parameters,
+                        "secure_channel_type",
+                        PyInt_FromLong(settings->secure_channel_type))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
 
-       PyDict_SetItemString(parameters, "key_version_number", 
-                      PyInt_FromLong(settings->key_version_number));
+       if (!dict_insert(parameters,
+                        "key_version_number",
+                        PyInt_FromLong(settings->key_version_number))) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
+       }
 


-- 
Samba Shared Repository

Reply via email to