LCOV - code coverage report
Current view: top level - source4/param - provision.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 184 300 61.3 %
Date: 2021-09-23 10:06:22 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2009
       5             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include <Python.h>
      22             : #include "python/py3compat.h"
      23             : #include <ldb.h>
      24             : #include <pyldb.h>
      25             : #include "includes.h"
      26             : #include "librpc/ndr/libndr.h"
      27             : #include "param/provision.h"
      28             : #include "param/secrets.h"
      29             : #include <pytalloc.h>
      30             : #include "python/modules.h"
      31             : #include "param/pyparam.h"
      32             : #include "dynconfig/dynconfig.h"
      33             : 
      34         300 : static bool dict_insert(PyObject* dict,
      35             :                         const char* key,
      36             :                         PyObject* value)
      37             : {
      38         300 :         if (value == NULL) {
      39           0 :                 return false;
      40             :         }
      41         300 :         if (PyDict_SetItemString(dict, key, value) == -1) {
      42           0 :                 Py_XDECREF(value);
      43           0 :                 return false;
      44             :         }
      45         300 :         Py_XDECREF(value);
      46         288 :         return true;
      47             : }
      48             : 
      49          16 : static PyObject *provision_module(void)
      50             : {
      51          16 :         PyObject *name = PyUnicode_FromString("samba.provision");
      52          16 :         PyObject *mod = NULL;
      53          16 :         if (name == NULL)
      54           0 :                 return NULL;
      55          16 :         mod = PyImport_Import(name);
      56          16 :         Py_CLEAR(name);
      57          15 :         return mod;
      58             : }
      59             : 
      60          71 : static PyObject *schema_module(void)
      61             : {
      62          71 :         PyObject *name = PyUnicode_FromString("samba.schema");
      63          71 :         PyObject *mod = NULL;
      64          71 :         if (name == NULL)
      65           0 :                 return NULL;
      66          71 :         mod = PyImport_Import(name);
      67          71 :         Py_CLEAR(name);
      68          70 :         return mod;
      69             : }
      70             : 
      71          11 : static PyObject *ldb_module(void)
      72             : {
      73          11 :         PyObject *name = PyUnicode_FromString("ldb");
      74          11 :         PyObject *mod = NULL;
      75          11 :         if (name == NULL)
      76           0 :                 return NULL;
      77          11 :         mod = PyImport_Import(name);
      78          11 :         Py_CLEAR(name);
      79          11 :         return mod;
      80             : }
      81             : 
      82          11 : static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
      83             : {
      84             :         PyLdbObject *ret;
      85          11 :         PyObject *ldb_mod = ldb_module();
      86             :         PyTypeObject *ldb_ctx_type;
      87          11 :         if (ldb_mod == NULL)
      88           0 :                 return NULL;
      89             : 
      90          11 :         ldb_ctx_type = (PyTypeObject *)PyObject_GetAttrString(ldb_mod, "Ldb");
      91             : 
      92          11 :         ret = (PyLdbObject *)ldb_ctx_type->tp_alloc(ldb_ctx_type, 0);
      93          11 :         if (ret == NULL) {
      94           0 :                 PyErr_NoMemory();
      95           0 :                 Py_XDECREF(ldb_ctx_type);
      96           0 :                 return NULL;
      97             :         }
      98          11 :         ret->mem_ctx = talloc_new(NULL);
      99          11 :         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
     100          11 :         Py_XDECREF(ldb_ctx_type);
     101          11 :         return (PyObject *)ret;
     102             : }
     103             : 
     104           5 : NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
     105             :                         struct provision_settings *settings, 
     106             :                         struct provision_result *result)
     107             : {
     108             :         const char *configfile;
     109           5 :         PyObject *provision_mod = NULL, *provision_dict = NULL;
     110           5 :         PyObject *provision_fn = NULL, *py_result = NULL;
     111           5 :         PyObject *parameters = NULL, *py_lp_ctx = NULL, *py_domaindn = NULL;
     112             : 
     113             :         struct ldb_context *samdb;
     114           5 :         NTSTATUS status = NT_STATUS_OK;
     115             :         
     116           5 :         DEBUG(0,("Provision for Become-DC test using python\n"));
     117             : 
     118           5 :         Py_Initialize();
     119           5 :         py_update_path(); /* Put the samba path at the start of sys.path */
     120             : 
     121           5 :         provision_mod = provision_module();
     122             : 
     123           5 :         if (provision_mod == NULL) {
     124           0 :                 PyErr_Print();
     125           0 :                 DEBUG(0, ("Unable to import provision Python module.\n"));
     126           0 :                 return NT_STATUS_UNSUCCESSFUL;
     127             :         }
     128             : 
     129           5 :         provision_dict = PyModule_GetDict(provision_mod);
     130             : 
     131           5 :         if (provision_dict == NULL) {
     132           0 :                 DEBUG(0, ("Unable to get dictionary for provision module\n"));
     133           0 :                 return NT_STATUS_UNSUCCESSFUL;
     134             :         }
     135             : 
     136           5 :         provision_fn = PyDict_GetItemString(provision_dict, "provision_become_dc");
     137           5 :         if (provision_fn == NULL) {
     138           0 :                 PyErr_Print();
     139           0 :                 DEBUG(0, ("Unable to get provision_become_dc function\n"));
     140           0 :                 return NT_STATUS_UNSUCCESSFUL;
     141             :         }
     142             :         
     143           5 :         DEBUG(0,("New Server in Site[%s]\n", 
     144             :                  settings->site_name));
     145             : 
     146           5 :         DEBUG(0,("DSA Instance [%s]\n"
     147             :                 "\tinvocationId[%s]\n",
     148             :                 settings->ntds_dn_str,
     149             :                 settings->invocation_id == NULL?"None":GUID_string(mem_ctx, settings->invocation_id)));
     150             : 
     151           5 :         DEBUG(0,("Paths under targetdir[%s]\n",
     152             :                  settings->targetdir));
     153           5 :         parameters = PyDict_New();
     154             : 
     155           5 :         configfile = lpcfg_configfile(lp_ctx);
     156           5 :         if (configfile != NULL) {
     157           5 :                 if (!dict_insert(parameters, "smbconf",
     158             :                                  PyUnicode_FromString(configfile))) {
     159           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     160           0 :                         goto out;
     161             :                 }
     162             :         }
     163             : 
     164           5 :         if (!dict_insert(parameters,
     165             :                          "rootdn",
     166             :                          PyUnicode_FromString(settings->root_dn_str))) {
     167           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     168           0 :                 goto out;
     169             :         }
     170           5 :         if (settings->targetdir != NULL) {
     171           5 :                 if (!dict_insert(parameters,
     172             :                                  "targetdir",
     173             :                                  PyUnicode_FromString(settings->targetdir))) {
     174           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     175           0 :                         goto out;
     176             :                 }
     177             :         }
     178           5 :         if (!dict_insert(parameters,
     179             :                          "hostname",
     180             :                          PyUnicode_FromString(settings->netbios_name))) {
     181           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     182           0 :                 goto out;
     183             :         }
     184           5 :         if (!dict_insert(parameters,
     185             :                          "domain",
     186             :                          PyUnicode_FromString(settings->domain))) {
     187           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     188           0 :                 goto out;
     189             :         }
     190           5 :         if (!dict_insert(parameters,
     191             :                          "realm",
     192             :                          PyUnicode_FromString(settings->realm))) {
     193           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     194           0 :                 goto out;
     195             :         }
     196           5 :         if (settings->root_dn_str) {
     197           5 :                 if (!dict_insert(parameters,
     198             :                                  "rootdn",
     199             :                                  PyUnicode_FromString(settings->root_dn_str))) {
     200           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     201           0 :                         goto out;
     202             :                 }
     203             :         }
     204             : 
     205           5 :         if (settings->domain_dn_str) {
     206           5 :                 if (!dict_insert(parameters,
     207             :                                  "domaindn",
     208             :                                  PyUnicode_FromString(settings->domain_dn_str))) {
     209           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     210           0 :                         goto out;
     211             :                 }
     212             :         }
     213             : 
     214           5 :         if (settings->schema_dn_str) {
     215           4 :                 if (!dict_insert(parameters,
     216             :                                  "schemadn",
     217             :                                  PyUnicode_FromString(settings->schema_dn_str))) {
     218           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     219           0 :                         goto out;
     220             :                 }
     221             :         }
     222           5 :         if (settings->config_dn_str) {
     223           4 :                 if (!dict_insert(parameters,
     224             :                                  "configdn",
     225             :                                  PyUnicode_FromString(settings->config_dn_str))) {
     226           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     227           0 :                         goto out;
     228             :                 }
     229             :         }
     230           5 :         if (settings->server_dn_str) {
     231           4 :                 if (!dict_insert(parameters,
     232             :                                  "serverdn",
     233             :                                  PyUnicode_FromString(settings->server_dn_str))) {
     234           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     235           0 :                         goto out;
     236             :                 }
     237             :         }
     238           5 :         if (settings->site_name) {
     239           5 :                 if (!dict_insert(parameters,
     240             :                                  "sitename",
     241             :                                   PyUnicode_FromString(settings->site_name))) {
     242           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     243           0 :                         goto out;
     244             :                 }
     245             :         }
     246             : 
     247           5 :         if (!dict_insert(parameters,
     248             :                          "machinepass",
     249             :                          PyUnicode_FromString(settings->machine_password))){
     250           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     251           0 :                 goto out;
     252             :         }
     253             : 
     254           5 :         if (!dict_insert(parameters,
     255             :                          "debuglevel",
     256           5 :                          PyLong_FromLong(DEBUGLEVEL))) {
     257           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     258           0 :                 goto out;
     259             :         }
     260             : 
     261           5 :         if (!dict_insert(parameters,
     262             :                          "use_ntvfs",
     263           5 :                          PyLong_FromLong(settings->use_ntvfs))) {
     264           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     265           0 :                 goto out;
     266             :         }
     267             : 
     268           5 :         py_result = PyEval_CallObjectWithKeywords(provision_fn, NULL, parameters);
     269             : 
     270           5 :         if (py_result == NULL) {
     271           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     272           0 :                 goto out;
     273             :         }
     274             : 
     275           5 :         py_domaindn = PyObject_GetAttrString(py_result, "domaindn");
     276           5 :         result->domaindn = talloc_strdup(mem_ctx, PyUnicode_AsUTF8(py_domaindn));
     277             : 
     278             :         /* FIXME paths */
     279           5 :         py_lp_ctx = PyObject_GetAttrString(py_result, "lp");
     280           5 :         if (py_lp_ctx == NULL) {
     281           0 :                 DEBUG(0, ("Missing 'lp' attribute"));
     282           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     283           0 :                 goto out;
     284             :         }
     285           5 :         result->lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     286             : 
     287           5 :         samdb = pyldb_Ldb_AsLdbContext(PyObject_GetAttrString(py_result, "samdb"));
     288           5 :         if (samdb == NULL) {
     289           0 :                 DEBUG(0, ("Missing 'samdb' attribute"));
     290           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     291           0 :                 goto out;
     292             :         }
     293           5 :         result->samdb = samdb;
     294           5 :         status = NT_STATUS_OK;
     295           5 : out:
     296           5 :         Py_CLEAR(parameters);
     297           5 :         Py_CLEAR(provision_mod);
     298           5 :         Py_CLEAR(provision_fn);
     299           5 :         Py_CLEAR(provision_dict);
     300           5 :         Py_CLEAR(py_result);
     301           5 :         Py_CLEAR(py_lp_ctx);
     302           5 :         Py_CLEAR(py_domaindn);
     303           5 :         if (!NT_STATUS_IS_OK(status)) {
     304           0 :                 PyErr_Print();
     305           0 :                 PyErr_Clear();
     306             :         }
     307           5 :         return status;
     308             : }
     309             : 
     310          11 : static PyObject *py_dom_sid_FromSid(struct dom_sid *sid)
     311             : {
     312          11 :         PyObject *mod_security = NULL, *dom_sid_Type = NULL, *result = NULL;
     313             : 
     314          11 :         mod_security = PyImport_ImportModule("samba.dcerpc.security");
     315          11 :         if (mod_security == NULL) {
     316           0 :                 return NULL;
     317             :         }
     318             : 
     319          11 :         dom_sid_Type = PyObject_GetAttrString(mod_security, "dom_sid");
     320          11 :         if (dom_sid_Type == NULL) {
     321           0 :                 Py_DECREF(mod_security);
     322           0 :                 return NULL;
     323             :         }
     324             : 
     325          11 :         result = pytalloc_reference((PyTypeObject *)dom_sid_Type, sid);
     326          11 :         Py_DECREF(mod_security);
     327          11 :         Py_DECREF(dom_sid_Type);
     328          11 :         return result;
     329             : }
     330             : 
     331          11 : NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
     332             :                                    struct tevent_context *event_ctx,
     333             :                                    struct provision_store_self_join_settings *settings,
     334             :                                    const char **error_string)
     335             : {
     336             :         int ret;
     337          11 :         PyObject *provision_mod = NULL, *provision_dict = NULL;
     338          11 :         PyObject *provision_fn = NULL, *py_result = NULL;
     339          11 :         PyObject *parameters = NULL;
     340          11 :         struct ldb_context *ldb = NULL;
     341          11 :         TALLOC_CTX *tmp_mem = talloc_new(mem_ctx);
     342             : 
     343          11 :         NTSTATUS status = NT_STATUS_OK;
     344          11 :         *error_string = NULL;
     345             : 
     346          11 :         if (!tmp_mem) {
     347           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     348           0 :                 goto out;
     349             :         }
     350             : 
     351             :         /* Create/Open the secrets database */
     352          11 :         ldb = secrets_db_create(tmp_mem, lp_ctx);
     353          11 :         if (!ldb) {
     354             :                 *error_string
     355           0 :                         = talloc_asprintf(mem_ctx, 
     356             :                                           "Could not open secrets database");
     357           0 :                 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     358           0 :                 goto out;
     359             :         }
     360             : 
     361          11 :         ret = ldb_transaction_start(ldb);
     362             : 
     363          11 :         if (ret != LDB_SUCCESS) {
     364             :                 *error_string
     365           0 :                         = talloc_asprintf(mem_ctx, 
     366             :                                           "Could not start transaction on secrets database: %s", ldb_errstring(ldb));
     367           0 :                 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     368           0 :                 goto out;
     369             :         }
     370             : 
     371          11 :         Py_Initialize();
     372          11 :         py_update_path(); /* Put the samba path at the start of sys.path */
     373          11 :         provision_mod = provision_module();
     374             : 
     375          11 :         if (provision_mod == NULL) {
     376             :                 *error_string
     377           0 :                         = talloc_asprintf(mem_ctx, "Unable to import provision Python module.");
     378           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     379           0 :                 goto out;
     380             :         }
     381             : 
     382          11 :         provision_dict = PyModule_GetDict(provision_mod);
     383             : 
     384          11 :         if (provision_dict == NULL) {
     385             :                 *error_string
     386           0 :                         = talloc_asprintf(mem_ctx, "Unable to get dictionary for provision module");
     387           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     388           0 :                 goto out;
     389             :         }
     390             : 
     391          11 :         provision_fn = PyDict_GetItemString(provision_dict, "secretsdb_self_join");
     392          11 :         if (provision_fn == NULL) {
     393             :                 *error_string
     394           0 :                         = talloc_asprintf(mem_ctx, "Unable to get provision_become_dc function");
     395           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     396           0 :                 goto out;
     397             :         }
     398             : 
     399          11 :         parameters = PyDict_New();
     400             : 
     401          11 :         if(!dict_insert(parameters,
     402             :                         "secretsdb",
     403             :                         PyLdb_FromLdbContext(ldb))){
     404           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     405           0 :                 goto out;
     406             :         }
     407          11 :         if (!dict_insert(parameters,
     408             :                          "domain",
     409             :                          PyUnicode_FromString(settings->domain_name))) {
     410           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     411           0 :                 goto out;
     412             :         }
     413          11 :         if (settings->realm != NULL) {
     414          11 :                 if (!dict_insert(parameters,
     415             :                                  "realm",
     416             :                                  PyUnicode_FromString(settings->realm))) {
     417           0 :                         status = NT_STATUS_UNSUCCESSFUL;
     418           0 :                         goto out;
     419             :                 }
     420             :         }
     421          11 :         if (!dict_insert(parameters,
     422             :                          "machinepass",
     423             :                          PyUnicode_FromString(settings->machine_password))) {
     424           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     425           0 :                 goto out;
     426             :         }
     427          11 :         if (!dict_insert(parameters,
     428             :                          "netbiosname",
     429             :                          PyUnicode_FromString(settings->netbios_name))) {
     430           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     431           0 :                 goto out;
     432             :         }
     433             : 
     434             : 
     435          11 :         if (!dict_insert(parameters,
     436             :                          "domainsid",
     437             :                          py_dom_sid_FromSid(settings->domain_sid))) {
     438           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     439           0 :                 goto out;
     440             :         }
     441             : 
     442          11 :         if (!dict_insert(parameters,
     443             :                          "secure_channel_type",
     444          11 :                          PyLong_FromLong(settings->secure_channel_type))) {
     445           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     446           0 :                 goto out;
     447             :         }
     448             : 
     449          11 :         if (!dict_insert(parameters,
     450             :                          "key_version_number",
     451          11 :                          PyLong_FromLong(settings->key_version_number))) {
     452           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     453           0 :                 goto out;
     454             :         }
     455             : 
     456          11 :         py_result = PyEval_CallObjectWithKeywords(provision_fn, NULL, parameters);
     457             : 
     458          11 :         if (py_result == NULL) {
     459           0 :                 ldb_transaction_cancel(ldb);
     460           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     461           0 :                 goto out;
     462             :         }
     463             : 
     464          11 :         ret = ldb_transaction_commit(ldb);
     465          11 :         if (ret != LDB_SUCCESS) {
     466             :                 *error_string
     467           0 :                         = talloc_asprintf(mem_ctx, 
     468             :                                           "Could not commit transaction on secrets database: %s", ldb_errstring(ldb));
     469           0 :                 status = NT_STATUS_INTERNAL_DB_ERROR;
     470           0 :                 goto out;
     471             :         }
     472             : 
     473          11 :         status = NT_STATUS_OK;
     474          11 : out:
     475          11 :         talloc_free(tmp_mem);
     476          11 :         Py_CLEAR(parameters);
     477          11 :         Py_CLEAR(provision_mod);
     478          11 :         Py_CLEAR(provision_dict);
     479          11 :         Py_CLEAR(py_result);
     480          11 :         if (!NT_STATUS_IS_OK(status)) {
     481           0 :                 PyErr_Print();
     482           0 :                 PyErr_Clear();
     483             :         }
     484          11 :         return status;
     485             : }
     486             : 
     487             : 
     488          71 : struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx,
     489             :                                          struct loadparm_context *lp_ctx,
     490             :                                          const char *schema_dn,
     491             :                                          DATA_BLOB *override_prefixmap)
     492             : {
     493             :         PyObject *schema_mod, *schema_dict, *schema_fn, *py_result, *parameters;
     494          71 :         PyObject *py_ldb = NULL;
     495          71 :         struct ldb_context *ldb_result = NULL;
     496          71 :         Py_Initialize();
     497          71 :         py_update_path(); /* Put the samba path at the start of sys.path */
     498             : 
     499          71 :         schema_mod = schema_module();
     500             : 
     501          71 :         if (schema_mod == NULL) {
     502           0 :                 PyErr_Print();
     503           0 :                 DEBUG(0, ("Unable to import schema Python module.\n"));
     504           0 :                 return NULL;
     505             :         }
     506             : 
     507          71 :         schema_dict = PyModule_GetDict(schema_mod);
     508             : 
     509          71 :         if (schema_dict == NULL) {
     510           0 :                 DEBUG(0, ("Unable to get dictionary for schema module\n"));
     511           0 :                 return NULL;
     512             :         }
     513             : 
     514          71 :         schema_fn = PyDict_GetItemString(schema_dict, "ldb_with_schema");
     515          71 :         if (schema_fn == NULL) {
     516           0 :                 PyErr_Print();
     517           0 :                 DEBUG(0, ("Unable to get schema_get_ldb function\n"));
     518           0 :                 return NULL;
     519             :         }
     520             :         
     521          71 :         parameters = PyDict_New();
     522             : 
     523          71 :         if (schema_dn) {
     524          70 :                 if (!dict_insert(parameters,
     525             :                                  "schemadn",
     526             :                                  PyUnicode_FromString(schema_dn))) {
     527           0 :                         return NULL;
     528             :                 }
     529             :         }
     530             : 
     531          71 :         if (override_prefixmap) {
     532         136 :                 if (!dict_insert(parameters,
     533             :                                  "override_prefixmap",
     534             :                                  PyBytes_FromStringAndSize(
     535          70 :                                         (const char *)override_prefixmap->data,
     536          70 :                                         override_prefixmap->length))) {
     537           0 :                         return NULL;
     538             :                 }
     539             :         }
     540             : 
     541          71 :         py_result = PyEval_CallObjectWithKeywords(schema_fn, NULL, parameters);
     542             : 
     543          71 :         Py_DECREF(parameters);
     544             : 
     545          71 :         if (py_result == NULL) {
     546           0 :                 PyErr_Print();
     547           0 :                 PyErr_Clear();
     548           0 :                 return NULL;
     549             :         }
     550             : 
     551          71 :         py_ldb = PyObject_GetAttrString(py_result, "ldb");
     552          71 :         Py_DECREF(py_result);
     553          71 :         ldb_result = pyldb_Ldb_AsLdbContext(py_ldb);
     554          71 :         if (talloc_reference(mem_ctx, ldb_result) == NULL) {
     555           0 :                 ldb_result = NULL;
     556             :         }
     557          71 :         Py_DECREF(py_ldb);
     558          70 :         return ldb_result;
     559             : }

Generated by: LCOV version 1.13