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