s3:blocking: call change_to_user_by_fsp() when dbwrap_watched_watch* finishes
[Samba.git] / auth / credentials / pycredentials.c
blob446f30970a2f68c9d0bf1081e93afedb5396f6ef
1 /*
2 Unix SMB/CIFS implementation.
3 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
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.
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.
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/>.
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"
38 void initcredentials(void);
40 static PyObject *py_creds_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
42 return pytalloc_steal(type, cli_credentials_init(NULL));
45 static PyObject *py_creds_get_username(PyObject *self, PyObject *unused)
47 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
48 if (creds == NULL) {
49 PyErr_Format(PyExc_TypeError, "Credentials expected");
50 return NULL;
52 return PyString_FromStringOrNULL(cli_credentials_get_username(creds));
55 static PyObject *py_creds_set_username(PyObject *self, PyObject *args)
57 char *newval;
58 enum credentials_obtained obt = CRED_SPECIFIED;
59 int _obt = obt;
60 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
61 if (creds == NULL) {
62 PyErr_Format(PyExc_TypeError, "Credentials expected");
63 return NULL;
66 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
67 return NULL;
69 obt = _obt;
71 return PyBool_FromLong(cli_credentials_set_username(creds, newval, obt));
74 static PyObject *py_creds_get_ntlm_username_domain(PyObject *self, PyObject *unused)
76 TALLOC_CTX *frame = talloc_stackframe();
77 const char *user = NULL;
78 const char *domain = NULL;
79 PyObject *ret = NULL;
80 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
81 if (creds == NULL) {
82 PyErr_Format(PyExc_TypeError, "Credentials expected");
83 return NULL;
85 cli_credentials_get_ntlm_username_domain(creds,
86 frame, &user, &domain);
87 ret = Py_BuildValue("(ss)",
88 user,
89 domain);
91 TALLOC_FREE(frame);
92 return ret;
95 static PyObject *py_creds_get_ntlm_response(PyObject *self, PyObject *args, PyObject *kwargs)
97 TALLOC_CTX *frame = talloc_stackframe();
98 PyObject *ret = NULL;
99 int flags;
100 struct timeval tv_now;
101 NTTIME server_timestamp;
102 DATA_BLOB challenge = data_blob_null;
103 DATA_BLOB target_info = data_blob_null;
104 NTSTATUS status;
105 DATA_BLOB lm_response = data_blob_null;
106 DATA_BLOB nt_response = data_blob_null;
107 DATA_BLOB lm_session_key = data_blob_null;
108 DATA_BLOB nt_session_key = data_blob_null;
109 const char *kwnames[] = { "flags", "challenge",
110 "target_info",
111 NULL };
112 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
113 if (creds == NULL) {
114 PyErr_Format(PyExc_TypeError, "Credentials expected");
115 return NULL;
118 tv_now = timeval_current();
119 server_timestamp = timeval_to_nttime(&tv_now);
121 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is#|s#",
122 discard_const_p(char *, kwnames),
123 &flags,
124 &challenge.data,
125 &challenge.length,
126 &target_info.data,
127 &target_info.length)) {
128 return NULL;
131 status = cli_credentials_get_ntlm_response(creds,
132 frame, &flags,
133 challenge,
134 &server_timestamp,
135 target_info,
136 &lm_response, &nt_response,
137 &lm_session_key, &nt_session_key);
139 if (!NT_STATUS_IS_OK(status)) {
140 PyErr_SetNTSTATUS(status);
141 TALLOC_FREE(frame);
142 return NULL;
145 ret = Py_BuildValue("{sis" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN
146 "s" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN "}",
147 "flags", flags,
148 "lm_response",
149 (const char *)lm_response.data, lm_response.length,
150 "nt_response",
151 (const char *)nt_response.data, nt_response.length,
152 "lm_session_key",
153 (const char *)lm_session_key.data, lm_session_key.length,
154 "nt_session_key",
155 (const char *)nt_session_key.data, nt_session_key.length);
156 TALLOC_FREE(frame);
157 return ret;
160 static PyObject *py_creds_get_principal(PyObject *self, PyObject *unused)
162 TALLOC_CTX *frame = talloc_stackframe();
163 PyObject *ret = NULL;
164 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
165 if (creds == NULL) {
166 PyErr_Format(PyExc_TypeError, "Credentials expected");
167 return NULL;
169 ret = PyString_FromStringOrNULL(cli_credentials_get_principal(creds, frame));
170 TALLOC_FREE(frame);
171 return ret;
174 static PyObject *py_creds_set_principal(PyObject *self, PyObject *args)
176 char *newval;
177 enum credentials_obtained obt = CRED_SPECIFIED;
178 int _obt = obt;
179 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
180 if (creds == NULL) {
181 PyErr_Format(PyExc_TypeError, "Credentials expected");
182 return NULL;
185 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
186 return NULL;
188 obt = _obt;
190 return PyBool_FromLong(cli_credentials_set_principal(creds, newval, obt));
193 static PyObject *py_creds_get_password(PyObject *self, PyObject *unused)
195 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
196 if (creds == NULL) {
197 PyErr_Format(PyExc_TypeError, "Credentials expected");
198 return NULL;
200 return PyString_FromStringOrNULL(cli_credentials_get_password(creds));
203 static PyObject *py_creds_set_password(PyObject *self, PyObject *args)
205 const char *newval = NULL;
206 enum credentials_obtained obt = CRED_SPECIFIED;
207 int _obt = obt;
208 PyObject *result = NULL;
209 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
210 if (creds == NULL) {
211 PyErr_Format(PyExc_TypeError, "Credentials expected");
212 return NULL;
215 if (!PyArg_ParseTuple(args, PYARG_STR_UNI"|i", "utf8", &newval, &_obt)) {
216 return NULL;
218 obt = _obt;
220 result = PyBool_FromLong(cli_credentials_set_password(creds, newval, obt));
221 PyMem_Free(discard_const_p(void*, newval));
222 return result;
225 static PyObject *py_creds_set_utf16_password(PyObject *self, PyObject *args)
227 enum credentials_obtained obt = CRED_SPECIFIED;
228 int _obt = obt;
229 PyObject *newval = NULL;
230 DATA_BLOB blob = data_blob_null;
231 Py_ssize_t size = 0;
232 int result;
233 bool ok;
234 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
235 if (creds == NULL) {
236 PyErr_Format(PyExc_TypeError, "Credentials expected");
237 return NULL;
240 if (!PyArg_ParseTuple(args, "O|i", &newval, &_obt)) {
241 return NULL;
243 obt = _obt;
245 result = PyBytes_AsStringAndSize(newval, (char **)&blob.data, &size);
246 if (result != 0) {
247 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to Bytes");
248 return NULL;
250 blob.length = size;
252 ok = cli_credentials_set_utf16_password(creds,
253 &blob, obt);
255 return PyBool_FromLong(ok);
258 static PyObject *py_creds_get_old_password(PyObject *self, PyObject *unused)
260 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
261 if (creds == NULL) {
262 PyErr_Format(PyExc_TypeError, "Credentials expected");
263 return NULL;
265 return PyString_FromStringOrNULL(cli_credentials_get_old_password(creds));
268 static PyObject *py_creds_set_old_password(PyObject *self, PyObject *args)
270 char *oldval;
271 enum credentials_obtained obt = CRED_SPECIFIED;
272 int _obt = obt;
273 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
274 if (creds == NULL) {
275 PyErr_Format(PyExc_TypeError, "Credentials expected");
276 return NULL;
279 if (!PyArg_ParseTuple(args, "s|i", &oldval, &_obt)) {
280 return NULL;
282 obt = _obt;
284 return PyBool_FromLong(cli_credentials_set_old_password(creds, oldval, obt));
287 static PyObject *py_creds_set_old_utf16_password(PyObject *self, PyObject *args)
289 PyObject *oldval = NULL;
290 DATA_BLOB blob = data_blob_null;
291 Py_ssize_t size = 0;
292 int result;
293 bool ok;
294 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
295 if (creds == NULL) {
296 PyErr_Format(PyExc_TypeError, "Credentials expected");
297 return NULL;
300 if (!PyArg_ParseTuple(args, "O", &oldval)) {
301 return NULL;
304 result = PyBytes_AsStringAndSize(oldval, (char **)&blob.data, &size);
305 if (result != 0) {
306 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to Bytes");
307 return NULL;
309 blob.length = size;
311 ok = cli_credentials_set_old_utf16_password(creds,
312 &blob);
314 return PyBool_FromLong(ok);
317 static PyObject *py_creds_get_domain(PyObject *self, PyObject *unused)
319 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
320 if (creds == NULL) {
321 PyErr_Format(PyExc_TypeError, "Credentials expected");
322 return NULL;
324 return PyString_FromStringOrNULL(cli_credentials_get_domain(creds));
327 static PyObject *py_creds_set_domain(PyObject *self, PyObject *args)
329 char *newval;
330 enum credentials_obtained obt = CRED_SPECIFIED;
331 int _obt = obt;
332 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
333 if (creds == NULL) {
334 PyErr_Format(PyExc_TypeError, "Credentials expected");
335 return NULL;
338 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
339 return NULL;
341 obt = _obt;
343 return PyBool_FromLong(cli_credentials_set_domain(creds, newval, obt));
346 static PyObject *py_creds_get_realm(PyObject *self, PyObject *unused)
348 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
349 if (creds == NULL) {
350 PyErr_Format(PyExc_TypeError, "Credentials expected");
351 return NULL;
353 return PyString_FromStringOrNULL(cli_credentials_get_realm(creds));
356 static PyObject *py_creds_set_realm(PyObject *self, PyObject *args)
358 char *newval;
359 enum credentials_obtained obt = CRED_SPECIFIED;
360 int _obt = obt;
361 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
362 if (creds == NULL) {
363 PyErr_Format(PyExc_TypeError, "Credentials expected");
364 return NULL;
367 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
368 return NULL;
370 obt = _obt;
372 return PyBool_FromLong(cli_credentials_set_realm(creds, newval, obt));
375 static PyObject *py_creds_get_bind_dn(PyObject *self, PyObject *unused)
377 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
378 if (creds == NULL) {
379 PyErr_Format(PyExc_TypeError, "Credentials expected");
380 return NULL;
382 return PyString_FromStringOrNULL(cli_credentials_get_bind_dn(creds));
385 static PyObject *py_creds_set_bind_dn(PyObject *self, PyObject *args)
387 char *newval;
388 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
389 if (creds == NULL) {
390 PyErr_Format(PyExc_TypeError, "Credentials expected");
391 return NULL;
393 if (!PyArg_ParseTuple(args, "s", &newval))
394 return NULL;
396 return PyBool_FromLong(cli_credentials_set_bind_dn(creds, newval));
399 static PyObject *py_creds_get_workstation(PyObject *self, PyObject *unused)
401 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
402 if (creds == NULL) {
403 PyErr_Format(PyExc_TypeError, "Credentials expected");
404 return NULL;
406 return PyString_FromStringOrNULL(cli_credentials_get_workstation(creds));
409 static PyObject *py_creds_set_workstation(PyObject *self, PyObject *args)
411 char *newval;
412 enum credentials_obtained obt = CRED_SPECIFIED;
413 int _obt = obt;
414 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
415 if (creds == NULL) {
416 PyErr_Format(PyExc_TypeError, "Credentials expected");
417 return NULL;
420 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
421 return NULL;
423 obt = _obt;
425 return PyBool_FromLong(cli_credentials_set_workstation(creds, newval, obt));
428 static PyObject *py_creds_is_anonymous(PyObject *self, PyObject *unused)
430 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
431 if (creds == NULL) {
432 PyErr_Format(PyExc_TypeError, "Credentials expected");
433 return NULL;
435 return PyBool_FromLong(cli_credentials_is_anonymous(creds));
438 static PyObject *py_creds_set_anonymous(PyObject *self, PyObject *unused)
440 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
441 if (creds == NULL) {
442 PyErr_Format(PyExc_TypeError, "Credentials expected");
443 return NULL;
445 cli_credentials_set_anonymous(creds);
446 Py_RETURN_NONE;
449 static PyObject *py_creds_authentication_requested(PyObject *self, PyObject *unused)
451 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
452 if (creds == NULL) {
453 PyErr_Format(PyExc_TypeError, "Credentials expected");
454 return NULL;
456 return PyBool_FromLong(cli_credentials_authentication_requested(creds));
459 static PyObject *py_creds_wrong_password(PyObject *self, PyObject *unused)
461 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
462 if (creds == NULL) {
463 PyErr_Format(PyExc_TypeError, "Credentials expected");
464 return NULL;
466 return PyBool_FromLong(cli_credentials_wrong_password(creds));
469 static PyObject *py_creds_set_cmdline_callbacks(PyObject *self, PyObject *unused)
471 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
472 if (creds == NULL) {
473 PyErr_Format(PyExc_TypeError, "Credentials expected");
474 return NULL;
476 return PyBool_FromLong(cli_credentials_set_cmdline_callbacks(creds));
479 static PyObject *py_creds_parse_string(PyObject *self, PyObject *args)
481 char *newval;
482 enum credentials_obtained obt = CRED_SPECIFIED;
483 int _obt = obt;
484 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
485 if (creds == NULL) {
486 PyErr_Format(PyExc_TypeError, "Credentials expected");
487 return NULL;
490 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
491 return NULL;
493 obt = _obt;
495 cli_credentials_parse_string(creds, newval, obt);
496 Py_RETURN_NONE;
499 static PyObject *py_creds_parse_file(PyObject *self, PyObject *args)
501 char *newval;
502 enum credentials_obtained obt = CRED_SPECIFIED;
503 int _obt = obt;
504 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
505 if (creds == NULL) {
506 PyErr_Format(PyExc_TypeError, "Credentials expected");
507 return NULL;
510 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
511 return NULL;
513 obt = _obt;
515 cli_credentials_parse_file(creds, newval, obt);
516 Py_RETURN_NONE;
519 static PyObject *py_cli_credentials_set_password_will_be_nt_hash(PyObject *self, PyObject *args)
521 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
522 PyObject *py_val = NULL;
523 bool val = false;
525 if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &py_val)) {
526 return NULL;
528 val = PyObject_IsTrue(py_val);
530 cli_credentials_set_password_will_be_nt_hash(creds, val);
531 Py_RETURN_NONE;
534 static PyObject *py_creds_get_nt_hash(PyObject *self, PyObject *unused)
536 PyObject *ret;
537 struct samr_Password *ntpw = NULL;
538 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
539 if (creds == NULL) {
540 PyErr_Format(PyExc_TypeError, "Credentials expected");
541 return NULL;
543 ntpw = cli_credentials_get_nt_hash(creds, creds);
545 ret = PyBytes_FromStringAndSize(discard_const_p(char, ntpw->hash), 16);
546 TALLOC_FREE(ntpw);
547 return ret;
550 static PyObject *py_creds_get_kerberos_state(PyObject *self, PyObject *unused)
552 int state;
553 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
554 if (creds == NULL) {
555 PyErr_Format(PyExc_TypeError, "Credentials expected");
556 return NULL;
558 state = cli_credentials_get_kerberos_state(creds);
559 return PyInt_FromLong(state);
562 static PyObject *py_creds_set_kerberos_state(PyObject *self, PyObject *args)
564 int state;
565 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
566 if (creds == NULL) {
567 PyErr_Format(PyExc_TypeError, "Credentials expected");
568 return NULL;
570 if (!PyArg_ParseTuple(args, "i", &state))
571 return NULL;
573 cli_credentials_set_kerberos_state(creds, state);
574 Py_RETURN_NONE;
577 static PyObject *py_creds_set_krb_forwardable(PyObject *self, PyObject *args)
579 int state;
580 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
581 if (creds == NULL) {
582 PyErr_Format(PyExc_TypeError, "Credentials expected");
583 return NULL;
585 if (!PyArg_ParseTuple(args, "i", &state))
586 return NULL;
588 cli_credentials_set_krb_forwardable(creds, state);
589 Py_RETURN_NONE;
593 static PyObject *py_creds_get_forced_sasl_mech(PyObject *self, PyObject *unused)
595 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
596 if (creds == NULL) {
597 PyErr_Format(PyExc_TypeError, "Credentials expected");
598 return NULL;
600 return PyString_FromStringOrNULL(cli_credentials_get_forced_sasl_mech(creds));
603 static PyObject *py_creds_set_forced_sasl_mech(PyObject *self, PyObject *args)
605 char *newval;
606 enum credentials_obtained obt = CRED_SPECIFIED;
607 int _obt = obt;
608 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
609 if (creds == NULL) {
610 PyErr_Format(PyExc_TypeError, "Credentials expected");
611 return NULL;
614 if (!PyArg_ParseTuple(args, "s", &newval)) {
615 return NULL;
617 obt = _obt;
619 cli_credentials_set_forced_sasl_mech(creds, newval);
620 Py_RETURN_NONE;
623 static PyObject *py_creds_guess(PyObject *self, PyObject *args)
625 PyObject *py_lp_ctx = Py_None;
626 struct loadparm_context *lp_ctx;
627 TALLOC_CTX *mem_ctx;
628 struct cli_credentials *creds;
630 creds = PyCredentials_AsCliCredentials(self);
631 if (creds == NULL) {
632 PyErr_Format(PyExc_TypeError, "Credentials expected");
633 return NULL;
636 if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
637 return NULL;
639 mem_ctx = talloc_new(NULL);
640 if (mem_ctx == NULL) {
641 PyErr_NoMemory();
642 return NULL;
645 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
646 if (lp_ctx == NULL) {
647 talloc_free(mem_ctx);
648 return NULL;
651 cli_credentials_guess(creds, lp_ctx);
653 talloc_free(mem_ctx);
655 Py_RETURN_NONE;
658 static PyObject *py_creds_set_machine_account(PyObject *self, PyObject *args)
660 PyObject *py_lp_ctx = Py_None;
661 struct loadparm_context *lp_ctx;
662 NTSTATUS status;
663 struct cli_credentials *creds;
664 TALLOC_CTX *mem_ctx;
666 creds = PyCredentials_AsCliCredentials(self);
667 if (creds == NULL) {
668 PyErr_Format(PyExc_TypeError, "Credentials expected");
669 return NULL;
672 if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
673 return NULL;
675 mem_ctx = talloc_new(NULL);
676 if (mem_ctx == NULL) {
677 PyErr_NoMemory();
678 return NULL;
681 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
682 if (lp_ctx == NULL) {
683 talloc_free(mem_ctx);
684 return NULL;
687 status = cli_credentials_set_machine_account(creds, lp_ctx);
688 talloc_free(mem_ctx);
690 PyErr_NTSTATUS_IS_ERR_RAISE(status);
692 Py_RETURN_NONE;
695 static PyObject *PyCredentialCacheContainer_from_ccache_container(struct ccache_container *ccc)
697 return pytalloc_reference(&PyCredentialCacheContainer, ccc);
701 static PyObject *py_creds_get_named_ccache(PyObject *self, PyObject *args)
703 PyObject *py_lp_ctx = Py_None;
704 char *ccache_name = NULL;
705 struct loadparm_context *lp_ctx;
706 struct ccache_container *ccc;
707 struct tevent_context *event_ctx;
708 int ret;
709 const char *error_string;
710 struct cli_credentials *creds;
711 TALLOC_CTX *mem_ctx;
713 creds = PyCredentials_AsCliCredentials(self);
714 if (creds == NULL) {
715 PyErr_Format(PyExc_TypeError, "Credentials expected");
716 return NULL;
719 if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name))
720 return NULL;
722 mem_ctx = talloc_new(NULL);
723 if (mem_ctx == NULL) {
724 PyErr_NoMemory();
725 return NULL;
728 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
729 if (lp_ctx == NULL) {
730 talloc_free(mem_ctx);
731 return NULL;
734 event_ctx = samba_tevent_context_init(mem_ctx);
736 ret = cli_credentials_get_named_ccache(creds, event_ctx, lp_ctx,
737 ccache_name, &ccc, &error_string);
738 talloc_unlink(mem_ctx, lp_ctx);
739 if (ret == 0) {
740 talloc_steal(ccc, event_ctx);
741 talloc_free(mem_ctx);
742 return PyCredentialCacheContainer_from_ccache_container(ccc);
745 PyErr_SetString(PyExc_RuntimeError, error_string?error_string:"NULL");
747 talloc_free(mem_ctx);
748 return NULL;
751 static PyObject *py_creds_set_named_ccache(PyObject *self, PyObject *args)
753 struct loadparm_context *lp_ctx = NULL;
754 enum credentials_obtained obt = CRED_SPECIFIED;
755 const char *error_string = NULL;
756 TALLOC_CTX *mem_ctx = NULL;
757 char *newval = NULL;
758 PyObject *py_lp_ctx = Py_None;
759 int _obt = obt;
760 int ret;
761 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
762 if (creds == NULL) {
763 PyErr_Format(PyExc_TypeError, "Credentials expected");
764 return NULL;
767 if (!PyArg_ParseTuple(args, "s|iO", &newval, &_obt, &py_lp_ctx))
768 return NULL;
770 mem_ctx = talloc_new(NULL);
771 if (mem_ctx == NULL) {
772 PyErr_NoMemory();
773 return NULL;
776 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
777 if (lp_ctx == NULL) {
778 talloc_free(mem_ctx);
779 return NULL;
782 ret = cli_credentials_set_ccache(creds,
783 lp_ctx,
784 newval, CRED_SPECIFIED,
785 &error_string);
787 if (ret != 0) {
788 PyErr_SetString(PyExc_RuntimeError,
789 error_string != NULL ? error_string : "NULL");
790 talloc_free(mem_ctx);
791 return NULL;
794 talloc_free(mem_ctx);
795 Py_RETURN_NONE;
798 static PyObject *py_creds_set_gensec_features(PyObject *self, PyObject *args)
800 unsigned int gensec_features;
801 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
802 if (creds == NULL) {
803 PyErr_Format(PyExc_TypeError, "Credentials expected");
804 return NULL;
807 if (!PyArg_ParseTuple(args, "I", &gensec_features))
808 return NULL;
810 cli_credentials_set_gensec_features(creds, gensec_features);
812 Py_RETURN_NONE;
815 static PyObject *py_creds_get_gensec_features(PyObject *self, PyObject *args)
817 unsigned int gensec_features;
818 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
819 if (creds == NULL) {
820 PyErr_Format(PyExc_TypeError, "Credentials expected");
821 return NULL;
824 gensec_features = cli_credentials_get_gensec_features(creds);
825 return PyInt_FromLong(gensec_features);
828 static PyObject *py_creds_new_client_authenticator(PyObject *self,
829 PyObject *args)
831 struct netr_Authenticator auth;
832 struct cli_credentials *creds = NULL;
833 struct netlogon_creds_CredentialState *nc = NULL;
834 PyObject *ret = NULL;
836 creds = PyCredentials_AsCliCredentials(self);
837 if (creds == NULL) {
838 PyErr_SetString(PyExc_RuntimeError,
839 "Failed to get credentials from python");
840 return NULL;
843 nc = creds->netlogon_creds;
844 if (nc == NULL) {
845 PyErr_SetString(PyExc_ValueError,
846 "No netlogon credentials cannot make "
847 "client authenticator");
848 return NULL;
851 netlogon_creds_client_authenticator(
853 &auth);
854 ret = Py_BuildValue("{s"PYARG_BYTES_LEN"si}",
855 "credential",
856 (const char *) &auth.cred, sizeof(auth.cred),
857 "timestamp", auth.timestamp);
858 return ret;
861 static PyObject *py_creds_set_secure_channel_type(PyObject *self, PyObject *args)
863 unsigned int channel_type;
864 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
865 if (creds == NULL) {
866 PyErr_Format(PyExc_TypeError, "Credentials expected");
867 return NULL;
870 if (!PyArg_ParseTuple(args, "I", &channel_type))
871 return NULL;
873 cli_credentials_set_secure_channel_type(
874 creds,
875 channel_type);
877 Py_RETURN_NONE;
880 static PyObject *py_creds_get_secure_channel_type(PyObject *self, PyObject *args)
882 enum netr_SchannelType channel_type = SEC_CHAN_NULL;
883 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
884 if (creds == NULL) {
885 PyErr_Format(PyExc_TypeError, "Credentials expected");
886 return NULL;
889 channel_type = cli_credentials_get_secure_channel_type(creds);
891 return PyInt_FromLong(channel_type);
894 static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self,
895 PyObject *args)
897 DATA_BLOB data = data_blob_null;
898 struct cli_credentials *creds = NULL;
899 struct netr_CryptPassword *pwd = NULL;
900 NTSTATUS status;
901 PyObject *py_cp = Py_None;
903 creds = PyCredentials_AsCliCredentials(self);
904 if (creds == NULL) {
905 PyErr_Format(PyExc_TypeError, "Credentials expected");
906 return NULL;
909 if (!PyArg_ParseTuple(args, "O", &py_cp)) {
910 return NULL;
913 pwd = pytalloc_get_type(py_cp, struct netr_CryptPassword);
914 if (pwd == NULL) {
915 /* pytalloc_get_type sets TypeError */
916 return NULL;
918 data.length = sizeof(struct netr_CryptPassword);
919 data.data = (uint8_t *)pwd;
920 status = netlogon_creds_session_encrypt(creds->netlogon_creds, data);
922 PyErr_NTSTATUS_IS_ERR_RAISE(status);
924 Py_RETURN_NONE;
927 static PyMethodDef py_creds_methods[] = {
929 .ml_name = "get_username",
930 .ml_meth = py_creds_get_username,
931 .ml_flags = METH_NOARGS,
932 .ml_doc = "S.get_username() -> username\nObtain username.",
935 .ml_name = "set_username",
936 .ml_meth = py_creds_set_username,
937 .ml_flags = METH_VARARGS,
938 .ml_doc = "S.set_username(name[, credentials.SPECIFIED]) -> None\n"
939 "Change username.",
942 .ml_name = "get_principal",
943 .ml_meth = py_creds_get_principal,
944 .ml_flags = METH_NOARGS,
945 .ml_doc = "S.get_principal() -> user@realm\nObtain user principal.",
948 .ml_name = "set_principal",
949 .ml_meth = py_creds_set_principal,
950 .ml_flags = METH_VARARGS,
951 .ml_doc = "S.set_principal(name[, credentials.SPECIFIED]) -> None\n"
952 "Change principal.",
955 .ml_name = "get_password",
956 .ml_meth = py_creds_get_password,
957 .ml_flags = METH_NOARGS,
958 .ml_doc = "S.get_password() -> password\n"
959 "Obtain password.",
962 .ml_name = "get_ntlm_username_domain",
963 .ml_meth = py_creds_get_ntlm_username_domain,
964 .ml_flags = METH_NOARGS,
965 .ml_doc = "S.get_ntlm_username_domain() -> (domain, username)\n"
966 "Obtain NTLM username and domain, split up either as (DOMAIN, user) or (\"\", \"user@realm\").",
969 .ml_name = "get_ntlm_response",
970 .ml_meth = PY_DISCARD_FUNC_SIG(PyCFunction,
971 py_creds_get_ntlm_response),
972 .ml_flags = METH_VARARGS | METH_KEYWORDS,
973 .ml_doc = "S.get_ntlm_response"
974 "(flags, challenge[, target_info]) -> "
975 "(flags, lm_response, nt_response, lm_session_key, nt_session_key)\n"
976 "Obtain LM or NTLM response.",
979 .ml_name = "set_password",
980 .ml_meth = py_creds_set_password,
981 .ml_flags = METH_VARARGS,
982 .ml_doc = "S.set_password(password[, credentials.SPECIFIED]) -> None\n"
983 "Change password.",
986 .ml_name = "set_utf16_password",
987 .ml_meth = py_creds_set_utf16_password,
988 .ml_flags = METH_VARARGS,
989 .ml_doc = "S.set_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
990 "Change password.",
993 .ml_name = "get_old_password",
994 .ml_meth = py_creds_get_old_password,
995 .ml_flags = METH_NOARGS,
996 .ml_doc = "S.get_old_password() -> password\n"
997 "Obtain old password.",
1000 .ml_name = "set_old_password",
1001 .ml_meth = py_creds_set_old_password,
1002 .ml_flags = METH_VARARGS,
1003 .ml_doc = "S.set_old_password(password[, credentials.SPECIFIED]) -> None\n"
1004 "Change old password.",
1007 .ml_name = "set_old_utf16_password",
1008 .ml_meth = py_creds_set_old_utf16_password,
1009 .ml_flags = METH_VARARGS,
1010 .ml_doc = "S.set_old_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
1011 "Change old password.",
1014 .ml_name = "get_domain",
1015 .ml_meth = py_creds_get_domain,
1016 .ml_flags = METH_NOARGS,
1017 .ml_doc = "S.get_domain() -> domain\n"
1018 "Obtain domain name.",
1021 .ml_name = "set_domain",
1022 .ml_meth = py_creds_set_domain,
1023 .ml_flags = METH_VARARGS,
1024 .ml_doc = "S.set_domain(domain[, credentials.SPECIFIED]) -> None\n"
1025 "Change domain name.",
1028 .ml_name = "get_realm",
1029 .ml_meth = py_creds_get_realm,
1030 .ml_flags = METH_NOARGS,
1031 .ml_doc = "S.get_realm() -> realm\n"
1032 "Obtain realm name.",
1035 .ml_name = "set_realm",
1036 .ml_meth = py_creds_set_realm,
1037 .ml_flags = METH_VARARGS,
1038 .ml_doc = "S.set_realm(realm[, credentials.SPECIFIED]) -> None\n"
1039 "Change realm name.",
1042 .ml_name = "get_bind_dn",
1043 .ml_meth = py_creds_get_bind_dn,
1044 .ml_flags = METH_NOARGS,
1045 .ml_doc = "S.get_bind_dn() -> bind dn\n"
1046 "Obtain bind DN.",
1049 .ml_name = "set_bind_dn",
1050 .ml_meth = py_creds_set_bind_dn,
1051 .ml_flags = METH_VARARGS,
1052 .ml_doc = "S.set_bind_dn(bind_dn) -> None\n"
1053 "Change bind DN.",
1056 .ml_name = "is_anonymous",
1057 .ml_meth = py_creds_is_anonymous,
1058 .ml_flags = METH_NOARGS,
1061 .ml_name = "set_anonymous",
1062 .ml_meth = py_creds_set_anonymous,
1063 .ml_flags = METH_NOARGS,
1064 .ml_doc = "S.set_anonymous() -> None\n"
1065 "Use anonymous credentials.",
1068 .ml_name = "get_workstation",
1069 .ml_meth = py_creds_get_workstation,
1070 .ml_flags = METH_NOARGS,
1073 .ml_name = "set_workstation",
1074 .ml_meth = py_creds_set_workstation,
1075 .ml_flags = METH_VARARGS,
1078 .ml_name = "authentication_requested",
1079 .ml_meth = py_creds_authentication_requested,
1080 .ml_flags = METH_NOARGS,
1083 .ml_name = "wrong_password",
1084 .ml_meth = py_creds_wrong_password,
1085 .ml_flags = METH_NOARGS,
1086 .ml_doc = "S.wrong_password() -> bool\n"
1087 "Indicate the returned password was incorrect.",
1090 .ml_name = "set_cmdline_callbacks",
1091 .ml_meth = py_creds_set_cmdline_callbacks,
1092 .ml_flags = METH_NOARGS,
1093 .ml_doc = "S.set_cmdline_callbacks() -> bool\n"
1094 "Use command-line to obtain credentials not explicitly set.",
1097 .ml_name = "parse_string",
1098 .ml_meth = py_creds_parse_string,
1099 .ml_flags = METH_VARARGS,
1100 .ml_doc = "S.parse_string(text[, credentials.SPECIFIED]) -> None\n"
1101 "Parse credentials string.",
1104 .ml_name = "parse_file",
1105 .ml_meth = py_creds_parse_file,
1106 .ml_flags = METH_VARARGS,
1107 .ml_doc = "S.parse_file(filename[, credentials.SPECIFIED]) -> None\n"
1108 "Parse credentials file.",
1111 .ml_name = "set_password_will_be_nt_hash",
1112 .ml_meth = py_cli_credentials_set_password_will_be_nt_hash,
1113 .ml_flags = METH_VARARGS,
1114 .ml_doc = "S.set_password_will_be_nt_hash(bool) -> None\n"
1115 "Alters the behaviour of S.set_password() "
1116 "to expect the NTHASH as hexstring.",
1119 .ml_name = "get_nt_hash",
1120 .ml_meth = py_creds_get_nt_hash,
1121 .ml_flags = METH_NOARGS,
1124 .ml_name = "get_kerberos_state",
1125 .ml_meth = py_creds_get_kerberos_state,
1126 .ml_flags = METH_NOARGS,
1129 .ml_name = "set_kerberos_state",
1130 .ml_meth = py_creds_set_kerberos_state,
1131 .ml_flags = METH_VARARGS,
1134 .ml_name = "set_krb_forwardable",
1135 .ml_meth = py_creds_set_krb_forwardable,
1136 .ml_flags = METH_VARARGS,
1139 .ml_name = "guess",
1140 .ml_meth = py_creds_guess,
1141 .ml_flags = METH_VARARGS,
1144 .ml_name = "set_machine_account",
1145 .ml_meth = py_creds_set_machine_account,
1146 .ml_flags = METH_VARARGS,
1149 .ml_name = "get_named_ccache",
1150 .ml_meth = py_creds_get_named_ccache,
1151 .ml_flags = METH_VARARGS,
1154 .ml_name = "set_named_ccache",
1155 .ml_meth = py_creds_set_named_ccache,
1156 .ml_flags = METH_VARARGS,
1157 .ml_doc = "S.set_named_ccache(krb5_ccache_name, obtained, lp) -> None\n"
1158 "Set credentials to KRB5 Credentials Cache (by name).",
1161 .ml_name = "set_gensec_features",
1162 .ml_meth = py_creds_set_gensec_features,
1163 .ml_flags = METH_VARARGS,
1166 .ml_name = "get_gensec_features",
1167 .ml_meth = py_creds_get_gensec_features,
1168 .ml_flags = METH_NOARGS,
1171 .ml_name = "get_forced_sasl_mech",
1172 .ml_meth = py_creds_get_forced_sasl_mech,
1173 .ml_flags = METH_NOARGS,
1174 .ml_doc = "S.get_forced_sasl_mech() -> SASL mechanism\nObtain forced SASL mechanism.",
1177 .ml_name = "set_forced_sasl_mech",
1178 .ml_meth = py_creds_set_forced_sasl_mech,
1179 .ml_flags = METH_VARARGS,
1180 .ml_doc = "S.set_forced_sasl_mech(name) -> None\n"
1181 "Set forced SASL mechanism.",
1184 .ml_name = "new_client_authenticator",
1185 .ml_meth = py_creds_new_client_authenticator,
1186 .ml_flags = METH_NOARGS,
1187 .ml_doc = "S.new_client_authenticator() -> Authenticator\n"
1188 "Get a new client NETLOGON_AUTHENTICATOR"},
1190 .ml_name = "set_secure_channel_type",
1191 .ml_meth = py_creds_set_secure_channel_type,
1192 .ml_flags = METH_VARARGS,
1195 .ml_name = "get_secure_channel_type",
1196 .ml_meth = py_creds_get_secure_channel_type,
1197 .ml_flags = METH_VARARGS,
1200 .ml_name = "encrypt_netr_crypt_password",
1201 .ml_meth = py_creds_encrypt_netr_crypt_password,
1202 .ml_flags = METH_VARARGS,
1203 .ml_doc = "S.encrypt_netr_crypt_password(password) -> NTSTATUS\n"
1204 "Encrypt the supplied password using the session key and\n"
1205 "the negotiated encryption algorithm in place\n"
1206 "i.e. it overwrites the original data"},
1207 { .ml_name = NULL }
1210 static struct PyModuleDef moduledef = {
1211 PyModuleDef_HEAD_INIT,
1212 .m_name = "credentials",
1213 .m_doc = "Credentials management.",
1214 .m_size = -1,
1215 .m_methods = py_creds_methods,
1218 PyTypeObject PyCredentials = {
1219 .tp_name = "credentials.Credentials",
1220 .tp_new = py_creds_new,
1221 .tp_flags = Py_TPFLAGS_DEFAULT,
1222 .tp_methods = py_creds_methods,
1225 static PyObject *py_ccache_name(PyObject *self, PyObject *unused)
1227 struct ccache_container *ccc = NULL;
1228 char *name = NULL;
1229 PyObject *py_name = NULL;
1230 int ret;
1232 ccc = pytalloc_get_type(self, struct ccache_container);
1234 ret = krb5_cc_get_full_name(ccc->smb_krb5_context->krb5_context,
1235 ccc->ccache, &name);
1236 if (ret == 0) {
1237 py_name = PyString_FromStringOrNULL(name);
1238 SAFE_FREE(name);
1239 } else {
1240 PyErr_SetString(PyExc_RuntimeError,
1241 "Failed to get ccache name");
1242 return NULL;
1244 return py_name;
1247 static PyMethodDef py_ccache_container_methods[] = {
1248 { "get_name", py_ccache_name, METH_NOARGS,
1249 "S.get_name() -> name\nObtain KRB5 credentials cache name." },
1250 { NULL }
1253 PyTypeObject PyCredentialCacheContainer = {
1254 .tp_name = "credentials.CredentialCacheContainer",
1255 .tp_flags = Py_TPFLAGS_DEFAULT,
1256 .tp_methods = py_ccache_container_methods,
1259 MODULE_INIT_FUNC(credentials)
1261 PyObject *m;
1262 if (pytalloc_BaseObject_PyType_Ready(&PyCredentials) < 0)
1263 return NULL;
1265 if (pytalloc_BaseObject_PyType_Ready(&PyCredentialCacheContainer) < 0)
1266 return NULL;
1268 m = PyModule_Create(&moduledef);
1269 if (m == NULL)
1270 return NULL;
1272 PyModule_AddObject(m, "UNINITIALISED", PyInt_FromLong(CRED_UNINITIALISED));
1273 PyModule_AddObject(m, "CALLBACK", PyInt_FromLong(CRED_CALLBACK));
1274 PyModule_AddObject(m, "GUESS_ENV", PyInt_FromLong(CRED_GUESS_ENV));
1275 PyModule_AddObject(m, "GUESS_FILE", PyInt_FromLong(CRED_GUESS_FILE));
1276 PyModule_AddObject(m, "CALLBACK_RESULT", PyInt_FromLong(CRED_CALLBACK_RESULT));
1277 PyModule_AddObject(m, "SPECIFIED", PyInt_FromLong(CRED_SPECIFIED));
1279 PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyInt_FromLong(CRED_AUTO_USE_KERBEROS));
1280 PyModule_AddObject(m, "DONT_USE_KERBEROS", PyInt_FromLong(CRED_DONT_USE_KERBEROS));
1281 PyModule_AddObject(m, "MUST_USE_KERBEROS", PyInt_FromLong(CRED_MUST_USE_KERBEROS));
1283 PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE", PyInt_FromLong(CRED_AUTO_KRB_FORWARDABLE));
1284 PyModule_AddObject(m, "NO_KRB_FORWARDABLE", PyInt_FromLong(CRED_NO_KRB_FORWARDABLE));
1285 PyModule_AddObject(m, "FORCE_KRB_FORWARDABLE", PyInt_FromLong(CRED_FORCE_KRB_FORWARDABLE));
1286 PyModule_AddObject(m, "CLI_CRED_NTLM2", PyInt_FromLong(CLI_CRED_NTLM2));
1287 PyModule_AddObject(m, "CLI_CRED_NTLMv2_AUTH", PyInt_FromLong(CLI_CRED_NTLMv2_AUTH));
1288 PyModule_AddObject(m, "CLI_CRED_LANMAN_AUTH", PyInt_FromLong(CLI_CRED_LANMAN_AUTH));
1289 PyModule_AddObject(m, "CLI_CRED_NTLM_AUTH", PyInt_FromLong(CLI_CRED_NTLM_AUTH));
1290 PyModule_AddObject(m, "CLI_CRED_CLEAR_AUTH", PyInt_FromLong(CLI_CRED_CLEAR_AUTH));
1292 Py_INCREF(&PyCredentials);
1293 PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
1294 Py_INCREF(&PyCredentialCacheContainer);
1295 PyModule_AddObject(m, "CredentialCacheContainer", (PyObject *)&PyCredentialCacheContainer);
1296 return m;