python: Add DsExtendedError Exception
[bbaumbach/samba-autobuild/.git] / python / pyglue.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
4    Copyright (C) Matthias Dieter Wallnöfer          2009
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 "includes.h"
22 #include "version.h"
23 #include "param/pyparam.h"
24 #include "lib/socket/netif.h"
25
26 void init_glue(void);
27 static PyObject *PyExc_NTSTATUSError;
28 static PyObject *PyExc_WERRORError;
29 static PyObject *PyExc_HRESULTError;
30 static PyObject *PyExc_DsExtendedError;
31
32 static PyObject *py_generate_random_str(PyObject *self, PyObject *args)
33 {
34         int len;
35         PyObject *ret;
36         char *retstr;
37         if (!PyArg_ParseTuple(args, "i", &len))
38                 return NULL;
39
40         retstr = generate_random_str(NULL, len);
41         ret = PyString_FromString(retstr);
42         talloc_free(retstr);
43         return ret;
44 }
45
46 static PyObject *py_generate_random_password(PyObject *self, PyObject *args)
47 {
48         int min, max;
49         PyObject *ret;
50         char *retstr;
51         if (!PyArg_ParseTuple(args, "ii", &min, &max))
52                 return NULL;
53
54         retstr = generate_random_password(NULL, min, max);
55         if (retstr == NULL) {
56                 return NULL;
57         }
58         ret = PyString_FromString(retstr);
59         talloc_free(retstr);
60         return ret;
61 }
62
63 static PyObject *py_unix2nttime(PyObject *self, PyObject *args)
64 {
65         time_t t;
66         unsigned int _t;
67         NTTIME nt;
68
69         if (!PyArg_ParseTuple(args, "I", &_t)) {
70                 return NULL;
71         }
72         t = _t;
73
74         unix_to_nt_time(&nt, t);
75
76         return PyLong_FromLongLong((uint64_t)nt);
77 }
78
79 static PyObject *py_nttime2unix(PyObject *self, PyObject *args)
80 {
81         time_t t;
82         NTTIME nt;
83         if (!PyArg_ParseTuple(args, "K", &nt))
84                 return NULL;
85
86         t = nt_time_to_unix(nt);
87
88         return PyInt_FromLong((uint64_t)t);
89 }
90
91 static PyObject *py_nttime2string(PyObject *self, PyObject *args)
92 {
93         PyObject *ret;
94         NTTIME nt;
95         TALLOC_CTX *tmp_ctx;
96         const char *string;
97         if (!PyArg_ParseTuple(args, "K", &nt))
98                 return NULL;
99
100         tmp_ctx = talloc_new(NULL);
101         if (tmp_ctx == NULL) {
102                 PyErr_NoMemory();
103                 return NULL;
104         }
105
106         string = nt_time_string(tmp_ctx, nt);
107         ret =  PyString_FromString(string);
108
109         talloc_free(tmp_ctx);
110
111         return ret;
112 }
113
114 static PyObject *py_set_debug_level(PyObject *self, PyObject *args)
115 {
116         unsigned level;
117         if (!PyArg_ParseTuple(args, "I", &level))
118                 return NULL;
119         (DEBUGLEVEL) = level;
120         Py_RETURN_NONE;
121 }
122
123 static PyObject *py_get_debug_level(PyObject *self)
124 {
125         return PyInt_FromLong(DEBUGLEVEL);
126 }
127
128 static PyObject *py_is_ntvfs_fileserver_built(PyObject *self)
129 {
130 #ifdef WITH_NTVFS_FILESERVER
131         Py_RETURN_TRUE;
132 #else
133         Py_RETURN_FALSE;
134 #endif
135 }
136
137 /*
138   return the list of interface IPs we have configured
139   takes an loadparm context, returns a list of IPs in string form
140
141   Does not return addresses on 127.0.0.0/8
142  */
143 static PyObject *py_interface_ips(PyObject *self, PyObject *args)
144 {
145         PyObject *pylist;
146         int count;
147         TALLOC_CTX *tmp_ctx;
148         PyObject *py_lp_ctx;
149         struct loadparm_context *lp_ctx;
150         struct interface *ifaces;
151         int i, ifcount;
152         int all_interfaces = 1;
153
154         if (!PyArg_ParseTuple(args, "O|i", &py_lp_ctx, &all_interfaces))
155                 return NULL;
156
157         tmp_ctx = talloc_new(NULL);
158         if (tmp_ctx == NULL) {
159                 PyErr_NoMemory();
160                 return NULL;
161         }
162
163         lp_ctx = lpcfg_from_py_object(tmp_ctx, py_lp_ctx);
164         if (lp_ctx == NULL) {
165                 talloc_free(tmp_ctx);
166                 return NULL;
167         }
168
169         load_interface_list(tmp_ctx, lp_ctx, &ifaces);
170
171         count = iface_list_count(ifaces);
172
173         /* first count how many are not loopback addresses */
174         for (ifcount = i = 0; i<count; i++) {
175                 const char *ip = iface_list_n_ip(ifaces, i);
176
177                 if (all_interfaces) {
178                         ifcount++;
179                         continue;
180                 }
181
182                 if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) {
183                         continue;
184                 }
185
186                 if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) {
187                         continue;
188                 }
189
190                 if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) {
191                         continue;
192                 }
193
194                 if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) {
195                         continue;
196                 }
197
198                 ifcount++;
199         }
200
201         pylist = PyList_New(ifcount);
202         for (ifcount = i = 0; i<count; i++) {
203                 const char *ip = iface_list_n_ip(ifaces, i);
204
205                 if (all_interfaces) {
206                         PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
207                         ifcount++;
208                         continue;
209                 }
210
211                 if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) {
212                         continue;
213                 }
214
215                 if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) {
216                         continue;
217                 }
218
219                 if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) {
220                         continue;
221                 }
222
223                 if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) {
224                         continue;
225                 }
226
227                 PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
228                 ifcount++;
229         }
230         talloc_free(tmp_ctx);
231         return pylist;
232 }
233
234 static PyObject *py_strcasecmp_m(PyObject *self, PyObject *args)
235 {
236         char *s1, *s2;
237
238         if (!PyArg_ParseTuple(args, "ss", &s1, &s2))
239                 return NULL;
240
241         return PyInt_FromLong(strcasecmp_m(s1, s2));
242 }
243
244 static PyObject *py_strstr_m(PyObject *self, PyObject *args)
245 {
246         char *s1, *s2, *ret;
247
248         if (!PyArg_ParseTuple(args, "ss", &s1, &s2))
249                 return NULL;
250
251         ret = strstr_m(s1, s2);
252         if (!ret) {
253                 Py_RETURN_NONE;
254         }
255         return PyString_FromString(ret);
256 }
257
258 static PyMethodDef py_misc_methods[] = {
259         { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
260                 "generate_random_str(len) -> string\n"
261                 "Generate random string with specified length." },
262         { "generate_random_password", (PyCFunction)py_generate_random_password,
263                 METH_VARARGS, "generate_random_password(min, max) -> string\n"
264                 "Generate random password with a length >= min and <= max." },
265         { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
266                 "unix2nttime(timestamp) -> nttime" },
267         { "nttime2unix", (PyCFunction)py_nttime2unix, METH_VARARGS,
268                 "nttime2unix(nttime) -> timestamp" },
269         { "nttime2string", (PyCFunction)py_nttime2string, METH_VARARGS,
270                 "nttime2string(nttime) -> string" },
271         { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
272                 "set debug level" },
273         { "get_debug_level", (PyCFunction)py_get_debug_level, METH_NOARGS,
274                 "get debug level" },
275         { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
276                 "interface_ips(lp_ctx[, all_interfaces) -> list_of_ifaces\n"
277                 "\n"
278                 "get interface IP address list"},
279         { "strcasecmp_m", (PyCFunction)py_strcasecmp_m, METH_VARARGS,
280                 "(for testing) compare two strings using Samba's strcasecmp_m()"},
281         { "strstr_m", (PyCFunction)py_strstr_m, METH_VARARGS,
282                 "(for testing) find one string in another with Samba's strstr_m()"},
283         { "is_ntvfs_fileserver_built", (PyCFunction)py_is_ntvfs_fileserver_built, METH_NOARGS,
284                 "is the NTVFS file server built in this installation?" },
285         { NULL }
286 };
287
288 void init_glue(void)
289 {
290         PyObject *m;
291
292         debug_setup_talloc_log();
293
294         m = Py_InitModule3("_glue", py_misc_methods, 
295                            "Python bindings for miscellaneous Samba functions.");
296         if (m == NULL)
297                 return;
298
299         PyModule_AddObject(m, "version",
300                                            PyString_FromString(SAMBA_VERSION_STRING));
301         PyExc_NTSTATUSError = PyErr_NewException(discard_const_p(char, "samba.NTSTATUSError"), PyExc_RuntimeError, NULL);
302         if (PyExc_NTSTATUSError != NULL) {
303                 Py_INCREF(PyExc_NTSTATUSError);
304                 PyModule_AddObject(m, "NTSTATUSError", PyExc_NTSTATUSError);
305         }
306
307         PyExc_WERRORError = PyErr_NewException(discard_const_p(char, "samba.WERRORError"), PyExc_RuntimeError, NULL);
308         if (PyExc_WERRORError != NULL) {
309                 Py_INCREF(PyExc_WERRORError);
310                 PyModule_AddObject(m, "WERRORError", PyExc_WERRORError);
311         }
312
313         PyExc_HRESULTError = PyErr_NewException(discard_const_p(char, "samba.HRESULTError"), PyExc_RuntimeError, NULL);
314         if (PyExc_HRESULTError != NULL) {
315                 Py_INCREF(PyExc_HRESULTError);
316                 PyModule_AddObject(m, "HRESULTError", PyExc_HRESULTError);
317         }
318
319         PyExc_DsExtendedError = PyErr_NewException(discard_const_p(char, "samba.DsExtendedError"), PyExc_RuntimeError, NULL);
320         if (PyExc_DsExtendedError != NULL) {
321                 Py_INCREF(PyExc_DsExtendedError);
322                 PyModule_AddObject(m, "DsExtendedError", PyExc_DsExtendedError);
323         }
324
325 }
326