bd877941a9a5172031736e1da645b4d80ee88be1
[samba.git] / 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 <Python.h>
20 #include "python/py3compat.h"
21 #include "includes.h"
22 #include "python/modules.h"
23 #include "pycredentials.h"
24 #include "param/param.h"
25 #include "auth/credentials/credentials_internal.h"
26 #include "librpc/gen_ndr/samr.h" /* for struct samr_Password */
27 #include "librpc/gen_ndr/netlogon.h"
28 #include "libcli/util/pyerrors.h"
29 #include "libcli/auth/libcli_auth.h"
30 #include "param/pyparam.h"
31 #include <tevent.h>
32 #include "libcli/auth/libcli_auth.h"
33 #include "system/kerberos.h"
34 #include "auth/kerberos/kerberos.h"
35 #include "libcli/smb/smb_constants.h"
36
37 void initcredentials(void);
38
39 static PyObject *py_creds_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
40 {
41         return pytalloc_steal(type, cli_credentials_init(NULL));
42 }
43
44 static PyObject *py_creds_get_username(PyObject *self, PyObject *unused)
45 {
46         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
47         if (creds == NULL) {
48                 PyErr_Format(PyExc_TypeError, "Credentials expected");
49                 return NULL;
50         }
51         return PyString_FromStringOrNULL(cli_credentials_get_username(creds));
52 }
53
54 static PyObject *py_creds_set_username(PyObject *self, PyObject *args)
55 {
56         char *newval;
57         enum credentials_obtained obt = CRED_SPECIFIED;
58         int _obt = obt;
59         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
60         if (creds == NULL) {
61                 PyErr_Format(PyExc_TypeError, "Credentials expected");
62                 return NULL;
63         }
64
65         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
66                 return NULL;
67         }
68         obt = _obt;
69
70         return PyBool_FromLong(cli_credentials_set_username(creds, newval, obt));
71 }
72
73 static PyObject *py_creds_get_ntlm_username_domain(PyObject *self, PyObject *unused)
74 {
75         TALLOC_CTX *frame = talloc_stackframe();
76         const char *user = NULL;
77         const char *domain = NULL;
78         PyObject *ret = NULL;
79         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
80         if (creds == NULL) {
81                 PyErr_Format(PyExc_TypeError, "Credentials expected");
82                 return NULL;
83         }
84         cli_credentials_get_ntlm_username_domain(creds,
85                                                  frame, &user, &domain);
86         ret = Py_BuildValue("(ss)",
87                             user,
88                             domain);
89
90         TALLOC_FREE(frame);
91         return ret;
92 }
93
94 static PyObject *py_creds_get_ntlm_response(PyObject *self, PyObject *args, PyObject *kwargs)
95 {
96         TALLOC_CTX *frame = talloc_stackframe();
97         PyObject *ret = NULL;
98         int flags;
99         struct timeval tv_now;
100         NTTIME server_timestamp;
101         DATA_BLOB challenge = data_blob_null;
102         DATA_BLOB target_info = data_blob_null;
103         NTSTATUS status;
104         DATA_BLOB lm_response = data_blob_null;
105         DATA_BLOB nt_response = data_blob_null;
106         DATA_BLOB lm_session_key = data_blob_null;
107         DATA_BLOB nt_session_key = data_blob_null;
108         const char *kwnames[] = { "flags", "challenge",
109                                   "target_info",
110                                   NULL };
111         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
112         if (creds == NULL) {
113                 PyErr_Format(PyExc_TypeError, "Credentials expected");
114                 return NULL;
115         }
116
117         tv_now = timeval_current();
118         server_timestamp = timeval_to_nttime(&tv_now);
119
120         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is#|s#",
121                                          discard_const_p(char *, kwnames),
122                                          &flags,
123                                          &challenge.data,
124                                          &challenge.length,
125                                          &target_info.data,
126                                          &target_info.length)) {
127                 return NULL;
128         }
129
130         status = cli_credentials_get_ntlm_response(creds,
131                                                    frame, &flags,
132                                                    challenge,
133                                                    &server_timestamp,
134                                                    target_info,
135                                                    &lm_response, &nt_response,
136                                                    &lm_session_key, &nt_session_key);
137
138         if (!NT_STATUS_IS_OK(status)) {
139                 PyErr_SetNTSTATUS(status);
140                 TALLOC_FREE(frame);
141                 return NULL;
142         }
143
144         ret = Py_BuildValue("{sis" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN
145                                     "s" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN "}",
146                             "flags", flags,
147                             "lm_response",
148                             (const char *)lm_response.data, lm_response.length,
149                             "nt_response",
150                             (const char *)nt_response.data, nt_response.length,
151                             "lm_session_key",
152                             (const char *)lm_session_key.data, lm_session_key.length,
153                             "nt_session_key",
154                             (const char *)nt_session_key.data, nt_session_key.length);
155         TALLOC_FREE(frame);
156         return ret;
157 }
158
159 static PyObject *py_creds_get_principal(PyObject *self, PyObject *unused)
160 {
161         TALLOC_CTX *frame = talloc_stackframe();
162         PyObject *ret = NULL;
163         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
164         if (creds == NULL) {
165                 PyErr_Format(PyExc_TypeError, "Credentials expected");
166                 return NULL;
167         }
168         ret = PyString_FromStringOrNULL(cli_credentials_get_principal(creds, frame));
169         TALLOC_FREE(frame);
170         return ret;
171 }
172
173 static PyObject *py_creds_set_principal(PyObject *self, PyObject *args)
174 {
175         char *newval;
176         enum credentials_obtained obt = CRED_SPECIFIED;
177         int _obt = obt;
178         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
179         if (creds == NULL) {
180                 PyErr_Format(PyExc_TypeError, "Credentials expected");
181                 return NULL;
182         }
183
184         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
185                 return NULL;
186         }
187         obt = _obt;
188
189         return PyBool_FromLong(cli_credentials_set_principal(creds, newval, obt));
190 }
191
192 static PyObject *py_creds_get_password(PyObject *self, PyObject *unused)
193 {
194         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
195         if (creds == NULL) {
196                 PyErr_Format(PyExc_TypeError, "Credentials expected");
197                 return NULL;
198         }
199         return PyString_FromStringOrNULL(cli_credentials_get_password(creds));
200 }
201
202 static PyObject *py_creds_set_password(PyObject *self, PyObject *args)
203 {
204         const char *newval = NULL;
205         enum credentials_obtained obt = CRED_SPECIFIED;
206         int _obt = obt;
207         PyObject *result = NULL;
208         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
209         if (creds == NULL) {
210                 PyErr_Format(PyExc_TypeError, "Credentials expected");
211                 return NULL;
212         }
213
214         if (!PyArg_ParseTuple(args, PYARG_STR_UNI"|i", "utf8", &newval, &_obt)) {
215                 return NULL;
216         }
217         obt = _obt;
218
219         result = PyBool_FromLong(cli_credentials_set_password(creds, newval, obt));
220         PyMem_Free(discard_const_p(void*, newval));
221         return result;
222 }
223
224 static PyObject *py_creds_set_utf16_password(PyObject *self, PyObject *args)
225 {
226         enum credentials_obtained obt = CRED_SPECIFIED;
227         int _obt = obt;
228         PyObject *newval = NULL;
229         DATA_BLOB blob = data_blob_null;
230         Py_ssize_t size =  0;
231         int result;
232         bool ok;
233         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
234         if (creds == NULL) {
235                 PyErr_Format(PyExc_TypeError, "Credentials expected");
236                 return NULL;
237         }
238
239         if (!PyArg_ParseTuple(args, "O|i", &newval, &_obt)) {
240                 return NULL;
241         }
242         obt = _obt;
243
244         result = PyBytes_AsStringAndSize(newval, (char **)&blob.data, &size);
245         if (result != 0) {
246                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to Bytes");
247                 return NULL;
248         }
249         blob.length = size;
250
251         ok = cli_credentials_set_utf16_password(creds,
252                                                 &blob, obt);
253
254         return PyBool_FromLong(ok);
255 }
256
257 static PyObject *py_creds_get_old_password(PyObject *self, PyObject *unused)
258 {
259         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
260         if (creds == NULL) {
261                 PyErr_Format(PyExc_TypeError, "Credentials expected");
262                 return NULL;
263         }
264         return PyString_FromStringOrNULL(cli_credentials_get_old_password(creds));
265 }
266
267 static PyObject *py_creds_set_old_password(PyObject *self, PyObject *args)
268 {
269         char *oldval;
270         enum credentials_obtained obt = CRED_SPECIFIED;
271         int _obt = obt;
272         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
273         if (creds == NULL) {
274                 PyErr_Format(PyExc_TypeError, "Credentials expected");
275                 return NULL;
276         }
277
278         if (!PyArg_ParseTuple(args, "s|i", &oldval, &_obt)) {
279                 return NULL;
280         }
281         obt = _obt;
282
283         return PyBool_FromLong(cli_credentials_set_old_password(creds, oldval, obt));
284 }
285
286 static PyObject *py_creds_set_old_utf16_password(PyObject *self, PyObject *args)
287 {
288         PyObject *oldval = NULL;
289         DATA_BLOB blob = data_blob_null;
290         Py_ssize_t size =  0;
291         int result;
292         bool ok;
293         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
294         if (creds == NULL) {
295                 PyErr_Format(PyExc_TypeError, "Credentials expected");
296                 return NULL;
297         }
298
299         if (!PyArg_ParseTuple(args, "O", &oldval)) {
300                 return NULL;
301         }
302
303         result = PyBytes_AsStringAndSize(oldval, (char **)&blob.data, &size);
304         if (result != 0) {
305                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to Bytes");
306                 return NULL;
307         }
308         blob.length = size;
309
310         ok = cli_credentials_set_old_utf16_password(creds,
311                                                     &blob);
312
313         return PyBool_FromLong(ok);
314 }
315
316 static PyObject *py_creds_get_domain(PyObject *self, PyObject *unused)
317 {
318         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
319         if (creds == NULL) {
320                 PyErr_Format(PyExc_TypeError, "Credentials expected");
321                 return NULL;
322         }
323         return PyString_FromStringOrNULL(cli_credentials_get_domain(creds));
324 }
325
326 static PyObject *py_creds_set_domain(PyObject *self, PyObject *args)
327 {
328         char *newval;
329         enum credentials_obtained obt = CRED_SPECIFIED;
330         int _obt = obt;
331         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
332         if (creds == NULL) {
333                 PyErr_Format(PyExc_TypeError, "Credentials expected");
334                 return NULL;
335         }
336
337         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
338                 return NULL;
339         }
340         obt = _obt;
341
342         return PyBool_FromLong(cli_credentials_set_domain(creds, newval, obt));
343 }
344
345 static PyObject *py_creds_get_realm(PyObject *self, PyObject *unused)
346 {
347         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
348         if (creds == NULL) {
349                 PyErr_Format(PyExc_TypeError, "Credentials expected");
350                 return NULL;
351         }
352         return PyString_FromStringOrNULL(cli_credentials_get_realm(creds));
353 }
354
355 static PyObject *py_creds_set_realm(PyObject *self, PyObject *args)
356 {
357         char *newval;
358         enum credentials_obtained obt = CRED_SPECIFIED;
359         int _obt = obt;
360         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
361         if (creds == NULL) {
362                 PyErr_Format(PyExc_TypeError, "Credentials expected");
363                 return NULL;
364         }
365
366         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
367                 return NULL;
368         }
369         obt = _obt;
370
371         return PyBool_FromLong(cli_credentials_set_realm(creds, newval, obt));
372 }
373
374 static PyObject *py_creds_get_bind_dn(PyObject *self, PyObject *unused)
375 {
376         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
377         if (creds == NULL) {
378                 PyErr_Format(PyExc_TypeError, "Credentials expected");
379                 return NULL;
380         }
381         return PyString_FromStringOrNULL(cli_credentials_get_bind_dn(creds));
382 }
383
384 static PyObject *py_creds_set_bind_dn(PyObject *self, PyObject *args)
385 {
386         char *newval;
387         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
388         if (creds == NULL) {
389                 PyErr_Format(PyExc_TypeError, "Credentials expected");
390                 return NULL;
391         }
392         if (!PyArg_ParseTuple(args, "z", &newval))
393                 return NULL;
394
395         return PyBool_FromLong(cli_credentials_set_bind_dn(creds, newval));
396 }
397
398 static PyObject *py_creds_get_workstation(PyObject *self, PyObject *unused)
399 {
400         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
401         if (creds == NULL) {
402                 PyErr_Format(PyExc_TypeError, "Credentials expected");
403                 return NULL;
404         }
405         return PyString_FromStringOrNULL(cli_credentials_get_workstation(creds));
406 }
407
408 static PyObject *py_creds_set_workstation(PyObject *self, PyObject *args)
409 {
410         char *newval;
411         enum credentials_obtained obt = CRED_SPECIFIED;
412         int _obt = obt;
413         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
414         if (creds == NULL) {
415                 PyErr_Format(PyExc_TypeError, "Credentials expected");
416                 return NULL;
417         }
418
419         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
420                 return NULL;
421         }
422         obt = _obt;
423
424         return PyBool_FromLong(cli_credentials_set_workstation(creds, newval, obt));
425 }
426
427 static PyObject *py_creds_is_anonymous(PyObject *self, PyObject *unused)
428 {
429         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
430         if (creds == NULL) {
431                 PyErr_Format(PyExc_TypeError, "Credentials expected");
432                 return NULL;
433         }
434         return PyBool_FromLong(cli_credentials_is_anonymous(creds));
435 }
436
437 static PyObject *py_creds_set_anonymous(PyObject *self, PyObject *unused)
438 {
439         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
440         if (creds == NULL) {
441                 PyErr_Format(PyExc_TypeError, "Credentials expected");
442                 return NULL;
443         }
444         cli_credentials_set_anonymous(creds);
445         Py_RETURN_NONE;
446 }
447
448 static PyObject *py_creds_authentication_requested(PyObject *self, PyObject *unused)
449 {
450         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
451         if (creds == NULL) {
452                 PyErr_Format(PyExc_TypeError, "Credentials expected");
453                 return NULL;
454         }
455         return PyBool_FromLong(cli_credentials_authentication_requested(creds));
456 }
457
458 static PyObject *py_creds_wrong_password(PyObject *self, PyObject *unused)
459 {
460         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
461         if (creds == NULL) {
462                 PyErr_Format(PyExc_TypeError, "Credentials expected");
463                 return NULL;
464         }
465          return PyBool_FromLong(cli_credentials_wrong_password(creds));
466 }
467
468 static PyObject *py_creds_set_cmdline_callbacks(PyObject *self, PyObject *unused)
469 {
470         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
471         if (creds == NULL) {
472                 PyErr_Format(PyExc_TypeError, "Credentials expected");
473                 return NULL;
474         }
475         return PyBool_FromLong(cli_credentials_set_cmdline_callbacks(creds));
476 }
477
478 static PyObject *py_creds_parse_string(PyObject *self, PyObject *args)
479 {
480         char *newval;
481         enum credentials_obtained obt = CRED_SPECIFIED;
482         int _obt = obt;
483         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
484         if (creds == NULL) {
485                 PyErr_Format(PyExc_TypeError, "Credentials expected");
486                 return NULL;
487         }
488
489         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
490                 return NULL;
491         }
492         obt = _obt;
493
494         cli_credentials_parse_string(creds, newval, obt);
495         Py_RETURN_NONE;
496 }
497
498 static PyObject *py_creds_parse_file(PyObject *self, PyObject *args)
499 {
500         char *newval;
501         enum credentials_obtained obt = CRED_SPECIFIED;
502         int _obt = obt;
503         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
504         if (creds == NULL) {
505                 PyErr_Format(PyExc_TypeError, "Credentials expected");
506                 return NULL;
507         }
508
509         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
510                 return NULL;
511         }
512         obt = _obt;
513
514         cli_credentials_parse_file(creds, newval, obt);
515         Py_RETURN_NONE;
516 }
517
518 static PyObject *py_cli_credentials_set_password_will_be_nt_hash(PyObject *self, PyObject *args)
519 {
520         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
521         PyObject *py_val = NULL;
522         bool val = false;
523
524         if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &py_val)) {
525                 return NULL;
526         }
527         val = PyObject_IsTrue(py_val);
528
529         cli_credentials_set_password_will_be_nt_hash(creds, val);
530         Py_RETURN_NONE;
531 }
532
533 static PyObject *py_creds_get_nt_hash(PyObject *self, PyObject *unused)
534 {
535         PyObject *ret;
536         struct samr_Password *ntpw = NULL;
537         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
538         if (creds == NULL) {
539                 PyErr_Format(PyExc_TypeError, "Credentials expected");
540                 return NULL;
541         }
542         ntpw = cli_credentials_get_nt_hash(creds, creds);
543
544         ret = PyBytes_FromStringAndSize(discard_const_p(char, ntpw->hash), 16);
545         TALLOC_FREE(ntpw);
546         return ret;
547 }
548
549 static PyObject *py_creds_set_nt_hash(PyObject *self, PyObject *args)
550 {
551         PyObject *py_cp = Py_None;
552         const struct samr_Password *pwd = NULL;
553         enum credentials_obtained obt = CRED_SPECIFIED;
554         int _obt = obt;
555         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
556         if (creds == NULL) {
557                 PyErr_Format(PyExc_TypeError, "Credentials expected");
558                 return NULL;
559         }
560
561         if (!PyArg_ParseTuple(args, "O|i", &py_cp, &_obt)) {
562                 return NULL;
563         }
564         obt = _obt;
565
566         pwd = pytalloc_get_type(py_cp, struct samr_Password);
567         if (pwd == NULL) {
568                 /* pytalloc_get_type sets TypeError */
569                 return NULL;
570         }
571
572         return PyBool_FromLong(cli_credentials_set_nt_hash(creds, pwd, obt));
573 }
574
575 static PyObject *py_creds_get_kerberos_state(PyObject *self, PyObject *unused)
576 {
577         int state;
578         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
579         if (creds == NULL) {
580                 PyErr_Format(PyExc_TypeError, "Credentials expected");
581                 return NULL;
582         }
583         state = cli_credentials_get_kerberos_state(creds);
584         return PyLong_FromLong(state);
585 }
586
587 static PyObject *py_creds_set_kerberos_state(PyObject *self, PyObject *args)
588 {
589         int state;
590         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
591         if (creds == NULL) {
592                 PyErr_Format(PyExc_TypeError, "Credentials expected");
593                 return NULL;
594         }
595         if (!PyArg_ParseTuple(args, "i", &state))
596                 return NULL;
597
598         cli_credentials_set_kerberos_state(creds, state, CRED_SPECIFIED);
599         Py_RETURN_NONE;
600 }
601
602 static PyObject *py_creds_set_krb_forwardable(PyObject *self, PyObject *args)
603 {
604         int state;
605         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
606         if (creds == NULL) {
607                 PyErr_Format(PyExc_TypeError, "Credentials expected");
608                 return NULL;
609         }
610         if (!PyArg_ParseTuple(args, "i", &state))
611                 return NULL;
612
613         cli_credentials_set_krb_forwardable(creds, state);
614         Py_RETURN_NONE;
615 }
616
617
618 static PyObject *py_creds_get_forced_sasl_mech(PyObject *self, PyObject *unused)
619 {
620         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
621         if (creds == NULL) {
622                 PyErr_Format(PyExc_TypeError, "Credentials expected");
623                 return NULL;
624         }
625         return PyString_FromStringOrNULL(cli_credentials_get_forced_sasl_mech(creds));
626 }
627
628 static PyObject *py_creds_set_forced_sasl_mech(PyObject *self, PyObject *args)
629 {
630         char *newval;
631         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
632         if (creds == NULL) {
633                 PyErr_Format(PyExc_TypeError, "Credentials expected");
634                 return NULL;
635         }
636
637         if (!PyArg_ParseTuple(args, "s", &newval)) {
638                 return NULL;
639         }
640
641         cli_credentials_set_forced_sasl_mech(creds, newval);
642         Py_RETURN_NONE;
643 }
644
645 static PyObject *py_creds_set_conf(PyObject *self, PyObject *args)
646 {
647         PyObject *py_lp_ctx = Py_None;
648         struct loadparm_context *lp_ctx;
649         TALLOC_CTX *mem_ctx;
650         struct cli_credentials *creds;
651         bool ok;
652
653         creds = PyCredentials_AsCliCredentials(self);
654         if (creds == NULL) {
655                 PyErr_Format(PyExc_TypeError, "Credentials expected");
656                 return NULL;
657         }
658
659         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx)) {
660                 return NULL;
661         }
662
663         mem_ctx = talloc_new(NULL);
664         if (mem_ctx == NULL) {
665                 PyErr_NoMemory();
666                 return NULL;
667         }
668
669         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
670         if (lp_ctx == NULL) {
671                 talloc_free(mem_ctx);
672                 return NULL;
673         }
674
675         ok = cli_credentials_set_conf(creds, lp_ctx);
676         talloc_free(mem_ctx);
677         if (!ok) {
678                 return NULL;
679         }
680
681         Py_RETURN_NONE;
682 }
683
684 static PyObject *py_creds_guess(PyObject *self, PyObject *args)
685 {
686         PyObject *py_lp_ctx = Py_None;
687         struct loadparm_context *lp_ctx;
688         TALLOC_CTX *mem_ctx;
689         struct cli_credentials *creds;
690         bool ok;
691
692         creds = PyCredentials_AsCliCredentials(self);
693         if (creds == NULL) {
694                 PyErr_Format(PyExc_TypeError, "Credentials expected");
695                 return NULL;
696         }
697
698         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
699                 return NULL;
700
701         mem_ctx = talloc_new(NULL);
702         if (mem_ctx == NULL) {
703                 PyErr_NoMemory();
704                 return NULL;
705         }
706
707         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
708         if (lp_ctx == NULL) {
709                 talloc_free(mem_ctx);
710                 return NULL;
711         }
712
713         ok = cli_credentials_guess(creds, lp_ctx);
714         talloc_free(mem_ctx);
715         if (!ok) {
716                 return NULL;
717         }
718
719         Py_RETURN_NONE;
720 }
721
722 static PyObject *py_creds_set_machine_account(PyObject *self, PyObject *args)
723 {
724         PyObject *py_lp_ctx = Py_None;
725         struct loadparm_context *lp_ctx;
726         NTSTATUS status;
727         struct cli_credentials *creds;
728         TALLOC_CTX *mem_ctx;
729
730         creds = PyCredentials_AsCliCredentials(self);
731         if (creds == NULL) {
732                 PyErr_Format(PyExc_TypeError, "Credentials expected");
733                 return NULL;
734         }
735
736         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
737                 return NULL;
738
739         mem_ctx = talloc_new(NULL);
740         if (mem_ctx == NULL) {
741                 PyErr_NoMemory();
742                 return NULL;
743         }
744
745         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
746         if (lp_ctx == NULL) {
747                 talloc_free(mem_ctx);
748                 return NULL;
749         }
750
751         status = cli_credentials_set_machine_account(creds, lp_ctx);
752         talloc_free(mem_ctx);
753
754         PyErr_NTSTATUS_IS_ERR_RAISE(status);
755
756         Py_RETURN_NONE;
757 }
758
759 static PyObject *PyCredentialCacheContainer_from_ccache_container(struct ccache_container *ccc)
760 {
761         return pytalloc_reference(&PyCredentialCacheContainer, ccc);
762 }
763
764
765 static PyObject *py_creds_get_named_ccache(PyObject *self, PyObject *args)
766 {
767         PyObject *py_lp_ctx = Py_None;
768         char *ccache_name = NULL;
769         struct loadparm_context *lp_ctx;
770         struct ccache_container *ccc;
771         struct tevent_context *event_ctx;
772         int ret;
773         const char *error_string;
774         struct cli_credentials *creds;
775         TALLOC_CTX *mem_ctx;
776
777         creds = PyCredentials_AsCliCredentials(self);
778         if (creds == NULL) {
779                 PyErr_Format(PyExc_TypeError, "Credentials expected");
780                 return NULL;
781         }
782
783         if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name))
784                 return NULL;
785
786         mem_ctx = talloc_new(NULL);
787         if (mem_ctx == NULL) {
788                 PyErr_NoMemory();
789                 return NULL;
790         }
791
792         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
793         if (lp_ctx == NULL) {
794                 talloc_free(mem_ctx);
795                 return NULL;
796         }
797
798         event_ctx = samba_tevent_context_init(mem_ctx);
799
800         ret = cli_credentials_get_named_ccache(creds, event_ctx, lp_ctx,
801                                                ccache_name, &ccc, &error_string);
802         talloc_unlink(mem_ctx, lp_ctx);
803         if (ret == 0) {
804                 talloc_steal(ccc, event_ctx);
805                 talloc_free(mem_ctx);
806                 return PyCredentialCacheContainer_from_ccache_container(ccc);
807         }
808
809         PyErr_SetString(PyExc_RuntimeError, error_string?error_string:"NULL");
810
811         talloc_free(mem_ctx);
812         return NULL;
813 }
814
815 static PyObject *py_creds_set_named_ccache(PyObject *self, PyObject *args)
816 {
817         struct loadparm_context *lp_ctx = NULL;
818         enum credentials_obtained obt = CRED_SPECIFIED;
819         const char *error_string = NULL;
820         TALLOC_CTX *mem_ctx = NULL;
821         char *newval = NULL;
822         PyObject *py_lp_ctx = Py_None;
823         int _obt = obt;
824         int ret;
825         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
826         if (creds == NULL) {
827                 PyErr_Format(PyExc_TypeError, "Credentials expected");
828                 return NULL;
829         }
830
831         if (!PyArg_ParseTuple(args, "s|iO", &newval, &_obt, &py_lp_ctx))
832                 return NULL;
833         obt = _obt;
834
835         mem_ctx = talloc_new(NULL);
836         if (mem_ctx == NULL) {
837                 PyErr_NoMemory();
838                 return NULL;
839         }
840
841         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
842         if (lp_ctx == NULL) {
843                 talloc_free(mem_ctx);
844                 return NULL;
845         }
846
847         ret = cli_credentials_set_ccache(creds,
848                                          lp_ctx,
849                                          newval, obt,
850                                          &error_string);
851
852         if (ret != 0) {
853                 PyErr_SetString(PyExc_RuntimeError,
854                                 error_string != NULL ? error_string : "NULL");
855                 talloc_free(mem_ctx);
856                 return NULL;
857         }
858
859         talloc_free(mem_ctx);
860         Py_RETURN_NONE;
861 }
862
863 static PyObject *py_creds_set_gensec_features(PyObject *self, PyObject *args)
864 {
865         unsigned int gensec_features;
866         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
867         if (creds == NULL) {
868                 PyErr_Format(PyExc_TypeError, "Credentials expected");
869                 return NULL;
870         }
871
872         if (!PyArg_ParseTuple(args, "I", &gensec_features))
873                 return NULL;
874
875         cli_credentials_set_gensec_features(creds,
876                                             gensec_features,
877                                             CRED_SPECIFIED);
878
879         Py_RETURN_NONE;
880 }
881
882 static PyObject *py_creds_get_gensec_features(PyObject *self, PyObject *args)
883 {
884         unsigned int gensec_features;
885         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
886         if (creds == NULL) {
887                 PyErr_Format(PyExc_TypeError, "Credentials expected");
888                 return NULL;
889         }
890
891         gensec_features = cli_credentials_get_gensec_features(creds);
892         return PyLong_FromLong(gensec_features);
893 }
894
895 static PyObject *py_creds_new_client_authenticator(PyObject *self,
896                                                    PyObject *args)
897 {
898         struct netr_Authenticator auth;
899         struct cli_credentials *creds = NULL;
900         struct netlogon_creds_CredentialState *nc = NULL;
901         PyObject *ret = NULL;
902         NTSTATUS status;
903
904         creds = PyCredentials_AsCliCredentials(self);
905         if (creds == NULL) {
906                 PyErr_SetString(PyExc_RuntimeError,
907                                 "Failed to get credentials from python");
908                 return NULL;
909         }
910
911         nc = creds->netlogon_creds;
912         if (nc == NULL) {
913                 PyErr_SetString(PyExc_ValueError,
914                                 "No netlogon credentials cannot make "
915                                 "client authenticator");
916                 return NULL;
917         }
918
919         status = netlogon_creds_client_authenticator(nc, &auth);
920         if (!NT_STATUS_IS_OK(status)) {
921                 PyErr_SetString(PyExc_ValueError,
922                                 "Failed to create client authenticator");
923                 return NULL;
924         }
925
926         ret = Py_BuildValue("{s"PYARG_BYTES_LEN"si}",
927                             "credential",
928                             (const char *) &auth.cred, sizeof(auth.cred),
929                             "timestamp", auth.timestamp);
930         return ret;
931 }
932
933 static PyObject *py_creds_set_secure_channel_type(PyObject *self, PyObject *args)
934 {
935         unsigned int channel_type;
936         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
937         if (creds == NULL) {
938                 PyErr_Format(PyExc_TypeError, "Credentials expected");
939                 return NULL;
940         }
941
942         if (!PyArg_ParseTuple(args, "I", &channel_type))
943                 return NULL;
944
945         cli_credentials_set_secure_channel_type(
946                 creds,
947                 channel_type);
948
949         Py_RETURN_NONE;
950 }
951
952 static PyObject *py_creds_get_secure_channel_type(PyObject *self, PyObject *args)
953 {
954         enum netr_SchannelType channel_type = SEC_CHAN_NULL;
955         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
956         if (creds == NULL) {
957                 PyErr_Format(PyExc_TypeError, "Credentials expected");
958                 return NULL;
959         }
960
961         channel_type = cli_credentials_get_secure_channel_type(creds);
962
963         return PyLong_FromLong(channel_type);
964 }
965
966 static PyObject *py_creds_get_aes256_key(PyObject *self, PyObject *args)
967 {
968         struct loadparm_context *lp_ctx = NULL;
969         TALLOC_CTX *mem_ctx = NULL;
970         PyObject *py_lp_ctx = Py_None;
971         const char *salt = NULL;
972         DATA_BLOB aes_256;
973         int code;
974         PyObject *ret = NULL;
975         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
976         if (creds == NULL) {
977                 PyErr_Format(PyExc_TypeError, "Credentials expected");
978                 return NULL;
979         }
980
981         if (!PyArg_ParseTuple(args, "s|O", &salt, &py_lp_ctx))
982                 return NULL;
983
984         mem_ctx = talloc_new(NULL);
985         if (mem_ctx == NULL) {
986                 PyErr_NoMemory();
987                 return NULL;
988         }
989
990         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
991         if (lp_ctx == NULL) {
992                 talloc_free(mem_ctx);
993                 return NULL;
994         }
995
996         code = cli_credentials_get_aes256_key(creds,
997                                               mem_ctx,
998                                               lp_ctx,
999                                               salt,
1000                                               &aes_256);
1001         if (code != 0) {
1002                 PyErr_SetString(PyExc_RuntimeError,
1003                                 "Failed to generate AES256 key");
1004                 talloc_free(mem_ctx);
1005                 return NULL;
1006         }
1007
1008         ret = PyBytes_FromStringAndSize((const char *)aes_256.data,
1009                                         aes_256.length);
1010         talloc_free(mem_ctx);
1011         return ret;
1012 }
1013
1014 static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self,
1015                                                       PyObject *args)
1016 {
1017         DATA_BLOB data = data_blob_null;
1018         struct cli_credentials    *creds  = NULL;
1019         struct netr_CryptPassword *pwd    = NULL;
1020         NTSTATUS status;
1021         PyObject *py_cp = Py_None;
1022
1023         creds = PyCredentials_AsCliCredentials(self);
1024         if (creds == NULL) {
1025                 PyErr_Format(PyExc_TypeError, "Credentials expected");
1026                 return NULL;
1027         }
1028
1029         if (!PyArg_ParseTuple(args, "O", &py_cp)) {
1030                 return NULL;
1031         }
1032
1033         pwd = pytalloc_get_type(py_cp, struct netr_CryptPassword);
1034         if (pwd == NULL) {
1035                 /* pytalloc_get_type sets TypeError */
1036                 return NULL;
1037         }
1038         data.length = sizeof(struct netr_CryptPassword);
1039         data.data   = (uint8_t *)pwd;
1040         status = netlogon_creds_session_encrypt(creds->netlogon_creds, data);
1041
1042         PyErr_NTSTATUS_IS_ERR_RAISE(status);
1043
1044         Py_RETURN_NONE;
1045 }
1046
1047 static PyObject *py_creds_encrypt_samr_password(PyObject *self,
1048                                                 PyObject *args)
1049 {
1050         DATA_BLOB data = data_blob_null;
1051         struct cli_credentials *creds  = NULL;
1052         struct samr_Password   *pwd    = NULL;
1053         NTSTATUS status;
1054         PyObject *py_cp = Py_None;
1055
1056         creds = PyCredentials_AsCliCredentials(self);
1057         if (creds == NULL) {
1058                 PyErr_Format(PyExc_TypeError, "Credentials expected");
1059                 return NULL;
1060         }
1061
1062         if (creds->netlogon_creds == NULL) {
1063                 PyErr_Format(PyExc_ValueError, "NetLogon credentials not set");
1064                 return NULL;
1065         }
1066
1067         if (!PyArg_ParseTuple(args, "O", &py_cp)) {
1068                 return NULL;
1069         }
1070
1071         pwd = pytalloc_get_type(py_cp, struct samr_Password);
1072         if (pwd == NULL) {
1073                 /* pytalloc_get_type sets TypeError */
1074                 return NULL;
1075         }
1076         data = data_blob_const(pwd->hash, sizeof(pwd->hash));
1077         status = netlogon_creds_session_encrypt(creds->netlogon_creds, data);
1078
1079         PyErr_NTSTATUS_IS_ERR_RAISE(status);
1080
1081         Py_RETURN_NONE;
1082 }
1083
1084 static PyObject *py_creds_get_smb_signing(PyObject *self, PyObject *unused)
1085 {
1086         enum smb_signing_setting signing_state;
1087         struct cli_credentials *creds = NULL;
1088
1089         creds = PyCredentials_AsCliCredentials(self);
1090         if (creds == NULL) {
1091                 PyErr_Format(PyExc_TypeError, "Credentials expected");
1092                 return NULL;
1093         }
1094
1095         signing_state = cli_credentials_get_smb_signing(creds);
1096         return PyLong_FromLong(signing_state);
1097 }
1098
1099 static PyObject *py_creds_set_smb_signing(PyObject *self, PyObject *args)
1100 {
1101         enum smb_signing_setting signing_state;
1102         struct cli_credentials *creds = NULL;
1103         enum credentials_obtained obt = CRED_SPECIFIED;
1104
1105         creds = PyCredentials_AsCliCredentials(self);
1106         if (creds == NULL) {
1107                 PyErr_Format(PyExc_TypeError, "Credentials expected");
1108                 return NULL;
1109         }
1110         if (!PyArg_ParseTuple(args, "i|i", &signing_state, &obt)) {
1111                 return NULL;
1112         }
1113
1114         switch (signing_state) {
1115         case SMB_SIGNING_DEFAULT:
1116         case SMB_SIGNING_OFF:
1117         case SMB_SIGNING_IF_REQUIRED:
1118         case SMB_SIGNING_DESIRED:
1119         case SMB_SIGNING_REQUIRED:
1120                 break;
1121         default:
1122                 PyErr_Format(PyExc_TypeError, "Invalid signing state value");
1123                 return NULL;
1124         }
1125
1126         cli_credentials_set_smb_signing(creds, signing_state, obt);
1127         Py_RETURN_NONE;
1128 }
1129
1130 static PyObject *py_creds_get_smb_ipc_signing(PyObject *self, PyObject *unused)
1131 {
1132         enum smb_signing_setting signing_state;
1133         struct cli_credentials *creds = NULL;
1134
1135         creds = PyCredentials_AsCliCredentials(self);
1136         if (creds == NULL) {
1137                 PyErr_Format(PyExc_TypeError, "Credentials expected");
1138                 return NULL;
1139         }
1140
1141         signing_state = cli_credentials_get_smb_ipc_signing(creds);
1142         return PyLong_FromLong(signing_state);
1143 }
1144
1145 static PyObject *py_creds_set_smb_ipc_signing(PyObject *self, PyObject *args)
1146 {
1147         enum smb_signing_setting signing_state;
1148         struct cli_credentials *creds = NULL;
1149         enum credentials_obtained obt = CRED_SPECIFIED;
1150
1151         creds = PyCredentials_AsCliCredentials(self);
1152         if (creds == NULL) {
1153                 PyErr_Format(PyExc_TypeError, "Credentials expected");
1154                 return NULL;
1155         }
1156         if (!PyArg_ParseTuple(args, "i|i", &signing_state, &obt)) {
1157                 return NULL;
1158         }
1159
1160         switch (signing_state) {
1161         case SMB_SIGNING_DEFAULT:
1162         case SMB_SIGNING_OFF:
1163         case SMB_SIGNING_IF_REQUIRED:
1164         case SMB_SIGNING_DESIRED:
1165         case SMB_SIGNING_REQUIRED:
1166                 break;
1167         default:
1168                 PyErr_Format(PyExc_TypeError, "Invalid signing state value");
1169                 return NULL;
1170         }
1171
1172         cli_credentials_set_smb_ipc_signing(creds, signing_state, obt);
1173         Py_RETURN_NONE;
1174 }
1175
1176 static PyObject *py_creds_get_smb_encryption(PyObject *self, PyObject *unused)
1177 {
1178         enum smb_encryption_setting encryption_state;
1179         struct cli_credentials *creds = NULL;
1180
1181         creds = PyCredentials_AsCliCredentials(self);
1182         if (creds == NULL) {
1183                 PyErr_Format(PyExc_TypeError, "Credentials expected");
1184                 return NULL;
1185         }
1186
1187         encryption_state = cli_credentials_get_smb_encryption(creds);
1188         return PyLong_FromLong(encryption_state);
1189 }
1190
1191 static PyObject *py_creds_set_smb_encryption(PyObject *self, PyObject *args)
1192 {
1193         enum smb_encryption_setting encryption_state;
1194         struct cli_credentials *creds = NULL;
1195         enum credentials_obtained obt = CRED_SPECIFIED;
1196
1197         creds = PyCredentials_AsCliCredentials(self);
1198         if (creds == NULL) {
1199                 PyErr_Format(PyExc_TypeError, "Credentials expected");
1200                 return NULL;
1201         }
1202         if (!PyArg_ParseTuple(args, "i|i", &encryption_state, &obt)) {
1203                 return NULL;
1204         }
1205
1206         switch (encryption_state) {
1207         case SMB_ENCRYPTION_DEFAULT:
1208         case SMB_ENCRYPTION_OFF:
1209         case SMB_ENCRYPTION_IF_REQUIRED:
1210         case SMB_ENCRYPTION_DESIRED:
1211         case SMB_ENCRYPTION_REQUIRED:
1212                 break;
1213         default:
1214                 PyErr_Format(PyExc_TypeError, "Invalid encryption state value");
1215                 return NULL;
1216         }
1217
1218         (void)cli_credentials_set_smb_encryption(creds, encryption_state, obt);
1219         Py_RETURN_NONE;
1220 }
1221
1222 static PyMethodDef py_creds_methods[] = {
1223         {
1224                 .ml_name  = "get_username",
1225                 .ml_meth  = py_creds_get_username,
1226                 .ml_flags = METH_NOARGS,
1227                 .ml_doc   = "S.get_username() -> username\nObtain username.",
1228         },
1229         {
1230                 .ml_name  = "set_username",
1231                 .ml_meth  = py_creds_set_username,
1232                 .ml_flags = METH_VARARGS,
1233                 .ml_doc   = "S.set_username(name[, credentials.SPECIFIED]) -> None\n"
1234                             "Change username.",
1235         },
1236         {
1237                 .ml_name  = "get_principal",
1238                 .ml_meth  = py_creds_get_principal,
1239                 .ml_flags = METH_NOARGS,
1240                 .ml_doc   = "S.get_principal() -> user@realm\nObtain user principal.",
1241         },
1242         {
1243                 .ml_name  = "set_principal",
1244                 .ml_meth  = py_creds_set_principal,
1245                 .ml_flags = METH_VARARGS,
1246                 .ml_doc   = "S.set_principal(name[, credentials.SPECIFIED]) -> None\n"
1247                             "Change principal.",
1248         },
1249         {
1250                 .ml_name  = "get_password",
1251                 .ml_meth  = py_creds_get_password,
1252                 .ml_flags = METH_NOARGS,
1253                 .ml_doc   = "S.get_password() -> password\n"
1254                             "Obtain password.",
1255         },
1256         {
1257                 .ml_name  = "get_ntlm_username_domain",
1258                 .ml_meth  = py_creds_get_ntlm_username_domain,
1259                 .ml_flags = METH_NOARGS,
1260                 .ml_doc   = "S.get_ntlm_username_domain() -> (domain, username)\n"
1261                             "Obtain NTLM username and domain, split up either as (DOMAIN, user) or (\"\", \"user@realm\").",
1262         },
1263         {
1264                 .ml_name  = "get_ntlm_response",
1265                 .ml_meth  = PY_DISCARD_FUNC_SIG(PyCFunction,
1266                                                 py_creds_get_ntlm_response),
1267                 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1268                 .ml_doc   = "S.get_ntlm_response"
1269                             "(flags, challenge[, target_info]) -> "
1270                             "(flags, lm_response, nt_response, lm_session_key, nt_session_key)\n"
1271                             "Obtain LM or NTLM response.",
1272         },
1273         {
1274                 .ml_name  = "set_password",
1275                 .ml_meth  = py_creds_set_password,
1276                 .ml_flags = METH_VARARGS,
1277                 .ml_doc   = "S.set_password(password[, credentials.SPECIFIED]) -> None\n"
1278                             "Change password.",
1279         },
1280         {
1281                 .ml_name  = "set_utf16_password",
1282                 .ml_meth  = py_creds_set_utf16_password,
1283                 .ml_flags = METH_VARARGS,
1284                 .ml_doc   = "S.set_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
1285                             "Change password.",
1286         },
1287         {
1288                 .ml_name  = "get_old_password",
1289                 .ml_meth  = py_creds_get_old_password,
1290                 .ml_flags = METH_NOARGS,
1291                 .ml_doc   = "S.get_old_password() -> password\n"
1292                             "Obtain old password.",
1293         },
1294         {
1295                 .ml_name  = "set_old_password",
1296                 .ml_meth  = py_creds_set_old_password,
1297                 .ml_flags = METH_VARARGS,
1298                 .ml_doc   = "S.set_old_password(password[, credentials.SPECIFIED]) -> None\n"
1299                             "Change old password.",
1300         },
1301         {
1302                 .ml_name  = "set_old_utf16_password",
1303                 .ml_meth  = py_creds_set_old_utf16_password,
1304                 .ml_flags = METH_VARARGS,
1305                 .ml_doc   = "S.set_old_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
1306                             "Change old password.",
1307         },
1308         {
1309                 .ml_name  = "get_domain",
1310                 .ml_meth  = py_creds_get_domain,
1311                 .ml_flags = METH_NOARGS,
1312                 .ml_doc   = "S.get_domain() -> domain\n"
1313                             "Obtain domain name.",
1314         },
1315         {
1316                 .ml_name  = "set_domain",
1317                 .ml_meth  = py_creds_set_domain,
1318                 .ml_flags = METH_VARARGS,
1319                 .ml_doc   = "S.set_domain(domain[, credentials.SPECIFIED]) -> None\n"
1320                             "Change domain name.",
1321         },
1322         {
1323                 .ml_name  = "get_realm",
1324                 .ml_meth  = py_creds_get_realm,
1325                 .ml_flags = METH_NOARGS,
1326                 .ml_doc   = "S.get_realm() -> realm\n"
1327                             "Obtain realm name.",
1328         },
1329         {
1330                 .ml_name  = "set_realm",
1331                 .ml_meth  = py_creds_set_realm,
1332                 .ml_flags = METH_VARARGS,
1333                 .ml_doc   = "S.set_realm(realm[, credentials.SPECIFIED]) -> None\n"
1334                             "Change realm name.",
1335         },
1336         {
1337                 .ml_name  = "get_bind_dn",
1338                 .ml_meth  = py_creds_get_bind_dn,
1339                 .ml_flags = METH_NOARGS,
1340                 .ml_doc   = "S.get_bind_dn() -> bind dn\n"
1341                             "Obtain bind DN.",
1342         },
1343         {
1344                 .ml_name  = "set_bind_dn",
1345                 .ml_meth  = py_creds_set_bind_dn,
1346                 .ml_flags = METH_VARARGS,
1347                 .ml_doc   = "S.set_bind_dn(bind_dn) -> None\n"
1348                             "Change bind DN.",
1349         },
1350         {
1351                 .ml_name  = "is_anonymous",
1352                 .ml_meth  = py_creds_is_anonymous,
1353                 .ml_flags = METH_NOARGS,
1354         },
1355         {
1356                 .ml_name  = "set_anonymous",
1357                 .ml_meth  = py_creds_set_anonymous,
1358                 .ml_flags = METH_NOARGS,
1359                 .ml_doc   = "S.set_anonymous() -> None\n"
1360                             "Use anonymous credentials.",
1361         },
1362         {
1363                 .ml_name  = "get_workstation",
1364                 .ml_meth  = py_creds_get_workstation,
1365                 .ml_flags = METH_NOARGS,
1366         },
1367         {
1368                 .ml_name  = "set_workstation",
1369                 .ml_meth  = py_creds_set_workstation,
1370                 .ml_flags = METH_VARARGS,
1371         },
1372         {
1373                 .ml_name  = "authentication_requested",
1374                 .ml_meth  = py_creds_authentication_requested,
1375                 .ml_flags = METH_NOARGS,
1376         },
1377         {
1378                 .ml_name  = "wrong_password",
1379                 .ml_meth  = py_creds_wrong_password,
1380                 .ml_flags = METH_NOARGS,
1381                 .ml_doc   = "S.wrong_password() -> bool\n"
1382                             "Indicate the returned password was incorrect.",
1383         },
1384         {
1385                 .ml_name  = "set_cmdline_callbacks",
1386                 .ml_meth  = py_creds_set_cmdline_callbacks,
1387                 .ml_flags = METH_NOARGS,
1388                 .ml_doc   = "S.set_cmdline_callbacks() -> bool\n"
1389                             "Use command-line to obtain credentials not explicitly set.",
1390         },
1391         {
1392                 .ml_name  = "parse_string",
1393                 .ml_meth  = py_creds_parse_string,
1394                 .ml_flags = METH_VARARGS,
1395                 .ml_doc   = "S.parse_string(text[, credentials.SPECIFIED]) -> None\n"
1396                             "Parse credentials string.",
1397         },
1398         {
1399                 .ml_name  = "parse_file",
1400                 .ml_meth  = py_creds_parse_file,
1401                 .ml_flags = METH_VARARGS,
1402                 .ml_doc   = "S.parse_file(filename[, credentials.SPECIFIED]) -> None\n"
1403                             "Parse credentials file.",
1404         },
1405         {
1406                 .ml_name  = "set_password_will_be_nt_hash",
1407                 .ml_meth  = py_cli_credentials_set_password_will_be_nt_hash,
1408                 .ml_flags = METH_VARARGS,
1409                 .ml_doc   = "S.set_password_will_be_nt_hash(bool) -> None\n"
1410                             "Alters the behaviour of S.set_password() "
1411                             "to expect the NTHASH as hexstring.",
1412         },
1413         {
1414                 .ml_name  = "get_nt_hash",
1415                 .ml_meth  = py_creds_get_nt_hash,
1416                 .ml_flags = METH_NOARGS,
1417         },
1418         {
1419                 .ml_name  = "set_nt_hash",
1420                 .ml_meth  = py_creds_set_nt_hash,
1421                 .ml_flags = METH_VARARGS,
1422                 .ml_doc = "S.set_net_sh(samr_Password[, credentials.SPECIFIED]) -> bool\n"
1423                         "Change NT hash.",
1424         },
1425         {
1426                 .ml_name  = "get_kerberos_state",
1427                 .ml_meth  = py_creds_get_kerberos_state,
1428                 .ml_flags = METH_NOARGS,
1429         },
1430         {
1431                 .ml_name  = "set_kerberos_state",
1432                 .ml_meth  = py_creds_set_kerberos_state,
1433                 .ml_flags = METH_VARARGS,
1434         },
1435         {
1436                 .ml_name  = "set_krb_forwardable",
1437                 .ml_meth  = py_creds_set_krb_forwardable,
1438                 .ml_flags = METH_VARARGS,
1439         },
1440         {
1441                 .ml_name  = "set_conf",
1442                 .ml_meth  = py_creds_set_conf,
1443                 .ml_flags = METH_VARARGS,
1444         },
1445         {
1446                 .ml_name  = "guess",
1447                 .ml_meth  = py_creds_guess,
1448                 .ml_flags = METH_VARARGS,
1449         },
1450         {
1451                 .ml_name  = "set_machine_account",
1452                 .ml_meth  = py_creds_set_machine_account,
1453                 .ml_flags = METH_VARARGS,
1454         },
1455         {
1456                 .ml_name  = "get_named_ccache",
1457                 .ml_meth  = py_creds_get_named_ccache,
1458                 .ml_flags = METH_VARARGS,
1459         },
1460         {
1461                 .ml_name  = "set_named_ccache",
1462                 .ml_meth  = py_creds_set_named_ccache,
1463                 .ml_flags = METH_VARARGS,
1464                 .ml_doc   = "S.set_named_ccache(krb5_ccache_name, obtained, lp) -> None\n"
1465                             "Set credentials to KRB5 Credentials Cache (by name).",
1466         },
1467         {
1468                 .ml_name  = "set_gensec_features",
1469                 .ml_meth  = py_creds_set_gensec_features,
1470                 .ml_flags = METH_VARARGS,
1471         },
1472         {
1473                 .ml_name  = "get_gensec_features",
1474                 .ml_meth  = py_creds_get_gensec_features,
1475                 .ml_flags = METH_NOARGS,
1476         },
1477         {
1478                 .ml_name  = "get_forced_sasl_mech",
1479                 .ml_meth  = py_creds_get_forced_sasl_mech,
1480                 .ml_flags = METH_NOARGS,
1481                 .ml_doc   = "S.get_forced_sasl_mech() -> SASL mechanism\nObtain forced SASL mechanism.",
1482         },
1483         {
1484                 .ml_name  = "set_forced_sasl_mech",
1485                 .ml_meth  = py_creds_set_forced_sasl_mech,
1486                 .ml_flags = METH_VARARGS,
1487                 .ml_doc   = "S.set_forced_sasl_mech(name) -> None\n"
1488                             "Set forced SASL mechanism.",
1489         },
1490         {
1491                 .ml_name  = "new_client_authenticator",
1492                 .ml_meth  = py_creds_new_client_authenticator,
1493                 .ml_flags = METH_NOARGS,
1494                 .ml_doc   = "S.new_client_authenticator() -> Authenticator\n"
1495                             "Get a new client NETLOGON_AUTHENTICATOR"},
1496         {
1497                 .ml_name  = "set_secure_channel_type",
1498                 .ml_meth  = py_creds_set_secure_channel_type,
1499                 .ml_flags = METH_VARARGS,
1500         },
1501         {
1502                 .ml_name  = "get_secure_channel_type",
1503                 .ml_meth  = py_creds_get_secure_channel_type,
1504                 .ml_flags = METH_VARARGS,
1505         },
1506         {
1507                 .ml_name  = "get_aes256_key",
1508                 .ml_meth  = py_creds_get_aes256_key,
1509                 .ml_flags = METH_VARARGS,
1510                 .ml_doc   = "S.get_aes256_key(salt[, lp]) -> bytes\n"
1511                             "Generate an AES256 key using the current password and\n"
1512                             "the specified salt",
1513         },
1514         {
1515                 .ml_name  = "encrypt_netr_crypt_password",
1516                 .ml_meth  = py_creds_encrypt_netr_crypt_password,
1517                 .ml_flags = METH_VARARGS,
1518                 .ml_doc   = "S.encrypt_netr_crypt_password(password) -> None\n"
1519                             "Encrypt the supplied password using the session key and\n"
1520                             "the negotiated encryption algorithm in place\n"
1521                             "i.e. it overwrites the original data"},
1522         {
1523                 .ml_name  = "encrypt_samr_password",
1524                 .ml_meth  = py_creds_encrypt_samr_password,
1525                 .ml_flags = METH_VARARGS,
1526                 .ml_doc   = "S.encrypt_samr_password(password) -> None\n"
1527                             "Encrypt the supplied password using the session key and\n"
1528                             "the negotiated encryption algorithm in place\n"
1529                             "i.e. it overwrites the original data"
1530         },
1531         {
1532                 .ml_name  = "get_smb_signing",
1533                 .ml_meth  = py_creds_get_smb_signing,
1534                 .ml_flags = METH_NOARGS,
1535         },
1536         {
1537                 .ml_name  = "set_smb_signing",
1538                 .ml_meth  = py_creds_set_smb_signing,
1539                 .ml_flags = METH_VARARGS,
1540         },
1541         {
1542                 .ml_name  = "get_smb_ipc_signing",
1543                 .ml_meth  = py_creds_get_smb_ipc_signing,
1544                 .ml_flags = METH_NOARGS,
1545         },
1546         {
1547                 .ml_name  = "set_smb_ipc_signing",
1548                 .ml_meth  = py_creds_set_smb_ipc_signing,
1549                 .ml_flags = METH_VARARGS,
1550         },
1551         {
1552                 .ml_name  = "get_smb_encryption",
1553                 .ml_meth  = py_creds_get_smb_encryption,
1554                 .ml_flags = METH_NOARGS,
1555         },
1556         {
1557                 .ml_name  = "set_smb_encryption",
1558                 .ml_meth  = py_creds_set_smb_encryption,
1559                 .ml_flags = METH_VARARGS,
1560         },
1561         { .ml_name = NULL }
1562 };
1563
1564 static struct PyModuleDef moduledef = {
1565     PyModuleDef_HEAD_INIT,
1566     .m_name = "credentials",
1567     .m_doc = "Credentials management.",
1568     .m_size = -1,
1569     .m_methods = py_creds_methods,
1570 };
1571
1572 PyTypeObject PyCredentials = {
1573         .tp_name = "credentials.Credentials",
1574         .tp_new = py_creds_new,
1575         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1576         .tp_methods = py_creds_methods,
1577 };
1578
1579 static PyObject *py_ccache_name(PyObject *self, PyObject *unused)
1580 {
1581         struct ccache_container *ccc = NULL;
1582         char *name = NULL;
1583         PyObject *py_name = NULL;
1584         int ret;
1585
1586         ccc = pytalloc_get_type(self, struct ccache_container);
1587
1588         ret = krb5_cc_get_full_name(ccc->smb_krb5_context->krb5_context,
1589                                     ccc->ccache, &name);
1590         if (ret == 0) {
1591                 py_name = PyString_FromStringOrNULL(name);
1592                 krb5_free_string(ccc->smb_krb5_context->krb5_context, name);
1593         } else {
1594                 PyErr_SetString(PyExc_RuntimeError,
1595                                 "Failed to get ccache name");
1596                 return NULL;
1597         }
1598         return py_name;
1599 }
1600
1601 static PyMethodDef py_ccache_container_methods[] = {
1602         { "get_name", py_ccache_name, METH_NOARGS,
1603           "S.get_name() -> name\nObtain KRB5 credentials cache name." },
1604         {0}
1605 };
1606
1607 PyTypeObject PyCredentialCacheContainer = {
1608         .tp_name = "credentials.CredentialCacheContainer",
1609         .tp_flags = Py_TPFLAGS_DEFAULT,
1610         .tp_methods = py_ccache_container_methods,
1611 };
1612
1613 MODULE_INIT_FUNC(credentials)
1614 {
1615         PyObject *m;
1616         if (pytalloc_BaseObject_PyType_Ready(&PyCredentials) < 0)
1617                 return NULL;
1618
1619         if (pytalloc_BaseObject_PyType_Ready(&PyCredentialCacheContainer) < 0)
1620                 return NULL;
1621
1622         m = PyModule_Create(&moduledef);
1623         if (m == NULL)
1624                 return NULL;
1625
1626         PyModule_AddObject(m, "UNINITIALISED", PyLong_FromLong(CRED_UNINITIALISED));
1627         PyModule_AddObject(m, "SMB_CONF", PyLong_FromLong(CRED_SMB_CONF));
1628         PyModule_AddObject(m, "CALLBACK", PyLong_FromLong(CRED_CALLBACK));
1629         PyModule_AddObject(m, "GUESS_ENV", PyLong_FromLong(CRED_GUESS_ENV));
1630         PyModule_AddObject(m, "GUESS_FILE", PyLong_FromLong(CRED_GUESS_FILE));
1631         PyModule_AddObject(m, "CALLBACK_RESULT", PyLong_FromLong(CRED_CALLBACK_RESULT));
1632         PyModule_AddObject(m, "SPECIFIED", PyLong_FromLong(CRED_SPECIFIED));
1633
1634         PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_DESIRED));
1635         PyModule_AddObject(m, "DONT_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_DISABLED));
1636         PyModule_AddObject(m, "MUST_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_REQUIRED));
1637
1638         PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE",  PyLong_FromLong(CRED_AUTO_KRB_FORWARDABLE));
1639         PyModule_AddObject(m, "NO_KRB_FORWARDABLE",    PyLong_FromLong(CRED_NO_KRB_FORWARDABLE));
1640         PyModule_AddObject(m, "FORCE_KRB_FORWARDABLE", PyLong_FromLong(CRED_FORCE_KRB_FORWARDABLE));
1641         PyModule_AddObject(m, "CLI_CRED_NTLM2", PyLong_FromLong(CLI_CRED_NTLM2));
1642         PyModule_AddObject(m, "CLI_CRED_NTLMv2_AUTH", PyLong_FromLong(CLI_CRED_NTLMv2_AUTH));
1643         PyModule_AddObject(m, "CLI_CRED_LANMAN_AUTH", PyLong_FromLong(CLI_CRED_LANMAN_AUTH));
1644         PyModule_AddObject(m, "CLI_CRED_NTLM_AUTH", PyLong_FromLong(CLI_CRED_NTLM_AUTH));
1645         PyModule_AddObject(m, "CLI_CRED_CLEAR_AUTH", PyLong_FromLong(CLI_CRED_CLEAR_AUTH));
1646
1647         PyModule_AddObject(m, "SMB_SIGNING_DEFAULT", PyLong_FromLong(SMB_SIGNING_DEFAULT));
1648         PyModule_AddObject(m, "SMB_SIGNING_OFF", PyLong_FromLong(SMB_SIGNING_OFF));
1649         PyModule_AddObject(m, "SMB_SIGNING_IF_REQUIRED", PyLong_FromLong(SMB_SIGNING_IF_REQUIRED));
1650         PyModule_AddObject(m, "SMB_SIGNING_DESIRED", PyLong_FromLong(SMB_SIGNING_DESIRED));
1651         PyModule_AddObject(m, "SMB_SIGNING_REQUIRED", PyLong_FromLong(SMB_SIGNING_REQUIRED));
1652
1653         PyModule_AddObject(m, "SMB_ENCRYPTION_DEFAULT", PyLong_FromLong(SMB_ENCRYPTION_DEFAULT));
1654         PyModule_AddObject(m, "SMB_ENCRYPTION_OFF", PyLong_FromLong(SMB_ENCRYPTION_OFF));
1655         PyModule_AddObject(m, "SMB_ENCRYPTION_IF_REQUIRED", PyLong_FromLong(SMB_ENCRYPTION_IF_REQUIRED));
1656         PyModule_AddObject(m, "SMB_ENCRYPTION_DESIRED", PyLong_FromLong(SMB_ENCRYPTION_DESIRED));
1657         PyModule_AddObject(m, "SMB_ENCRYPTION_REQUIRED", PyLong_FromLong(SMB_ENCRYPTION_REQUIRED));
1658
1659         Py_INCREF(&PyCredentials);
1660         PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
1661         Py_INCREF(&PyCredentialCacheContainer);
1662         PyModule_AddObject(m, "CredentialCacheContainer", (PyObject *)&PyCredentialCacheContainer);
1663         return m;
1664 }