auth/spnego: inline gensec_spnego_update_client() into gensec_spnego_update_send()
[vlendec/samba-autobuild/.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 "pycredentials.h"
23 #include "param/param.h"
24 #include "lib/cmdline/credentials.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 "auth/credentials/credentials_internal.h"
34
35 void initcredentials(void);
36
37 static PyObject *PyString_FromStringOrNULL(const char *str)
38 {
39         if (str == NULL)
40                 Py_RETURN_NONE;
41         return PyStr_FromString(str);
42 }
43
44 static PyObject *py_creds_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
45 {
46         return pytalloc_steal(type, cli_credentials_init(NULL));
47 }
48
49 static PyObject *py_creds_get_username(PyObject *self, PyObject *unused)
50 {
51         return PyString_FromStringOrNULL(cli_credentials_get_username(PyCredentials_AsCliCredentials(self)));
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
60         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
61                 return NULL;
62         }
63         obt = _obt;
64
65         return PyBool_FromLong(cli_credentials_set_username(PyCredentials_AsCliCredentials(self), newval, obt));
66 }
67
68 static PyObject *py_creds_get_ntlm_username_domain(PyObject *self, PyObject *unused)
69 {
70         TALLOC_CTX *frame = talloc_stackframe();
71         const char *user = NULL;
72         const char *domain = NULL;
73         PyObject *ret = NULL;
74         cli_credentials_get_ntlm_username_domain(PyCredentials_AsCliCredentials(self),
75                                                  frame, &user, &domain);
76         ret = Py_BuildValue("(OO)",
77                             PyString_FromStringOrNULL(user),
78                             PyString_FromStringOrNULL(domain));
79         TALLOC_FREE(frame);
80         return ret;
81 }
82
83 static PyObject *py_creds_get_ntlm_response(PyObject *self, PyObject *args, PyObject *kwargs)
84 {
85         TALLOC_CTX *frame = talloc_stackframe();
86         PyObject *ret = NULL;
87         int flags;
88         struct timeval tv_now;
89         NTTIME server_timestamp;
90         DATA_BLOB challenge = data_blob_null;
91         DATA_BLOB target_info = data_blob_null;
92         NTSTATUS status;
93         DATA_BLOB lm_response = data_blob_null;
94         DATA_BLOB nt_response = data_blob_null;
95         DATA_BLOB lm_session_key = data_blob_null;
96         DATA_BLOB nt_session_key = data_blob_null;
97         const char *kwnames[] = { "flags", "challenge",
98                                   "target_info",
99                                   NULL };
100
101         tv_now = timeval_current();
102         server_timestamp = timeval_to_nttime(&tv_now);
103
104         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is#|s#",
105                                          discard_const_p(char *, kwnames),
106                                          &flags,
107                                          &challenge.data,
108                                          &challenge.length,
109                                          &target_info.data,
110                                          &target_info.length)) {
111                 return NULL;
112         }
113
114         status = cli_credentials_get_ntlm_response(PyCredentials_AsCliCredentials(self),
115                                                    frame, &flags,
116                                                    challenge,
117                                                    &server_timestamp,
118                                                    target_info,
119                                                    &lm_response, &nt_response,
120                                                    &lm_session_key, &nt_session_key);
121
122         if (!NT_STATUS_IS_OK(status)) {
123                 PyErr_SetNTSTATUS(status);
124                 TALLOC_FREE(frame);
125                 return NULL;
126         }
127
128         ret = Py_BuildValue("{sis" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN
129                                     "s" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN "}",
130                             "flags", flags,
131                             "lm_reponse",
132                             (const char *)lm_response.data, lm_response.length,
133                             "nt_response",
134                             (const char *)nt_response.data, nt_response.length,
135                             "lm_session_key",
136                             (const char *)lm_session_key.data, lm_session_key.length,
137                             "nt_session_key",
138                             (const char *)nt_session_key.data, nt_session_key.length);
139         TALLOC_FREE(frame);
140         return ret;
141 }
142
143 static PyObject *py_creds_get_principal(PyObject *self, PyObject *unused)
144 {
145         TALLOC_CTX *frame = talloc_stackframe();
146         PyObject *ret = PyString_FromStringOrNULL(cli_credentials_get_principal(PyCredentials_AsCliCredentials(self), frame));
147         TALLOC_FREE(frame);
148         return ret;
149 }
150
151 static PyObject *py_creds_set_principal(PyObject *self, PyObject *args)
152 {
153         char *newval;
154         enum credentials_obtained obt = CRED_SPECIFIED;
155         int _obt = obt;
156
157         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
158                 return NULL;
159         }
160         obt = _obt;
161
162         return PyBool_FromLong(cli_credentials_set_principal(PyCredentials_AsCliCredentials(self), newval, obt));
163 }
164
165 static PyObject *py_creds_get_password(PyObject *self, PyObject *unused)
166 {
167         return PyString_FromStringOrNULL(cli_credentials_get_password(PyCredentials_AsCliCredentials(self)));
168 }
169
170 static PyObject *py_creds_set_password(PyObject *self, PyObject *args)
171 {
172         char *newval;
173         enum credentials_obtained obt = CRED_SPECIFIED;
174         int _obt = obt;
175
176         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
177                 return NULL;
178         }
179         obt = _obt;
180
181         return PyBool_FromLong(cli_credentials_set_password(PyCredentials_AsCliCredentials(self), newval, obt));
182 }
183
184 static PyObject *py_creds_set_utf16_password(PyObject *self, PyObject *args)
185 {
186         enum credentials_obtained obt = CRED_SPECIFIED;
187         int _obt = obt;
188         PyObject *newval = NULL;
189         DATA_BLOB blob = data_blob_null;
190         Py_ssize_t size =  0;
191         int result;
192         bool ok;
193
194         if (!PyArg_ParseTuple(args, "O|i", &newval, &_obt)) {
195                 return NULL;
196         }
197         obt = _obt;
198
199         result = PyBytes_AsStringAndSize(newval, (char **)&blob.data, &size);
200         if (result != 0) {
201                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to Bytes");
202                 return NULL;
203         }
204         blob.length = size;
205
206         ok = cli_credentials_set_utf16_password(PyCredentials_AsCliCredentials(self),
207                                                 &blob, obt);
208
209         return PyBool_FromLong(ok);
210 }
211
212 static PyObject *py_creds_get_old_password(PyObject *self, PyObject *unused)
213 {
214         return PyString_FromStringOrNULL(cli_credentials_get_old_password(PyCredentials_AsCliCredentials(self)));
215 }
216
217 static PyObject *py_creds_set_old_password(PyObject *self, PyObject *args)
218 {
219         char *oldval;
220         enum credentials_obtained obt = CRED_SPECIFIED;
221         int _obt = obt;
222
223         if (!PyArg_ParseTuple(args, "s|i", &oldval, &_obt)) {
224                 return NULL;
225         }
226         obt = _obt;
227
228         return PyBool_FromLong(cli_credentials_set_old_password(PyCredentials_AsCliCredentials(self), oldval, obt));
229 }
230
231 static PyObject *py_creds_set_old_utf16_password(PyObject *self, PyObject *args)
232 {
233         PyObject *oldval = NULL;
234         DATA_BLOB blob = data_blob_null;
235         Py_ssize_t size =  0;
236         int result;
237         bool ok;
238
239         if (!PyArg_ParseTuple(args, "O", &oldval)) {
240                 return NULL;
241         }
242
243         result = PyBytes_AsStringAndSize(oldval, (char **)&blob.data, &size);
244         if (result != 0) {
245                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to Bytes");
246                 return NULL;
247         }
248         blob.length = size;
249
250         ok = cli_credentials_set_old_utf16_password(PyCredentials_AsCliCredentials(self),
251                                                     &blob);
252
253         return PyBool_FromLong(ok);
254 }
255
256 static PyObject *py_creds_get_domain(PyObject *self, PyObject *unused)
257 {
258         return PyString_FromStringOrNULL(cli_credentials_get_domain(PyCredentials_AsCliCredentials(self)));
259 }
260
261 static PyObject *py_creds_set_domain(PyObject *self, PyObject *args)
262 {
263         char *newval;
264         enum credentials_obtained obt = CRED_SPECIFIED;
265         int _obt = obt;
266
267         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
268                 return NULL;
269         }
270         obt = _obt;
271
272         return PyBool_FromLong(cli_credentials_set_domain(PyCredentials_AsCliCredentials(self), newval, obt));
273 }
274
275 static PyObject *py_creds_get_realm(PyObject *self, PyObject *unused)
276 {
277         return PyString_FromStringOrNULL(cli_credentials_get_realm(PyCredentials_AsCliCredentials(self)));
278 }
279
280 static PyObject *py_creds_set_realm(PyObject *self, PyObject *args)
281 {
282         char *newval;
283         enum credentials_obtained obt = CRED_SPECIFIED;
284         int _obt = obt;
285
286         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
287                 return NULL;
288         }
289         obt = _obt;
290
291         return PyBool_FromLong(cli_credentials_set_realm(PyCredentials_AsCliCredentials(self), newval, obt));
292 }
293
294 static PyObject *py_creds_get_bind_dn(PyObject *self, PyObject *unused)
295 {
296         return PyString_FromStringOrNULL(cli_credentials_get_bind_dn(PyCredentials_AsCliCredentials(self)));
297 }
298
299 static PyObject *py_creds_set_bind_dn(PyObject *self, PyObject *args)
300 {
301         char *newval;
302         if (!PyArg_ParseTuple(args, "s", &newval))
303                 return NULL;
304
305         return PyBool_FromLong(cli_credentials_set_bind_dn(PyCredentials_AsCliCredentials(self), newval));
306 }
307
308 static PyObject *py_creds_get_workstation(PyObject *self, PyObject *unused)
309 {
310         return PyString_FromStringOrNULL(cli_credentials_get_workstation(PyCredentials_AsCliCredentials(self)));
311 }
312
313 static PyObject *py_creds_set_workstation(PyObject *self, PyObject *args)
314 {
315         char *newval;
316         enum credentials_obtained obt = CRED_SPECIFIED;
317         int _obt = obt;
318
319         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
320                 return NULL;
321         }
322         obt = _obt;
323
324         return PyBool_FromLong(cli_credentials_set_workstation(PyCredentials_AsCliCredentials(self), newval, obt));
325 }
326
327 static PyObject *py_creds_is_anonymous(PyObject *self, PyObject *unused)
328 {
329         return PyBool_FromLong(cli_credentials_is_anonymous(PyCredentials_AsCliCredentials(self)));
330 }
331
332 static PyObject *py_creds_set_anonymous(PyObject *self, PyObject *unused)
333 {
334         cli_credentials_set_anonymous(PyCredentials_AsCliCredentials(self));
335         Py_RETURN_NONE;
336 }
337
338 static PyObject *py_creds_authentication_requested(PyObject *self, PyObject *unused)
339 {
340         return PyBool_FromLong(cli_credentials_authentication_requested(PyCredentials_AsCliCredentials(self)));
341 }
342
343 static PyObject *py_creds_wrong_password(PyObject *self, PyObject *unused)
344 {
345         return PyBool_FromLong(cli_credentials_wrong_password(PyCredentials_AsCliCredentials(self)));
346 }
347
348 static PyObject *py_creds_set_cmdline_callbacks(PyObject *self, PyObject *unused)
349 {
350         return PyBool_FromLong(cli_credentials_set_cmdline_callbacks(PyCredentials_AsCliCredentials(self)));
351 }
352
353 static PyObject *py_creds_parse_string(PyObject *self, PyObject *args)
354 {
355         char *newval;
356         enum credentials_obtained obt = CRED_SPECIFIED;
357         int _obt = obt;
358
359         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
360                 return NULL;
361         }
362         obt = _obt;
363
364         cli_credentials_parse_string(PyCredentials_AsCliCredentials(self), newval, obt);
365         Py_RETURN_NONE;
366 }
367
368 static PyObject *py_creds_parse_file(PyObject *self, PyObject *args)
369 {
370         char *newval;
371         enum credentials_obtained obt = CRED_SPECIFIED;
372         int _obt = obt;
373
374         if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
375                 return NULL;
376         }
377         obt = _obt;
378
379         cli_credentials_parse_file(PyCredentials_AsCliCredentials(self), newval, obt);
380         Py_RETURN_NONE;
381 }
382
383 static PyObject *py_cli_credentials_set_password_will_be_nt_hash(PyObject *self, PyObject *args)
384 {
385         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
386         PyObject *py_val = NULL;
387         bool val = false;
388
389         if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &py_val)) {
390                 return NULL;
391         }
392         val = PyObject_IsTrue(py_val);
393
394         cli_credentials_set_password_will_be_nt_hash(creds, val);
395         Py_RETURN_NONE;
396 }
397
398 static PyObject *py_creds_get_nt_hash(PyObject *self, PyObject *unused)
399 {
400         PyObject *ret;
401         struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
402         struct samr_Password *ntpw = cli_credentials_get_nt_hash(creds, creds);
403
404         ret = PyBytes_FromStringAndSize(discard_const_p(char, ntpw->hash), 16);
405         TALLOC_FREE(ntpw);
406         return ret;
407 }
408
409 static PyObject *py_creds_get_kerberos_state(PyObject *self, PyObject *unused)
410 {
411         int state = cli_credentials_get_kerberos_state(PyCredentials_AsCliCredentials(self));
412         return PyInt_FromLong(state);
413 }
414
415 static PyObject *py_creds_set_kerberos_state(PyObject *self, PyObject *args)
416 {
417         int state;
418         if (!PyArg_ParseTuple(args, "i", &state))
419                 return NULL;
420
421         cli_credentials_set_kerberos_state(PyCredentials_AsCliCredentials(self), state);
422         Py_RETURN_NONE;
423 }
424
425 static PyObject *py_creds_set_krb_forwardable(PyObject *self, PyObject *args)
426 {
427         int state;
428         if (!PyArg_ParseTuple(args, "i", &state))
429                 return NULL;
430
431         cli_credentials_set_krb_forwardable(PyCredentials_AsCliCredentials(self), state);
432         Py_RETURN_NONE;
433 }
434
435
436 static PyObject *py_creds_get_forced_sasl_mech(PyObject *self, PyObject *unused)
437 {
438         return PyString_FromStringOrNULL(cli_credentials_get_forced_sasl_mech(PyCredentials_AsCliCredentials(self)));
439 }
440
441 static PyObject *py_creds_set_forced_sasl_mech(PyObject *self, PyObject *args)
442 {
443         char *newval;
444         enum credentials_obtained obt = CRED_SPECIFIED;
445         int _obt = obt;
446
447         if (!PyArg_ParseTuple(args, "s", &newval)) {
448                 return NULL;
449         }
450         obt = _obt;
451
452         cli_credentials_set_forced_sasl_mech(PyCredentials_AsCliCredentials(self), newval);
453         Py_RETURN_NONE;
454 }
455
456 static PyObject *py_creds_guess(PyObject *self, PyObject *args)
457 {
458         PyObject *py_lp_ctx = Py_None;
459         struct loadparm_context *lp_ctx;
460         TALLOC_CTX *mem_ctx;
461         struct cli_credentials *creds;
462
463         creds = PyCredentials_AsCliCredentials(self);
464
465         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
466                 return NULL;
467
468         mem_ctx = talloc_new(NULL);
469         if (mem_ctx == NULL) {
470                 PyErr_NoMemory();
471                 return NULL;
472         }
473
474         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
475         if (lp_ctx == NULL) {
476                 talloc_free(mem_ctx);
477                 return NULL;
478         }
479
480         cli_credentials_guess(creds, lp_ctx);
481
482         talloc_free(mem_ctx);
483
484         Py_RETURN_NONE;
485 }
486
487 static PyObject *py_creds_set_machine_account(PyObject *self, PyObject *args)
488 {
489         PyObject *py_lp_ctx = Py_None;
490         struct loadparm_context *lp_ctx;
491         NTSTATUS status;
492         struct cli_credentials *creds;
493         TALLOC_CTX *mem_ctx;
494
495         creds = PyCredentials_AsCliCredentials(self);
496
497         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
498                 return NULL;
499
500         mem_ctx = talloc_new(NULL);
501         if (mem_ctx == NULL) {
502                 PyErr_NoMemory();
503                 return NULL;
504         }
505
506         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
507         if (lp_ctx == NULL) {
508                 talloc_free(mem_ctx);
509                 return NULL;
510         }
511
512         status = cli_credentials_set_machine_account(creds, lp_ctx);
513         talloc_free(mem_ctx);
514
515         PyErr_NTSTATUS_IS_ERR_RAISE(status);
516
517         Py_RETURN_NONE;
518 }
519
520 static PyObject *PyCredentialCacheContainer_from_ccache_container(struct ccache_container *ccc)
521 {
522         return pytalloc_reference(&PyCredentialCacheContainer, ccc);
523 }
524
525
526 static PyObject *py_creds_get_named_ccache(PyObject *self, PyObject *args)
527 {
528         PyObject *py_lp_ctx = Py_None;
529         char *ccache_name;
530         struct loadparm_context *lp_ctx;
531         struct ccache_container *ccc;
532         struct tevent_context *event_ctx;
533         int ret;
534         const char *error_string;
535         struct cli_credentials *creds;
536         TALLOC_CTX *mem_ctx;
537
538         creds = PyCredentials_AsCliCredentials(self);
539
540         if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name))
541                 return NULL;
542
543         mem_ctx = talloc_new(NULL);
544         if (mem_ctx == NULL) {
545                 PyErr_NoMemory();
546                 return NULL;
547         }
548
549         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
550         if (lp_ctx == NULL) {
551                 talloc_free(mem_ctx);
552                 return NULL;
553         }
554
555         event_ctx = samba_tevent_context_init(mem_ctx);
556
557         ret = cli_credentials_get_named_ccache(creds, event_ctx, lp_ctx,
558                                                ccache_name, &ccc, &error_string);
559         talloc_unlink(mem_ctx, lp_ctx);
560         if (ret == 0) {
561                 talloc_steal(ccc, event_ctx);
562                 talloc_free(mem_ctx);
563                 return PyCredentialCacheContainer_from_ccache_container(ccc);
564         }
565
566         PyErr_SetString(PyExc_RuntimeError, error_string?error_string:"NULL");
567
568         talloc_free(mem_ctx);
569         return NULL;
570 }
571
572 static PyObject *py_creds_set_gensec_features(PyObject *self, PyObject *args)
573 {
574         unsigned int gensec_features;
575
576         if (!PyArg_ParseTuple(args, "I", &gensec_features))
577                 return NULL;
578
579         cli_credentials_set_gensec_features(PyCredentials_AsCliCredentials(self), gensec_features);
580
581         Py_RETURN_NONE;
582 }
583
584 static PyObject *py_creds_get_gensec_features(PyObject *self, PyObject *args)
585 {
586         unsigned int gensec_features;
587
588         gensec_features = cli_credentials_get_gensec_features(PyCredentials_AsCliCredentials(self));
589         return PyInt_FromLong(gensec_features);
590 }
591
592 static PyObject *py_creds_new_client_authenticator(PyObject *self,
593                                                    PyObject *args)
594 {
595         struct netr_Authenticator auth;
596         struct cli_credentials *creds = NULL;
597         struct netlogon_creds_CredentialState *nc = NULL;
598         PyObject *ret = NULL;
599
600         creds = PyCredentials_AsCliCredentials(self);
601         if (creds == NULL) {
602                 PyErr_SetString(PyExc_RuntimeError,
603                                 "Failed to get credentials from python");
604                 return NULL;
605         }
606
607         nc = creds->netlogon_creds;
608         if (nc == NULL) {
609                 PyErr_SetString(PyExc_ValueError,
610                                 "No netlogon credentials cannot make "
611                                 "client authenticator");
612                 return NULL;
613         }
614
615         netlogon_creds_client_authenticator(
616                 nc,
617                 &auth);
618         ret = Py_BuildValue("{ss#si}",
619                             "credential",
620                             (const char *) &auth.cred, sizeof(auth.cred),
621                             "timestamp", auth.timestamp);
622         return ret;
623 }
624
625 static PyObject *py_creds_set_secure_channel_type(PyObject *self, PyObject *args)
626 {
627         unsigned int channel_type;
628
629         if (!PyArg_ParseTuple(args, "I", &channel_type))
630                 return NULL;
631
632         cli_credentials_set_secure_channel_type(
633                 PyCredentials_AsCliCredentials(self),
634                 channel_type);
635
636         Py_RETURN_NONE;
637 }
638
639 static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self,
640                                                       PyObject *args)
641 {
642         DATA_BLOB data = data_blob_null;
643         struct cli_credentials    *creds  = NULL;
644         struct netr_CryptPassword *pwd    = NULL;
645         NTSTATUS status;
646         PyObject *py_cp = Py_None;
647
648         creds = PyCredentials_AsCliCredentials(self);
649
650         if (!PyArg_ParseTuple(args, "|O", &py_cp)) {
651                 return NULL;
652         }
653         pwd = pytalloc_get_type(py_cp, struct netr_CryptPassword);
654         data.length = sizeof(struct netr_CryptPassword);
655         data.data   = (uint8_t *)pwd;
656         status = netlogon_creds_session_encrypt(creds->netlogon_creds, data);
657
658         PyErr_NTSTATUS_IS_ERR_RAISE(status);
659
660         Py_RETURN_NONE;
661 }
662
663 static PyMethodDef py_creds_methods[] = {
664         { "get_username", py_creds_get_username, METH_NOARGS,
665                 "S.get_username() -> username\nObtain username." },
666         { "set_username", py_creds_set_username, METH_VARARGS,
667                 "S.set_username(name[, credentials.SPECIFIED]) -> None\n"
668                 "Change username." },
669         { "get_principal", py_creds_get_principal, METH_NOARGS,
670                 "S.get_principal() -> user@realm\nObtain user principal." },
671         { "set_principal", py_creds_set_principal, METH_VARARGS,
672                 "S.set_principal(name[, credentials.SPECIFIED]) -> None\n"
673                 "Change principal." },
674         { "get_password", py_creds_get_password, METH_NOARGS,
675                 "S.get_password() -> password\n"
676                 "Obtain password." },
677         { "get_ntlm_username_domain", py_creds_get_ntlm_username_domain, METH_NOARGS,
678                 "S.get_ntlm_username_domain() -> (domain, username)\n"
679                 "Obtain NTLM username and domain, split up either as (DOMAIN, user) or (\"\", \"user@realm\")." },
680         { "get_ntlm_response", (PyCFunction)py_creds_get_ntlm_response, METH_VARARGS | METH_KEYWORDS,
681                 "S.get_ntlm_response"
682                 "(flags, challenge[, target_info]) -> "
683                 "(flags, lm_response, nt_response, lm_session_key, nt_session_key)\n"
684                 "Obtain LM or NTLM response." },
685         { "set_password", py_creds_set_password, METH_VARARGS,
686                 "S.set_password(password[, credentials.SPECIFIED]) -> None\n"
687                 "Change password." },
688         { "set_utf16_password", py_creds_set_utf16_password, METH_VARARGS,
689                 "S.set_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
690                 "Change password." },
691         { "get_old_password", py_creds_get_old_password, METH_NOARGS,
692                 "S.get_old_password() -> password\n"
693                 "Obtain old password." },
694         { "set_old_password", py_creds_set_old_password, METH_VARARGS,
695                 "S.set_old_password(password[, credentials.SPECIFIED]) -> None\n"
696                 "Change old password." },
697         { "set_old_utf16_password", py_creds_set_old_utf16_password, METH_VARARGS,
698                 "S.set_old_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
699                 "Change old password." },
700         { "get_domain", py_creds_get_domain, METH_NOARGS,
701                 "S.get_domain() -> domain\n"
702                 "Obtain domain name." },
703         { "set_domain", py_creds_set_domain, METH_VARARGS,
704                 "S.set_domain(domain[, credentials.SPECIFIED]) -> None\n"
705                 "Change domain name." },
706         { "get_realm", py_creds_get_realm, METH_NOARGS,
707                 "S.get_realm() -> realm\n"
708                 "Obtain realm name." },
709         { "set_realm", py_creds_set_realm, METH_VARARGS,
710                 "S.set_realm(realm[, credentials.SPECIFIED]) -> None\n"
711                 "Change realm name." },
712         { "get_bind_dn", py_creds_get_bind_dn, METH_NOARGS,
713                 "S.get_bind_dn() -> bind dn\n"
714                 "Obtain bind DN." },
715         { "set_bind_dn", py_creds_set_bind_dn, METH_VARARGS,
716                 "S.set_bind_dn(bind_dn) -> None\n"
717                 "Change bind DN." },
718         { "is_anonymous", py_creds_is_anonymous, METH_NOARGS,
719                 NULL },
720         { "set_anonymous", py_creds_set_anonymous, METH_NOARGS,
721                 "S.set_anonymous() -> None\n"
722                 "Use anonymous credentials." },
723         { "get_workstation", py_creds_get_workstation, METH_NOARGS,
724                 NULL },
725         { "set_workstation", py_creds_set_workstation, METH_VARARGS,
726                 NULL },
727         { "authentication_requested", py_creds_authentication_requested, METH_NOARGS,
728                 NULL },
729         { "wrong_password", py_creds_wrong_password, METH_NOARGS,
730                 "S.wrong_password() -> bool\n"
731                 "Indicate the returned password was incorrect." },
732         { "set_cmdline_callbacks", py_creds_set_cmdline_callbacks, METH_NOARGS,
733                 "S.set_cmdline_callbacks() -> bool\n"
734                 "Use command-line to obtain credentials not explicitly set." },
735         { "parse_string", py_creds_parse_string, METH_VARARGS,
736                 "S.parse_string(text[, credentials.SPECIFIED]) -> None\n"
737                 "Parse credentials string." },
738         { "parse_file", py_creds_parse_file, METH_VARARGS,
739                 "S.parse_file(filename[, credentials.SPECIFIED]) -> None\n"
740                 "Parse credentials file." },
741         { "set_password_will_be_nt_hash",
742                 py_cli_credentials_set_password_will_be_nt_hash, METH_VARARGS,
743                 "S.set_password_will_be_nt_hash(bool) -> None\n"
744                 "Alters the behaviour of S.set_password() "
745                 "to expect the NTHASH as hexstring." },
746         { "get_nt_hash", py_creds_get_nt_hash, METH_NOARGS,
747                 NULL },
748         { "get_kerberos_state", py_creds_get_kerberos_state, METH_NOARGS,
749                 NULL },
750         { "set_kerberos_state", py_creds_set_kerberos_state, METH_VARARGS,
751                 NULL },
752         { "set_krb_forwardable", py_creds_set_krb_forwardable, METH_VARARGS,
753                 NULL },
754         { "guess", py_creds_guess, METH_VARARGS, NULL },
755         { "set_machine_account", py_creds_set_machine_account, METH_VARARGS, NULL },
756         { "get_named_ccache", py_creds_get_named_ccache, METH_VARARGS, NULL },
757         { "set_gensec_features", py_creds_set_gensec_features, METH_VARARGS, NULL },
758         { "get_gensec_features", py_creds_get_gensec_features, METH_NOARGS, NULL },
759         { "get_forced_sasl_mech", py_creds_get_forced_sasl_mech, METH_NOARGS,
760                 "S.get_forced_sasl_mech() -> SASL mechanism\nObtain forced SASL mechanism." },
761         { "set_forced_sasl_mech", py_creds_set_forced_sasl_mech, METH_VARARGS,
762                 "S.set_forced_sasl_mech(name) -> None\n"
763                 "Set forced SASL mechanism." },
764         { "new_client_authenticator",
765                 py_creds_new_client_authenticator,
766                 METH_NOARGS,
767                 "S.new_client_authenticator() -> Authenticator\n"
768                 "Get a new client NETLOGON_AUTHENTICATOR"},
769         { "set_secure_channel_type", py_creds_set_secure_channel_type,
770           METH_VARARGS, NULL },
771         { "encrypt_netr_crypt_password",
772                 py_creds_encrypt_netr_crypt_password,
773                 METH_VARARGS,
774                 "S.encrypt_netr_crypt_password(password) -> NTSTATUS\n"
775                 "Encrypt the supplied password using the session key and\n"
776                 "the negotiated encryption algorithm in place\n"
777                 "i.e. it overwrites the original data"},
778         { NULL }
779 };
780
781 static struct PyModuleDef moduledef = {
782     PyModuleDef_HEAD_INIT,
783     .m_name = "credentials",
784     .m_doc = "Credentials management.",
785     .m_size = -1,
786     .m_methods = py_creds_methods,
787 };
788
789 PyTypeObject PyCredentials = {
790         .tp_name = "credentials.Credentials",
791         .tp_new = py_creds_new,
792         .tp_flags = Py_TPFLAGS_DEFAULT,
793         .tp_methods = py_creds_methods,
794 };
795
796
797 PyTypeObject PyCredentialCacheContainer = {
798         .tp_name = "credentials.CredentialCacheContainer",
799         .tp_flags = Py_TPFLAGS_DEFAULT,
800 };
801
802 MODULE_INIT_FUNC(credentials)
803 {
804         PyObject *m;
805         if (pytalloc_BaseObject_PyType_Ready(&PyCredentials) < 0)
806                 return NULL;
807
808         if (pytalloc_BaseObject_PyType_Ready(&PyCredentialCacheContainer) < 0)
809                 return NULL;
810
811         m = PyModule_Create(&moduledef);
812         if (m == NULL)
813                 return NULL;
814
815         PyModule_AddObject(m, "UNINITIALISED", PyInt_FromLong(CRED_UNINITIALISED));
816         PyModule_AddObject(m, "CALLBACK", PyInt_FromLong(CRED_CALLBACK));
817         PyModule_AddObject(m, "GUESS_ENV", PyInt_FromLong(CRED_GUESS_ENV));
818         PyModule_AddObject(m, "GUESS_FILE", PyInt_FromLong(CRED_GUESS_FILE));
819         PyModule_AddObject(m, "CALLBACK_RESULT", PyInt_FromLong(CRED_CALLBACK_RESULT));
820         PyModule_AddObject(m, "SPECIFIED", PyInt_FromLong(CRED_SPECIFIED));
821
822         PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyInt_FromLong(CRED_AUTO_USE_KERBEROS));
823         PyModule_AddObject(m, "DONT_USE_KERBEROS", PyInt_FromLong(CRED_DONT_USE_KERBEROS));
824         PyModule_AddObject(m, "MUST_USE_KERBEROS", PyInt_FromLong(CRED_MUST_USE_KERBEROS));
825
826         PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE",  PyInt_FromLong(CRED_AUTO_KRB_FORWARDABLE));
827         PyModule_AddObject(m, "NO_KRB_FORWARDABLE",    PyInt_FromLong(CRED_NO_KRB_FORWARDABLE));
828         PyModule_AddObject(m, "FORCE_KRB_FORWARDABLE", PyInt_FromLong(CRED_FORCE_KRB_FORWARDABLE));
829         PyModule_AddObject(m, "CLI_CRED_NTLM2", PyInt_FromLong(CLI_CRED_NTLM2));
830         PyModule_AddObject(m, "CLI_CRED_NTLMv2_AUTH", PyInt_FromLong(CLI_CRED_NTLMv2_AUTH));
831         PyModule_AddObject(m, "CLI_CRED_LANMAN_AUTH", PyInt_FromLong(CLI_CRED_LANMAN_AUTH));
832         PyModule_AddObject(m, "CLI_CRED_NTLM_AUTH", PyInt_FromLong(CLI_CRED_NTLM_AUTH));
833         PyModule_AddObject(m, "CLI_CRED_CLEAR_AUTH", PyInt_FromLong(CLI_CRED_CLEAR_AUTH));
834
835         Py_INCREF(&PyCredentials);
836         PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
837         Py_INCREF(&PyCredentialCacheContainer);
838         PyModule_AddObject(m, "CredentialCacheContainer", (PyObject *)&PyCredentialCacheContainer);
839         return m;
840 }