LCOV - code coverage report
Current view: top level - source4/param - pyparam.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 224 301 74.4 %
Date: 2021-09-23 10:06:22 Functions: 27 31 87.1 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
       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 "param/param.h"
      24             : #include "param/loadparm.h"
      25             : #include <pytalloc.h>
      26             : #include "dynconfig/dynconfig.h"
      27             : 
      28             : #define PyLoadparmContext_AsLoadparmContext(obj) pytalloc_get_type(obj, struct loadparm_context)
      29             : #define PyLoadparmService_AsLoadparmService(obj) pytalloc_get_type(obj, struct loadparm_service)
      30             : 
      31             : extern PyTypeObject PyLoadparmContext;
      32             : extern PyTypeObject PyLoadparmService;
      33             : 
      34           0 : static PyObject *PyLoadparmService_FromService(struct loadparm_service *service)
      35             : {
      36           2 :         return pytalloc_reference(&PyLoadparmService, service);
      37             : }
      38             : 
      39       51156 : static PyObject *py_lp_ctx_get_helper(struct loadparm_context *lp_ctx, const char *service_name, const char *param_name)
      40             : {
      41       51156 :         struct parm_struct *parm = NULL;
      42       51156 :         void *parm_ptr = NULL;
      43             :         int i;
      44             : 
      45       55948 :         if (service_name != NULL && strwicmp(service_name, GLOBAL_NAME) && 
      46        9562 :                 strwicmp(service_name, GLOBAL_NAME2)) {
      47             :                 struct loadparm_service *service;
      48             :                 /* its a share parameter */
      49        4792 :                 service = lpcfg_service(lp_ctx, service_name);
      50        4792 :                 if (service == NULL) {
      51          20 :                         return NULL;
      52             :                 }
      53        4770 :                 if (strchr(param_name, ':')) {
      54             :                         /* its a parametric option on a share */
      55           0 :                         const char *type = talloc_strndup(lp_ctx, param_name,
      56             :                                                                                           strcspn(param_name, ":"));
      57           0 :                         const char *option = strchr(param_name, ':') + 1;
      58             :                         const char *value;
      59           0 :                         if (type == NULL || option == NULL) {
      60           0 :                         return NULL;
      61             :                         }
      62           0 :                         value = lpcfg_get_parametric(lp_ctx, service, type, option);
      63           0 :                         if (value == NULL) {
      64           0 :                         return NULL;
      65             :                         }
      66           0 :                         return PyUnicode_FromString(value);
      67             :                 }
      68             : 
      69        4770 :                 parm = lpcfg_parm_struct(lp_ctx, param_name);
      70        4770 :                 if (parm == NULL || parm->p_class == P_GLOBAL) {
      71           0 :                         return NULL;
      72             :                 }
      73        4770 :                 parm_ptr = lpcfg_parm_ptr(lp_ctx, service, parm);
      74       46364 :     } else if (strchr(param_name, ':')) {
      75             :                 /* its a global parametric option */
      76       28033 :                 const char *type = talloc_strndup(lp_ctx,
      77             :                                   param_name, strcspn(param_name, ":"));
      78       28033 :                 const char *option = strchr(param_name, ':') + 1;
      79             :                 const char *value;
      80       28033 :                 if (type == NULL || option == NULL) {
      81           0 :                         return NULL;
      82             :                 }
      83       28033 :                 value = lpcfg_get_parametric(lp_ctx, NULL, type, option);
      84       28033 :                 if (value == NULL)
      85         686 :                         return NULL;
      86       27022 :                 return PyUnicode_FromString(value);
      87             :         } else {
      88             :                 /* its a global parameter */
      89       18331 :                 parm = lpcfg_parm_struct(lp_ctx, param_name);
      90       18331 :                 if (parm == NULL) {
      91           0 :                         return NULL;
      92             :                 }
      93       18331 :                 parm_ptr = lpcfg_parm_ptr(lp_ctx, NULL, parm);
      94             :         }
      95             : 
      96       23101 :         if (parm == NULL || parm_ptr == NULL) {
      97           0 :                 return NULL;
      98             :     }
      99             : 
     100             :     /* construct and return the right type of python object */
     101       23101 :     switch (parm->type) {
     102           0 :     case P_CHAR:
     103           0 :         return PyUnicode_FromFormat("%c", *(char *)parm_ptr);
     104       16297 :     case P_STRING:
     105             :     case P_USTRING:
     106       16297 :         return PyUnicode_FromString(*(char **)parm_ptr);
     107         192 :     case P_BOOL:
     108         192 :         return PyBool_FromLong(*(bool *)parm_ptr);
     109           0 :     case P_BOOLREV:
     110           0 :         return PyBool_FromLong(!(*(bool *)parm_ptr));
     111          22 :     case P_INTEGER:
     112             :     case P_OCTAL:
     113             :     case P_BYTES:
     114          22 :         return PyLong_FromLong(*(int *)parm_ptr);
     115        2206 :     case P_ENUM:
     116        4948 :         for (i=0; parm->enum_list[i].name; i++) {
     117        4979 :             if (*(int *)parm_ptr == parm->enum_list[i].value) {
     118        2237 :                 return PyUnicode_FromString(parm->enum_list[i].name);
     119             :             }
     120             :         }
     121           0 :         return NULL;
     122        4353 :     case P_CMDLIST:
     123             :     case P_LIST: 
     124             :         {
     125             :             int j;
     126        4353 :             const char **strlist = *(const char ***)parm_ptr;
     127             :             PyObject *pylist;
     128             :                 
     129        4353 :             if(strlist == NULL) {
     130        3912 :                     return PyList_New(0);
     131             :             }
     132             :                 
     133         441 :             pylist = PyList_New(str_list_length(strlist));
     134        3045 :             for (j = 0; strlist[j]; j++) 
     135        2604 :                 PyList_SetItem(pylist, j, 
     136        2567 :                                PyUnicode_FromString(strlist[j]));
     137         434 :             return pylist;
     138             :         }
     139             :     }
     140           0 :     return NULL;
     141             : 
     142             : }
     143             : 
     144       21210 : static PyObject *py_lp_ctx_load(PyObject *self, PyObject *args)
     145             : {
     146             :         char *filename;
     147             :         bool ret;
     148       21210 :         if (!PyArg_ParseTuple(args, "s", &filename))
     149           0 :                 return NULL;
     150             : 
     151       21210 :         ret = lpcfg_load(PyLoadparmContext_AsLoadparmContext(self), filename);
     152             : 
     153       21210 :         if (!ret) {
     154           0 :                 PyErr_Format(PyExc_RuntimeError, "Unable to load file %s", filename);
     155           0 :                 return NULL;
     156             :         }
     157       21210 :         Py_RETURN_NONE;
     158             : }
     159             : 
     160          69 : static PyObject *py_lp_ctx_load_default(PyObject *self, PyObject *unused)
     161             : {
     162             :         bool ret;
     163          69 :         ret = lpcfg_load_default(PyLoadparmContext_AsLoadparmContext(self));
     164             : 
     165          69 :         if (!ret) {
     166           0 :                 PyErr_SetString(PyExc_RuntimeError, "Unable to load default file");
     167           0 :                 return NULL;
     168             :         }
     169          69 :         Py_RETURN_NONE;
     170             : }
     171             : 
     172       51156 : static PyObject *py_lp_ctx_get(PyObject *self, PyObject *args)
     173             : {
     174             :         char *param_name;
     175       51156 :         char *section_name = NULL;
     176             :         PyObject *ret;
     177       51156 :         if (!PyArg_ParseTuple(args, "s|z", &param_name, &section_name))
     178           0 :                 return NULL;
     179             : 
     180       51156 :         ret = py_lp_ctx_get_helper(PyLoadparmContext_AsLoadparmContext(self), section_name, param_name);
     181       51156 :         if (ret == NULL)
     182        1033 :                 Py_RETURN_NONE;
     183       48516 :         return ret;
     184             : }
     185             : 
     186           2 : static PyObject *py_lp_ctx_is_myname(PyObject *self, PyObject *args)
     187             : {
     188             :         char *name;
     189           2 :         if (!PyArg_ParseTuple(args, "s", &name))
     190           0 :                 return NULL;
     191             : 
     192           2 :         return PyBool_FromLong(lpcfg_is_myname(PyLoadparmContext_AsLoadparmContext(self), name));
     193             : }
     194             : 
     195           2 : static PyObject *py_lp_ctx_is_mydomain(PyObject *self, PyObject *args)
     196             : {
     197             :         char *name;
     198           2 :         if (!PyArg_ParseTuple(args, "s", &name))
     199           0 :                 return NULL;
     200             : 
     201           2 :         return PyBool_FromLong(lpcfg_is_mydomain(PyLoadparmContext_AsLoadparmContext(self), name));
     202             : }
     203             : 
     204        3954 : static PyObject *py_lp_ctx_set(PyObject *self, PyObject *args)
     205             : {
     206             :         char *name, *value;
     207             :         bool ret;
     208        3954 :         if (!PyArg_ParseTuple(args, "ss", &name, &value))
     209           0 :                 return NULL;
     210             : 
     211        3954 :         ret = lpcfg_set_cmdline(PyLoadparmContext_AsLoadparmContext(self), name, value);
     212        3954 :         if (!ret) {
     213           2 :                 PyErr_SetString(PyExc_RuntimeError, "Unable to set parameter");
     214           2 :                 return NULL;
     215             :         }
     216             : 
     217        3952 :         Py_RETURN_NONE;
     218             : }
     219             : 
     220       22300 : static PyObject *py_lp_ctx_private_path(PyObject *self, PyObject *args)
     221             : {
     222             :         char *name, *path;
     223             :         PyObject *ret;
     224       22300 :         if (!PyArg_ParseTuple(args, "s", &name))
     225           0 :                 return NULL;
     226             : 
     227       22300 :         path = lpcfg_private_path(NULL, PyLoadparmContext_AsLoadparmContext(self), name);
     228       22300 :         ret = PyUnicode_FromString(path);
     229       22300 :         talloc_free(path);
     230             : 
     231       22300 :         return ret;
     232             : }
     233             : 
     234         260 : static PyObject *py_lp_ctx_services(PyObject *self, PyObject *unused)
     235             : {
     236         260 :         struct loadparm_context *lp_ctx = PyLoadparmContext_AsLoadparmContext(self);
     237             :         PyObject *ret;
     238             :         int i;
     239         260 :         ret = PyList_New(lpcfg_numservices(lp_ctx));
     240        4172 :         for (i = 0; i < lpcfg_numservices(lp_ctx); i++) {
     241        3912 :                 struct loadparm_service *service = lpcfg_servicebynum(lp_ctx, i);
     242        3912 :                 if (service != NULL) {
     243        3912 :                         PyList_SetItem(ret, i, PyUnicode_FromString(lpcfg_servicename(service)));
     244             :                 }
     245             :         }
     246         260 :         return ret;
     247             : }
     248             : 
     249         177 : static PyObject *py_lp_ctx_server_role(PyObject *self, PyObject *unused)
     250             : {
     251         177 :         struct loadparm_context *lp_ctx = PyLoadparmContext_AsLoadparmContext(self);
     252             :         uint32_t role;
     253             :         const char *role_str;
     254             : 
     255         177 :         role = lpcfg_server_role(lp_ctx);
     256         177 :         role_str = server_role_str(role);
     257             : 
     258         177 :         return PyUnicode_FromString(role_str);
     259             : }
     260             : 
     261         726 : static PyObject *py_lp_dump(PyObject *self, PyObject *args)
     262             : {
     263         726 :         bool show_defaults = false;
     264         726 :         const char *file_name = "";
     265         726 :         const char *mode = "w";
     266             :         FILE *f;
     267         726 :         struct loadparm_context *lp_ctx = PyLoadparmContext_AsLoadparmContext(self);
     268             : 
     269         726 :         if (!PyArg_ParseTuple(args, "|bss", &show_defaults, &file_name, &mode))
     270           0 :                 return NULL;
     271             : 
     272         726 :         if (file_name[0] == '\0') {
     273         516 :                 f = stdout;
     274             :         } else {
     275         210 :                 f = fopen(file_name, mode);
     276             :         }
     277             : 
     278         726 :         if (f == NULL) {
     279           0 :                 PyErr_SetFromErrno(PyExc_IOError);
     280           0 :                 return NULL;
     281             :         }
     282             : 
     283         726 :         lpcfg_dump(lp_ctx, f, show_defaults, lpcfg_numservices(lp_ctx));
     284             : 
     285         726 :         if (f != stdout) {
     286         210 :                 fclose(f);
     287             :         }
     288             : 
     289         726 :         Py_RETURN_NONE;
     290             : }
     291             : 
     292        1442 : static PyObject *py_lp_dump_a_parameter(PyObject *self, PyObject *args)
     293             : {
     294             :         char *param_name;
     295        1442 :         const char *section_name = NULL;
     296        1442 :         const char *file_name = "";
     297        1442 :         const char *mode = "w";
     298             :         FILE *f;
     299        1442 :         struct loadparm_context *lp_ctx = PyLoadparmContext_AsLoadparmContext(self);
     300             :         struct loadparm_service *service;
     301             :         bool ret;
     302             : 
     303        1442 :         if (!PyArg_ParseTuple(args, "s|zss", &param_name, &section_name, &file_name, &mode))
     304           0 :                 return NULL;
     305             : 
     306        1442 :         if (file_name[0] == '\0') {
     307        1441 :                 f = stdout;
     308             :         } else {
     309           1 :                 f = fopen(file_name, mode);
     310             :         }
     311             : 
     312        1442 :         if (f == NULL) {
     313           0 :                 return NULL;
     314             :         }
     315             : 
     316        1837 :         if (section_name != NULL && strwicmp(section_name, GLOBAL_NAME) &&
     317         395 :                 strwicmp(section_name, GLOBAL_NAME2)) {
     318             :                 /* it's a share parameter */
     319         395 :                 service = lpcfg_service(lp_ctx, section_name);
     320         788 :                 if (service == NULL) {
     321           1 :                         PyErr_Format(PyExc_RuntimeError, "Unknown section %s", section_name);
     322           1 :                         return NULL;
     323             :                 }
     324             :         } else {
     325             :                 /* it's global */
     326        1047 :                 service = NULL;
     327        1047 :                 section_name = "global";
     328             :         }
     329             : 
     330        1441 :         ret = lpcfg_dump_a_parameter(lp_ctx, service, param_name, f);
     331             : 
     332        1441 :         if (!ret) {
     333           1 :                 PyErr_Format(PyExc_RuntimeError, "Parameter %s unknown for section %s", param_name, section_name);
     334           1 :                 if (f != stdout) {
     335           0 :                         fclose(f);
     336             :                 }
     337           0 :                 return NULL;
     338             :         }
     339             : 
     340        1440 :         if (f != stdout) {
     341           1 :                 fclose(f);
     342             :         }
     343             : 
     344        1440 :         Py_RETURN_NONE;
     345             : 
     346             : }
     347             : 
     348        1159 : static PyObject *py_lp_log_level(PyObject *self, PyObject *unused)
     349             : {
     350        1159 :         int ret = debuglevel_get();
     351        1159 :         return PyLong_FromLong(ret);
     352             : }
     353             : 
     354             : 
     355        4733 : static PyObject *py_samdb_url(PyObject *self, PyObject *unused)
     356             : {
     357        4733 :         struct loadparm_context *lp_ctx = PyLoadparmContext_AsLoadparmContext(self);
     358        4733 :         return PyUnicode_FromFormat("tdb://%s/sam.ldb", lpcfg_private_dir(lp_ctx));
     359             : }
     360             : 
     361         688 : static PyObject *py_cache_path(PyObject *self, PyObject *args)
     362             : {
     363         688 :         struct loadparm_context *lp_ctx = PyLoadparmContext_AsLoadparmContext(self);
     364         688 :         char *name = NULL;
     365         688 :         char *path = NULL;
     366         688 :         PyObject *ret = NULL;
     367             : 
     368         688 :         if (!PyArg_ParseTuple(args, "s", &name)) {
     369           0 :                 return NULL;
     370             :         }
     371             : 
     372         688 :         path = lpcfg_cache_path(NULL, lp_ctx, name);
     373         688 :         if (!path) {
     374           0 :                 PyErr_Format(PyExc_RuntimeError,
     375             :                              "Unable to access cache %s", name);
     376           0 :                 return NULL;
     377             :         }
     378         688 :         ret = PyUnicode_FromString(path);
     379         688 :         talloc_free(path);
     380             : 
     381         688 :         return ret;
     382             : }
     383             : 
     384          40 : static PyObject *py_state_path(PyObject *self, PyObject *args)
     385             : {
     386          20 :         struct loadparm_context *lp_ctx =
     387          20 :                 PyLoadparmContext_AsLoadparmContext(self);
     388          40 :         char *name = NULL;
     389          40 :         char *path = NULL;
     390          40 :         PyObject *ret = NULL;
     391             : 
     392          40 :         if (!PyArg_ParseTuple(args, "s", &name)) {
     393           0 :                 return NULL;
     394             :         }
     395             : 
     396          40 :         path = lpcfg_state_path(NULL, lp_ctx, name);
     397          40 :         if (!path) {
     398           0 :                 PyErr_Format(PyExc_RuntimeError,
     399             :                              "Unable to access cache %s", name);
     400           0 :                 return NULL;
     401             :         }
     402          40 :         ret = PyUnicode_FromString(path);
     403          40 :         talloc_free(path);
     404             : 
     405          40 :         return ret;
     406             : }
     407             : 
     408             : static PyMethodDef py_lp_ctx_methods[] = {
     409             :         { "load", py_lp_ctx_load, METH_VARARGS,
     410             :                 "S.load(filename) -> None\n"
     411             :                 "Load specified file." },
     412             :         { "load_default", py_lp_ctx_load_default, METH_NOARGS,
     413             :                 "S.load_default() -> None\n"
     414             :                 "Load default smb.conf file." },
     415             :         { "is_myname", py_lp_ctx_is_myname, METH_VARARGS,
     416             :                 "S.is_myname(name) -> bool\n"
     417             :                 "Check whether the specified name matches one of our netbios names." },
     418             :         { "is_mydomain", py_lp_ctx_is_mydomain, METH_VARARGS,
     419             :                 "S.is_mydomain(name) -> bool\n"
     420             :                 "Check whether the specified name matches our domain name." },
     421             :         { "get", py_lp_ctx_get, METH_VARARGS,
     422             :                 "S.get(name, service_name) -> value\n"
     423             :                 "Find specified parameter." },
     424             :         { "set", py_lp_ctx_set, METH_VARARGS,
     425             :                 "S.set(name, value) -> bool\n"
     426             :                 "Change a parameter." },
     427             :         { "private_path", py_lp_ctx_private_path, METH_VARARGS,
     428             :                 "S.private_path(name) -> path\n" },
     429             :         { "services", py_lp_ctx_services, METH_NOARGS,
     430             :                 "S.services() -> list" },
     431             :         { "server_role", py_lp_ctx_server_role, METH_NOARGS,
     432             :                 "S.server_role() -> value\n"
     433             :                 "Get the server role." },
     434             :         { "dump", py_lp_dump, METH_VARARGS,
     435             :                 "S.dump(show_defaults=False, file_name='', mode='w')" },
     436             :         { "dump_a_parameter", py_lp_dump_a_parameter, METH_VARARGS,
     437             :                 "S.dump_a_parameter(name, service_name, file_name='', mode='w')" },
     438             :         { "log_level", py_lp_log_level, METH_NOARGS,
     439             :                 "S.log_level() -> int\n Get the active log level" },
     440             :         { "samdb_url", py_samdb_url, METH_NOARGS,
     441             :                 "S.samdb_url() -> string\n"
     442             :                 "Returns the current URL for sam.ldb." },
     443             :         { "cache_path", py_cache_path, METH_VARARGS,
     444             :                 "S.cache_path(name) -> string\n"
     445             :                 "Returns a path in the Samba cache directory." },
     446             :         { "state_path", py_state_path, METH_VARARGS,
     447             :                 "S.state_path(name) -> string\n"
     448             :                 "Returns a path in the Samba state directory." },
     449             :         {0}
     450             : };
     451             : 
     452           1 : static PyObject *py_lp_ctx_default_service(PyObject *self, void *closure)
     453             : {
     454           2 :         return PyLoadparmService_FromService(lpcfg_default_service(PyLoadparmContext_AsLoadparmContext(self)));
     455             : }
     456             : 
     457        4316 : static PyObject *py_lp_ctx_config_file(PyObject *self, void *closure)
     458             : {
     459        4316 :         const char *configfile = lpcfg_configfile(PyLoadparmContext_AsLoadparmContext(self));
     460        4316 :         if (configfile == NULL)
     461           0 :                 Py_RETURN_NONE;
     462             :         else
     463        4316 :                 return PyUnicode_FromString(configfile);
     464             : }
     465             : 
     466           0 : static PyObject *py_lp_ctx_weak_crypto(PyObject *self, void *closure)
     467             : {
     468           0 :         enum samba_weak_crypto weak_crypto =
     469           0 :                 lpcfg_weak_crypto(PyLoadparmContext_AsLoadparmContext(self));
     470             : 
     471           0 :         switch(weak_crypto) {
     472           0 :         case SAMBA_WEAK_CRYPTO_UNKNOWN:
     473           0 :                 Py_RETURN_NONE;
     474           0 :         case SAMBA_WEAK_CRYPTO_ALLOWED:
     475           0 :                 return PyUnicode_FromString("allowed");
     476           0 :         case SAMBA_WEAK_CRYPTO_DISALLOWED:
     477           0 :                 return PyUnicode_FromString("disallowed");
     478             :         }
     479             : 
     480           0 :         Py_RETURN_NONE;
     481             : }
     482             : 
     483             : static PyGetSetDef py_lp_ctx_getset[] = {
     484             :         {
     485             :                 .name = discard_const_p(char, "default_service"),
     486             :                 .get  = (getter)py_lp_ctx_default_service,
     487             :         },
     488             :         {
     489             :                 .name = discard_const_p(char, "configfile"),
     490             :                 .get  = (getter)py_lp_ctx_config_file,
     491             :                 .doc  = discard_const_p(char, "Name of last config file that was loaded.")
     492             :         },
     493             :         {
     494             :                 .name = discard_const_p(char, "weak_crypto"),
     495             :                 .get  = (getter)py_lp_ctx_weak_crypto,
     496             :                 .doc  = discard_const_p(char, "If weak crypto is allowed.")
     497             :         },
     498             :         { .name = NULL }
     499             : };
     500             : 
     501       20199 : static PyObject *py_lp_ctx_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     502             : {
     503       20199 :         const char *kwnames[] = {"filename_for_non_global_lp", NULL};
     504             :         PyObject *lp_ctx;
     505       20199 :         const char *non_global_conf = NULL;
     506             :         struct loadparm_context *ctx;
     507             : 
     508       20199 :         if (!PyArg_ParseTupleAndKeywords(args,
     509             :                                          kwargs,
     510             :                                          "|s",
     511             :                                          discard_const_p(char *,
     512             :                                                          kwnames),
     513             :                                          &non_global_conf)) {
     514           0 :                 return NULL;
     515             :         }
     516             : 
     517             :         /*
     518             :          * by default, any LoadParm python objects map to a single global
     519             :          * underlying object. The filename_for_non_global_lp arg overrides this
     520             :          * default behaviour and creates a separate underlying LoadParm object.
     521             :          */
     522       20199 :         if (non_global_conf != NULL) {
     523             :                 bool ok;
     524          87 :                 ctx = loadparm_init(NULL);
     525          87 :                 if (ctx == NULL) {
     526           0 :                         PyErr_NoMemory();
     527           0 :                         return NULL;
     528             :                 }
     529             : 
     530          87 :                 lp_ctx = pytalloc_reference(type, ctx);
     531          87 :                 if (lp_ctx == NULL) {
     532           0 :                         PyErr_NoMemory();
     533           0 :                         return NULL;
     534             :                 }
     535             : 
     536         169 :                 ok = lpcfg_load_no_global(
     537          87 :                         PyLoadparmContext_AsLoadparmContext(lp_ctx),
     538             :                         non_global_conf);
     539          87 :                 if (!ok) {
     540           2 :                         PyErr_Format(PyExc_ValueError,
     541             :                                      "Could not load non-global conf %s",
     542             :                                      non_global_conf);
     543           2 :                         return NULL;
     544             :                 }
     545          84 :                 return lp_ctx;
     546             :         } else{
     547       20112 :                 return pytalloc_reference(type, loadparm_init_global(false));
     548             :         }
     549             : }
     550             : 
     551           7 : static Py_ssize_t py_lp_ctx_len(PyObject *self)
     552             : {
     553           7 :         return lpcfg_numservices(PyLoadparmContext_AsLoadparmContext(self));
     554             : }
     555             : 
     556           3 : static PyObject *py_lp_ctx_getitem(PyObject *self, PyObject *name)
     557             : {
     558             :         struct loadparm_service *service;
     559           3 :         if (!PyUnicode_Check(name)) {
     560           0 :                 PyErr_SetString(PyExc_TypeError, "Only string subscripts are supported");
     561           0 :                 return NULL;
     562             :         }
     563           3 :         service = lpcfg_service(PyLoadparmContext_AsLoadparmContext(self), PyUnicode_AsUTF8(name));
     564           3 :         if (service == NULL) {
     565           2 :                 PyErr_SetString(PyExc_KeyError, "No such section");
     566           2 :                 return NULL;
     567             :         }
     568           1 :         return PyLoadparmService_FromService(service);
     569             : }
     570             : 
     571             : static PyMappingMethods py_lp_ctx_mapping = {
     572             :         .mp_length = (lenfunc)py_lp_ctx_len,
     573             :         .mp_subscript = (binaryfunc)py_lp_ctx_getitem,
     574             : };
     575             : 
     576             : PyTypeObject PyLoadparmContext = {
     577             :         .tp_name = "param.LoadParm",
     578             :         .tp_getset = py_lp_ctx_getset,
     579             :         .tp_methods = py_lp_ctx_methods,
     580             :         .tp_new = py_lp_ctx_new,
     581             :         .tp_as_mapping = &py_lp_ctx_mapping,
     582             :         .tp_flags = Py_TPFLAGS_DEFAULT,
     583             : };
     584             : 
     585           1 : static PyObject *py_lp_service_dump(PyObject *self, PyObject *args)
     586             : {
     587           1 :         bool show_defaults = false;
     588             :         FILE *f;
     589           1 :         const char *file_name = "";
     590           1 :         const char *mode = "w";
     591           1 :         struct loadparm_service *service = PyLoadparmService_AsLoadparmService(self);
     592             :         struct loadparm_service *default_service;
     593             :         PyObject *py_default_service;
     594             : 
     595           1 :         if (!PyArg_ParseTuple(args, "O|bss", &py_default_service, &show_defaults, &file_name, &mode))
     596           0 :                 return NULL;
     597             : 
     598           1 :         if (file_name[0] == '\0') {
     599           1 :                 f = stdout;
     600             :         } else {
     601           0 :                 f = fopen(file_name, mode);
     602             :         }
     603             : 
     604           1 :         if (f == NULL) {
     605           0 :                 return NULL;
     606             :         }
     607             : 
     608           1 :         if (!PyObject_TypeCheck(py_default_service, &PyLoadparmService)) {
     609           0 :                 PyErr_SetNone(PyExc_TypeError);
     610           0 :                 if (f != stdout) {
     611           0 :                         fclose(f);
     612             :                 }
     613           0 :                 return NULL;
     614             :         }
     615             : 
     616           1 :         default_service = PyLoadparmService_AsLoadparmService(py_default_service);
     617             : 
     618           1 :         lpcfg_dump_one(f, show_defaults, service, default_service);
     619             : 
     620           1 :         if (f != stdout) {
     621           0 :                 fclose(f);
     622             :         }
     623             : 
     624           1 :         Py_RETURN_NONE;
     625             : }
     626             : 
     627             : static PyMethodDef py_lp_service_methods[] = {
     628             :         { "dump", (PyCFunction)py_lp_service_dump, METH_VARARGS, 
     629             :                 "S.dump(default_service, show_defaults=False, file_name='', mode='w')" },
     630             :         {0}
     631             : };
     632             : 
     633             : PyTypeObject PyLoadparmService = {
     634             :         .tp_name = "param.LoadparmService",
     635             :         .tp_methods = py_lp_service_methods,
     636             :         .tp_flags = Py_TPFLAGS_DEFAULT,
     637             : };
     638             : 
     639         190 : static PyObject *py_data_dir(PyObject *self)
     640             : {
     641         190 :         return PyUnicode_FromString(dyn_DATADIR);
     642             : }
     643             : 
     644           0 : static PyObject *py_default_path(PyObject *self, PyObject *Py_UNUSED(ignored))
     645             : {
     646           0 :         return PyUnicode_FromString(lp_default_path());
     647             : }
     648             : 
     649        7662 : static PyObject *py_setup_dir(PyObject *self, PyObject *Py_UNUSED(ignored))
     650             : {
     651        7662 :         return PyUnicode_FromString(dyn_SETUPDIR);
     652             : }
     653             : 
     654       24495 : static PyObject *py_modules_dir(PyObject *self, PyObject *Py_UNUSED(ignored))
     655             : {
     656       24495 :         return PyUnicode_FromString(dyn_MODULESDIR);
     657             : }
     658             : 
     659         494 : static PyObject *py_bin_dir(PyObject *self, PyObject *Py_UNUSED(ignored))
     660             : {
     661         494 :         return PyUnicode_FromString(dyn_BINDIR);
     662             : }
     663             : 
     664           0 : static PyObject *py_sbin_dir(PyObject *self, PyObject *Py_UNUSED(ignored))
     665             : {
     666           0 :         return PyUnicode_FromString(dyn_SBINDIR);
     667             : }
     668             : 
     669             : static PyMethodDef pyparam_methods[] = {
     670             :         { "data_dir", (PyCFunction)py_data_dir, METH_NOARGS,
     671             :                 "Returns the compiled in location of data directory." },
     672             :         { "default_path", (PyCFunction)py_default_path, METH_NOARGS,
     673             :                 "Returns the default smb.conf path." },
     674             :         { "setup_dir", (PyCFunction)py_setup_dir, METH_NOARGS,
     675             :                 "Returns the compiled in location of provision templates." },
     676             :         { "modules_dir", (PyCFunction)py_modules_dir, METH_NOARGS,
     677             :                 "Returns the compiled in location of modules." },
     678             :         { "bin_dir", (PyCFunction)py_bin_dir, METH_NOARGS,
     679             :                 "Returns the compiled in BINDIR." },
     680             :         { "sbin_dir", (PyCFunction)py_sbin_dir, METH_NOARGS,
     681             :                 "Returns the compiled in SBINDIR." },
     682             :         {0}
     683             : };
     684             : 
     685             : static struct PyModuleDef moduledef = {
     686             :         PyModuleDef_HEAD_INIT,
     687             :         .m_name = "param",
     688             :         .m_doc = "Parsing and writing Samba configuration files.",
     689             :         .m_size = -1,
     690             :         .m_methods = pyparam_methods,
     691             : };
     692             : 
     693       11823 : MODULE_INIT_FUNC(param)
     694             : {
     695             :         PyObject *m;
     696       11823 :         PyTypeObject *talloc_type = pytalloc_GetObjectType();
     697       11823 :         if (talloc_type == NULL)
     698           0 :                 return NULL;
     699             : 
     700       11823 :         if (pytalloc_BaseObject_PyType_Ready(&PyLoadparmContext) < 0)
     701           0 :                 return NULL;
     702             : 
     703       11823 :         if (pytalloc_BaseObject_PyType_Ready(&PyLoadparmService) < 0)
     704           0 :                 return NULL;
     705             : 
     706       11823 :         m = PyModule_Create(&moduledef);
     707       11823 :         if (m == NULL)
     708           0 :                 return NULL;
     709             : 
     710       11823 :         Py_INCREF(&PyLoadparmContext);
     711       11823 :         PyModule_AddObject(m, "LoadParm", (PyObject *)&PyLoadparmContext);
     712       11823 :         return m;
     713             : }

Generated by: LCOV version 1.13