pydsdb: Move write_prefixes_from_schema_to_ldb to pydsdb from pyglue.
[metze/samba/wip.git] / source4 / scripting / 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 "ldb.h"
23 #include "ldb_errors.h"
24 #include "ldb_wrap.h"
25 #include "param/param.h"
26 #include "auth/credentials/credentials.h"
27 #include "dsdb/samdb/samdb.h"
28 #include "lib/ldb-samba/ldif_handlers.h"
29 #include "librpc/ndr/libndr.h"
30 #include "version.h"
31 #include "lib/ldb/pyldb.h"
32 #include "libcli/util/pyerrors.h"
33 #include "libcli/security/security.h"
34 #include "auth/pyauth.h"
35 #include "param/pyparam.h"
36 #include "auth/credentials/pycredentials.h"
37 #include "lib/socket/netif.h"
38 #include "lib/socket/netif_proto.h"
39
40 /* FIXME: These should be in a header file somewhere, once we finish moving
41  * away from SWIG .. */
42 #define PyErr_LDB_OR_RAISE(py_ldb, ldb) \
43 /*      if (!PyLdb_Check(py_ldb)) { \
44                 PyErr_SetString(py_ldb_get_exception(), "Ldb connection object required"); \
45                 return NULL; \
46         } */\
47         ldb = PyLdb_AsLdbContext(py_ldb);
48
49 static PyObject *py_generate_random_str(PyObject *self, PyObject *args)
50 {
51         int len;
52         PyObject *ret;
53         char *retstr;
54         if (!PyArg_ParseTuple(args, "i", &len))
55                 return NULL;
56
57         retstr = generate_random_str(NULL, len);
58         ret = PyString_FromString(retstr);
59         talloc_free(retstr);
60         return ret;
61 }
62
63 static PyObject *py_generate_random_password(PyObject *self, PyObject *args)
64 {
65         int min, max;
66         PyObject *ret;
67         char *retstr;
68         if (!PyArg_ParseTuple(args, "ii", &min, &max))
69                 return NULL;
70
71         retstr = generate_random_password(NULL, min, max);
72         if (retstr == NULL) {
73                 return NULL;
74         }
75         ret = PyString_FromString(retstr);
76         talloc_free(retstr);
77         return ret;
78 }
79
80 static PyObject *py_unix2nttime(PyObject *self, PyObject *args)
81 {
82         time_t t;
83         NTTIME nt;
84         if (!PyArg_ParseTuple(args, "I", &t))
85                 return NULL;
86
87         unix_to_nt_time(&nt, t);
88
89         return PyLong_FromLongLong((uint64_t)nt);
90 }
91
92 static PyObject *py_nttime2unix(PyObject *self, PyObject *args)
93 {
94         time_t t;
95         NTTIME nt;
96         if (!PyArg_ParseTuple(args, "K", &nt))
97                 return NULL;
98
99         t = nt_time_to_unix(nt);
100
101         return PyInt_FromLong((uint64_t)t);
102 }
103
104 static PyObject *py_nttime2string(PyObject *self, PyObject *args)
105 {
106         PyObject *ret;
107         NTTIME nt;
108         TALLOC_CTX *tmp_ctx;
109         const char *string;
110         if (!PyArg_ParseTuple(args, "K", &nt))
111                 return NULL;
112
113         tmp_ctx = talloc_new(NULL);
114
115         string = nt_time_string(tmp_ctx, nt);
116         ret =  PyString_FromString(string);
117
118         talloc_free(tmp_ctx);
119
120         return ret;
121 }
122
123 static PyObject *py_set_debug_level(PyObject *self, PyObject *args)
124 {
125         unsigned level;
126         if (!PyArg_ParseTuple(args, "I", &level))
127                 return NULL;
128         (DEBUGLEVEL) = level;
129         Py_RETURN_NONE;
130 }
131
132
133
134 /*
135   return the list of interface IPs we have configured
136   takes an loadparm context, returns a list of IPs in string form
137
138   Does not return addresses on 127.0.0.0/8
139  */
140 static PyObject *py_interface_ips(PyObject *self, PyObject *args)
141 {
142         PyObject *pylist;
143         int count;
144         TALLOC_CTX *tmp_ctx;
145         PyObject *py_lp_ctx;
146         struct loadparm_context *lp_ctx;
147         struct interface *ifaces;
148         int i, ifcount;
149         int all_interfaces;
150
151         if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
152                 return NULL;
153
154         tmp_ctx = talloc_new(NULL);
155
156         lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
157         if (lp_ctx == NULL) {
158                 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
159                 talloc_free(tmp_ctx);
160                 return NULL;
161         }
162
163         load_interfaces(tmp_ctx, lp_interfaces(lp_ctx), &ifaces);
164
165         count = iface_count(ifaces);
166
167         /* first count how many are not loopback addresses */
168         for (ifcount = i = 0; i<count; i++) {
169                 const char *ip = iface_n_ip(ifaces, i);
170                 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
171                         ifcount++;
172                 }
173         }
174
175         pylist = PyList_New(ifcount);
176         for (ifcount = i = 0; i<count; i++) {
177                 const char *ip = iface_n_ip(ifaces, i);
178                 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
179                         PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
180                         ifcount++;
181                 }
182         }
183         talloc_free(tmp_ctx);
184         return pylist;
185 }
186
187
188 static PyMethodDef py_misc_methods[] = {
189         { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
190                 "generate_random_str(len) -> string\n"
191                 "Generate random string with specified length." },
192         { "generate_random_password", (PyCFunction)py_generate_random_password, METH_VARARGS,
193                 "generate_random_password(min, max) -> string\n"
194                 "Generate random password with a length >= min and <= max." },
195         { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
196                 "unix2nttime(timestamp) -> nttime" },
197         { "nttime2unix", (PyCFunction)py_nttime2unix, METH_VARARGS,
198                 "nttime2unix(nttime) -> timestamp" },
199         { "nttime2string", (PyCFunction)py_nttime2string, METH_VARARGS,
200                 "nttime2string(nttime) -> string" },
201         { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
202                 "set debug level" },
203         { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
204                 "get interface IP address list"},
205         { NULL }
206 };
207
208 void init_glue(void)
209 {
210         PyObject *m;
211
212         debug_setup_talloc_log();
213
214         m = Py_InitModule3("_glue", py_misc_methods, 
215                            "Python bindings for miscellaneous Samba functions.");
216         if (m == NULL)
217                 return;
218
219         PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
220
221         /* one of the most annoying things about python scripts is
222            that they don't die when you hit control-C. This fixes that
223            sillyness. As we do all database operations using
224            transactions, this is also safe. In fact, not dying
225            immediately is unsafe as we could end up treating the
226            control-C exception as a different error and try to modify
227            as database incorrectly 
228         */
229         signal(SIGINT, SIG_DFL);
230 }
231