6fcab80ce66f6e37deb319508ebf4fc205349ece
[kai/samba-autobuild/.git] / source4 / auth / credentials / pycredentials.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
4    
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "includes.h"
20 #include <Python.h>
21 #include "pycredentials.h"
22 #include "param/param.h"
23 #include "lib/cmdline/credentials.h"
24 #include "librpc/gen_ndr/samr.h" /* for struct samr_Password */
25 #include "libcli/util/pyerrors.h"
26 #include "param/pyparam.h"
27
28 #ifndef Py_RETURN_NONE
29 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
30 #endif
31
32 struct cli_credentials *cli_credentials_from_py_object(PyObject *py_obj)
33 {
34     if (py_obj == Py_None) {
35         return cli_credentials_init_anon(NULL);
36     }
37         
38     /* FIXME: Check type? */
39     return PyCredentials_AsCliCredentials(py_obj);
40 }
41
42 static PyObject *PyString_FromStringOrNULL(const char *str)
43 {
44         if (str == NULL)
45                 Py_RETURN_NONE;
46         return PyString_FromString(str);
47 }
48
49 static PyObject *py_creds_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
50 {
51         return py_talloc_import(type, cli_credentials_init(NULL));
52 }
53
54 static PyObject *py_creds_get_username(py_talloc_Object *self)
55 {
56         return PyString_FromStringOrNULL(cli_credentials_get_username(self->ptr));
57 }
58
59 static PyObject *py_creds_set_username(py_talloc_Object *self, PyObject *args)
60 {
61         char *newval;
62         enum credentials_obtained obt = CRED_SPECIFIED;
63         if (!PyArg_ParseTuple(args, "s|i", &newval, &obt))
64                 return NULL;
65
66         return PyBool_FromLong(cli_credentials_set_username(self->ptr, newval, obt));
67 }
68
69 static PyObject *py_creds_get_password(py_talloc_Object *self)
70 {
71         return PyString_FromStringOrNULL(cli_credentials_get_password(self->ptr));
72 }
73
74
75 static PyObject *py_creds_set_password(py_talloc_Object *self, PyObject *args)
76 {
77         char *newval;
78         enum credentials_obtained obt = CRED_SPECIFIED;
79         if (!PyArg_ParseTuple(args, "s|i", &newval, &obt))
80                 return NULL;
81
82         return PyBool_FromLong(cli_credentials_set_password(self->ptr, newval, obt));
83 }
84
85 static PyObject *py_creds_get_domain(py_talloc_Object *self)
86 {
87         return PyString_FromStringOrNULL(cli_credentials_get_domain(self->ptr));
88 }
89
90 static PyObject *py_creds_set_domain(py_talloc_Object *self, PyObject *args)
91 {
92         char *newval;
93         enum credentials_obtained obt = CRED_SPECIFIED;
94         if (!PyArg_ParseTuple(args, "s|i", &newval, &obt))
95                 return NULL;
96
97         return PyBool_FromLong(cli_credentials_set_domain(self->ptr, newval, obt));
98 }
99
100 static PyObject *py_creds_get_realm(py_talloc_Object *self)
101 {
102         return PyString_FromStringOrNULL(cli_credentials_get_realm(self->ptr));
103 }
104
105 static PyObject *py_creds_set_realm(py_talloc_Object *self, PyObject *args)
106 {
107         char *newval;
108         enum credentials_obtained obt = CRED_SPECIFIED;
109         if (!PyArg_ParseTuple(args, "s|i", &newval, &obt))
110                 return NULL;
111
112         return PyBool_FromLong(cli_credentials_set_realm(self->ptr, newval, obt));
113 }
114
115 static PyObject *py_creds_get_bind_dn(py_talloc_Object *self)
116 {
117         return PyString_FromStringOrNULL(cli_credentials_get_bind_dn(self->ptr));
118 }
119
120 static PyObject *py_creds_set_bind_dn(py_talloc_Object *self, PyObject *args)
121 {
122         char *newval;
123         if (!PyArg_ParseTuple(args, "s", &newval))
124                 return NULL;
125
126         return PyBool_FromLong(cli_credentials_set_bind_dn(self->ptr, newval));
127 }
128
129 static PyObject *py_creds_get_workstation(py_talloc_Object *self)
130 {
131         return PyString_FromStringOrNULL(cli_credentials_get_workstation(self->ptr));
132 }
133
134 static PyObject *py_creds_set_workstation(py_talloc_Object *self, PyObject *args)
135 {
136         char *newval;
137         enum credentials_obtained obt = CRED_SPECIFIED;
138         if (!PyArg_ParseTuple(args, "s|i", &newval, &obt))
139                 return NULL;
140
141         return PyBool_FromLong(cli_credentials_set_workstation(self->ptr, newval, obt));
142 }
143
144 static PyObject *py_creds_is_anonymous(py_talloc_Object *self)
145 {
146         return PyBool_FromLong(cli_credentials_is_anonymous(self->ptr));
147 }
148
149 static PyObject *py_creds_set_anonymous(py_talloc_Object *self)
150 {
151         cli_credentials_set_anonymous(self->ptr);
152         Py_RETURN_NONE;
153 }
154
155 static PyObject *py_creds_authentication_requested(py_talloc_Object *self)
156 {
157         return PyBool_FromLong(cli_credentials_authentication_requested(self->ptr));
158 }
159
160 static PyObject *py_creds_wrong_password(py_talloc_Object *self)
161 {
162         return PyBool_FromLong(cli_credentials_wrong_password(self->ptr));
163 }
164
165 static PyObject *py_creds_set_cmdline_callbacks(py_talloc_Object *self)
166 {
167         return PyBool_FromLong(cli_credentials_set_cmdline_callbacks(self->ptr));
168 }
169
170 static PyObject *py_creds_parse_string(py_talloc_Object *self, PyObject *args)
171 {
172         char *newval;
173         enum credentials_obtained obt = CRED_SPECIFIED;
174         if (!PyArg_ParseTuple(args, "s|i", &newval, &obt))
175                 return NULL;
176
177         cli_credentials_parse_string(self->ptr, newval, obt);
178         Py_RETURN_NONE;
179 }
180
181 static PyObject *py_creds_get_nt_hash(py_talloc_Object *self)
182 {
183         const struct samr_Password *ntpw = cli_credentials_get_nt_hash(self->ptr, self->ptr);
184
185         return PyString_FromStringAndSize((char *)ntpw->hash, 16);
186 }
187
188 static PyObject *py_creds_set_kerberos_state(py_talloc_Object *self, PyObject *args)
189 {
190         int state;
191         if (!PyArg_ParseTuple(args, "i", &state))
192                 return NULL;
193
194         cli_credentials_set_kerberos_state(self->ptr, state);
195         Py_RETURN_NONE;
196 }
197
198 static PyObject *py_creds_guess(py_talloc_Object *self, PyObject *args)
199 {
200         PyObject *py_lp_ctx = Py_None;
201         struct loadparm_context *lp_ctx;
202         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
203                 return NULL;
204
205         lp_ctx = lp_from_py_object(py_lp_ctx);
206         if (lp_ctx == NULL) 
207                 return NULL;
208
209         cli_credentials_guess(self->ptr, lp_ctx);
210
211         Py_RETURN_NONE;
212 }
213
214 static PyObject *py_creds_set_machine_account(py_talloc_Object *self, PyObject *args)
215 {
216         PyObject *py_lp_ctx = Py_None;
217         struct loadparm_context *lp_ctx;
218         NTSTATUS status;
219         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
220                 return NULL;
221
222         lp_ctx = lp_from_py_object(py_lp_ctx);
223         if (lp_ctx == NULL) 
224                 return NULL;
225
226         status = cli_credentials_set_machine_account(self->ptr, lp_ctx);
227         PyErr_NTSTATUS_IS_ERR_RAISE(status);
228
229         Py_RETURN_NONE;
230 }
231
232 static PyMethodDef py_creds_methods[] = {
233         { "get_username", (PyCFunction)py_creds_get_username, METH_NOARGS,
234                 "S.get_username() -> username\nObtain username." },
235         { "set_username", (PyCFunction)py_creds_set_username, METH_VARARGS,
236                 "S.set_username(name, obtained=CRED_SPECIFIED) -> None\n"
237                 "Change username." },
238         { "get_password", (PyCFunction)py_creds_get_password, METH_NOARGS,
239                 "S.get_password() -> password\n"
240                 "Obtain password." },
241         { "set_password", (PyCFunction)py_creds_set_password, METH_VARARGS,
242                 "S.set_password(password, obtained=CRED_SPECIFIED) -> None\n"
243                 "Change password." },
244         { "get_domain", (PyCFunction)py_creds_get_domain, METH_NOARGS,
245                 "S.get_domain() -> domain\n"
246                 "Obtain domain name." },
247         { "set_domain", (PyCFunction)py_creds_set_domain, METH_VARARGS,
248                 "S.set_domain(domain, obtained=CRED_SPECIFIED) -> None\n"
249                 "Change domain name." },
250         { "get_realm", (PyCFunction)py_creds_get_realm, METH_NOARGS,
251                 "S.get_realm() -> realm\n"
252                 "Obtain realm name." },
253         { "set_realm", (PyCFunction)py_creds_set_realm, METH_VARARGS,
254                 "S.set_realm(realm, obtained=CRED_SPECIFIED) -> None\n"
255                 "Change realm name." },
256         { "get_bind_dn", (PyCFunction)py_creds_get_bind_dn, METH_NOARGS,
257                 "S.get_bind_dn() -> bind dn\n"
258                 "Obtain bind DN." },
259         { "set_bind_dn", (PyCFunction)py_creds_set_bind_dn, METH_VARARGS,
260                 "S.set_bind_dn(bind_dn) -> None\n"
261                 "Change bind DN." },
262         { "is_anonymous", (PyCFunction)py_creds_is_anonymous, METH_NOARGS,
263                 NULL },
264         { "set_anonymous", (PyCFunction)py_creds_set_anonymous, METH_NOARGS,
265                 "S.set_anonymous() -> None\n"
266                 "Use anonymous credentials." },
267         { "get_workstation", (PyCFunction)py_creds_get_workstation, METH_NOARGS,
268                 NULL },
269         { "set_workstation", (PyCFunction)py_creds_set_workstation, METH_VARARGS,
270                 NULL },
271         { "authentication_requested", (PyCFunction)py_creds_authentication_requested, METH_NOARGS,
272                 NULL },
273         { "wrong_password", (PyCFunction)py_creds_wrong_password, METH_NOARGS,
274                 "S.wrong_password() -> bool\n"
275                 "Indicate the returned password was incorrect." },
276         { "set_cmdline_callbacks", (PyCFunction)py_creds_set_cmdline_callbacks, METH_NOARGS,
277                 "S.set_cmdline_callbacks() -> bool\n"
278                 "Use command-line to obtain credentials not explicitly set." },
279         { "parse_string", (PyCFunction)py_creds_parse_string, METH_VARARGS,
280                 "S.parse_string(text, obtained=CRED_SPECIFIED) -> None\n"
281                 "Parse credentials string." },
282         { "get_nt_hash", (PyCFunction)py_creds_get_nt_hash, METH_NOARGS,
283                 NULL },
284         { "set_kerberos_state", (PyCFunction)py_creds_set_kerberos_state, METH_VARARGS,
285                 NULL },
286         { "guess", (PyCFunction)py_creds_guess, METH_VARARGS, NULL },
287         { "set_machine_account", (PyCFunction)py_creds_set_machine_account, METH_VARARGS, NULL },
288         { NULL }
289 };
290
291 PyTypeObject PyCredentials = {
292         .tp_name = "Credentials",
293         .tp_basicsize = sizeof(py_talloc_Object),
294         .tp_dealloc = py_talloc_dealloc,
295         .tp_new = py_creds_new,
296         .tp_flags = Py_TPFLAGS_DEFAULT,
297         .tp_methods = py_creds_methods,
298 };
299
300 void initcredentials(void)
301 {
302         PyObject *m;
303
304         if (PyType_Ready(&PyCredentials) < 0)
305                 return;
306
307         m = Py_InitModule3("credentials", NULL, "Credentials management.");
308         if (m == NULL)
309                 return;
310
311         PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyInt_FromLong(CRED_AUTO_USE_KERBEROS));
312         PyModule_AddObject(m, "DONT_USE_KERBEROS", PyInt_FromLong(CRED_DONT_USE_KERBEROS));
313         PyModule_AddObject(m, "MUST_USE_KERBEROS", PyInt_FromLong(CRED_MUST_USE_KERBEROS));
314
315         Py_INCREF(&PyCredentials);
316         PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
317 }