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