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