auth:creds: Add python bindings for (get|set)_smb_signing
[Samba.git] / auth / credentials / pycredentials.c
blob846c418419fcc9155be47f4fbe1a26772e399838
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"
37 #include "libcli/smb/smb_constants.h"
39 void initcredentials(void);
41 static PyObject *py_creds_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
43 return pytalloc_steal(type, cli_credentials_init(NULL));
46 static PyObject *py_creds_get_username(PyObject *self, PyObject *unused)
48 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
49 if (creds == NULL) {
50 PyErr_Format(PyExc_TypeError, "Credentials expected");
51 return NULL;
53 return PyString_FromStringOrNULL(cli_credentials_get_username(creds));
56 static PyObject *py_creds_set_username(PyObject *self, PyObject *args)
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;
67 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
68 return NULL;
70 obt = _obt;
72 return PyBool_FromLong(cli_credentials_set_username(creds, newval, obt));
75 static PyObject *py_creds_get_ntlm_username_domain(PyObject *self, PyObject *unused)
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;
86 cli_credentials_get_ntlm_username_domain(creds,
87 frame, &user, &domain);
88 ret = Py_BuildValue("(ss)",
89 user,
90 domain);
92 TALLOC_FREE(frame);
93 return ret;
96 static PyObject *py_creds_get_ntlm_response(PyObject *self, PyObject *args, PyObject *kwargs)
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;
119 tv_now = timeval_current();
120 server_timestamp = timeval_to_nttime(&tv_now);
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;
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);
140 if (!NT_STATUS_IS_OK(status)) {
141 PyErr_SetNTSTATUS(status);
142 TALLOC_FREE(frame);
143 return NULL;
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;
161 static PyObject *py_creds_get_principal(PyObject *self, PyObject *unused)
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;
170 ret = PyString_FromStringOrNULL(cli_credentials_get_principal(creds, frame));
171 TALLOC_FREE(frame);
172 return ret;
175 static PyObject *py_creds_set_principal(PyObject *self, PyObject *args)
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;
186 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
187 return NULL;
189 obt = _obt;
191 return PyBool_FromLong(cli_credentials_set_principal(creds, newval, obt));
194 static PyObject *py_creds_get_password(PyObject *self, PyObject *unused)
196 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
197 if (creds == NULL) {
198 PyErr_Format(PyExc_TypeError, "Credentials expected");
199 return NULL;
201 return PyString_FromStringOrNULL(cli_credentials_get_password(creds));
204 static PyObject *py_creds_set_password(PyObject *self, PyObject *args)
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;
216 if (!PyArg_ParseTuple(args, PYARG_STR_UNI"|i", "utf8", &newval, &_obt)) {
217 return NULL;
219 obt = _obt;
221 result = PyBool_FromLong(cli_credentials_set_password(creds, newval, obt));
222 PyMem_Free(discard_const_p(void*, newval));
223 return result;
226 static PyObject *py_creds_set_utf16_password(PyObject *self, PyObject *args)
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;
241 if (!PyArg_ParseTuple(args, "O|i", &newval, &_obt)) {
242 return NULL;
244 obt = _obt;
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;
251 blob.length = size;
253 ok = cli_credentials_set_utf16_password(creds,
254 &blob, obt);
256 return PyBool_FromLong(ok);
259 static PyObject *py_creds_get_old_password(PyObject *self, PyObject *unused)
261 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
262 if (creds == NULL) {
263 PyErr_Format(PyExc_TypeError, "Credentials expected");
264 return NULL;
266 return PyString_FromStringOrNULL(cli_credentials_get_old_password(creds));
269 static PyObject *py_creds_set_old_password(PyObject *self, PyObject *args)
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;
280 if (!PyArg_ParseTuple(args, "s|i", &oldval, &_obt)) {
281 return NULL;
283 obt = _obt;
285 return PyBool_FromLong(cli_credentials_set_old_password(creds, oldval, obt));
288 static PyObject *py_creds_set_old_utf16_password(PyObject *self, PyObject *args)
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;
301 if (!PyArg_ParseTuple(args, "O", &oldval)) {
302 return NULL;
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;
310 blob.length = size;
312 ok = cli_credentials_set_old_utf16_password(creds,
313 &blob);
315 return PyBool_FromLong(ok);
318 static PyObject *py_creds_get_domain(PyObject *self, PyObject *unused)
320 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
321 if (creds == NULL) {
322 PyErr_Format(PyExc_TypeError, "Credentials expected");
323 return NULL;
325 return PyString_FromStringOrNULL(cli_credentials_get_domain(creds));
328 static PyObject *py_creds_set_domain(PyObject *self, PyObject *args)
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;
339 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
340 return NULL;
342 obt = _obt;
344 return PyBool_FromLong(cli_credentials_set_domain(creds, newval, obt));
347 static PyObject *py_creds_get_realm(PyObject *self, PyObject *unused)
349 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
350 if (creds == NULL) {
351 PyErr_Format(PyExc_TypeError, "Credentials expected");
352 return NULL;
354 return PyString_FromStringOrNULL(cli_credentials_get_realm(creds));
357 static PyObject *py_creds_set_realm(PyObject *self, PyObject *args)
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;
368 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
369 return NULL;
371 obt = _obt;
373 return PyBool_FromLong(cli_credentials_set_realm(creds, newval, obt));
376 static PyObject *py_creds_get_bind_dn(PyObject *self, PyObject *unused)
378 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
379 if (creds == NULL) {
380 PyErr_Format(PyExc_TypeError, "Credentials expected");
381 return NULL;
383 return PyString_FromStringOrNULL(cli_credentials_get_bind_dn(creds));
386 static PyObject *py_creds_set_bind_dn(PyObject *self, PyObject *args)
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;
394 if (!PyArg_ParseTuple(args, "s", &newval))
395 return NULL;
397 return PyBool_FromLong(cli_credentials_set_bind_dn(creds, newval));
400 static PyObject *py_creds_get_workstation(PyObject *self, PyObject *unused)
402 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
403 if (creds == NULL) {
404 PyErr_Format(PyExc_TypeError, "Credentials expected");
405 return NULL;
407 return PyString_FromStringOrNULL(cli_credentials_get_workstation(creds));
410 static PyObject *py_creds_set_workstation(PyObject *self, PyObject *args)
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;
421 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
422 return NULL;
424 obt = _obt;
426 return PyBool_FromLong(cli_credentials_set_workstation(creds, newval, obt));
429 static PyObject *py_creds_is_anonymous(PyObject *self, PyObject *unused)
431 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
432 if (creds == NULL) {
433 PyErr_Format(PyExc_TypeError, "Credentials expected");
434 return NULL;
436 return PyBool_FromLong(cli_credentials_is_anonymous(creds));
439 static PyObject *py_creds_set_anonymous(PyObject *self, PyObject *unused)
441 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
442 if (creds == NULL) {
443 PyErr_Format(PyExc_TypeError, "Credentials expected");
444 return NULL;
446 cli_credentials_set_anonymous(creds);
447 Py_RETURN_NONE;
450 static PyObject *py_creds_authentication_requested(PyObject *self, PyObject *unused)
452 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
453 if (creds == NULL) {
454 PyErr_Format(PyExc_TypeError, "Credentials expected");
455 return NULL;
457 return PyBool_FromLong(cli_credentials_authentication_requested(creds));
460 static PyObject *py_creds_wrong_password(PyObject *self, PyObject *unused)
462 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
463 if (creds == NULL) {
464 PyErr_Format(PyExc_TypeError, "Credentials expected");
465 return NULL;
467 return PyBool_FromLong(cli_credentials_wrong_password(creds));
470 static PyObject *py_creds_set_cmdline_callbacks(PyObject *self, PyObject *unused)
472 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
473 if (creds == NULL) {
474 PyErr_Format(PyExc_TypeError, "Credentials expected");
475 return NULL;
477 return PyBool_FromLong(cli_credentials_set_cmdline_callbacks(creds));
480 static PyObject *py_creds_parse_string(PyObject *self, PyObject *args)
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;
491 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
492 return NULL;
494 obt = _obt;
496 cli_credentials_parse_string(creds, newval, obt);
497 Py_RETURN_NONE;
500 static PyObject *py_creds_parse_file(PyObject *self, PyObject *args)
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;
511 if (!PyArg_ParseTuple(args, "s|i", &newval, &_obt)) {
512 return NULL;
514 obt = _obt;
516 cli_credentials_parse_file(creds, newval, obt);
517 Py_RETURN_NONE;
520 static PyObject *py_cli_credentials_set_password_will_be_nt_hash(PyObject *self, PyObject *args)
522 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
523 PyObject *py_val = NULL;
524 bool val = false;
526 if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &py_val)) {
527 return NULL;
529 val = PyObject_IsTrue(py_val);
531 cli_credentials_set_password_will_be_nt_hash(creds, val);
532 Py_RETURN_NONE;
535 static PyObject *py_creds_get_nt_hash(PyObject *self, PyObject *unused)
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;
544 ntpw = cli_credentials_get_nt_hash(creds, creds);
546 ret = PyBytes_FromStringAndSize(discard_const_p(char, ntpw->hash), 16);
547 TALLOC_FREE(ntpw);
548 return ret;
551 static PyObject *py_creds_get_kerberos_state(PyObject *self, PyObject *unused)
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;
559 state = cli_credentials_get_kerberos_state(creds);
560 return PyLong_FromLong(state);
563 static PyObject *py_creds_set_kerberos_state(PyObject *self, PyObject *args)
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;
571 if (!PyArg_ParseTuple(args, "i", &state))
572 return NULL;
574 cli_credentials_set_kerberos_state(creds, state);
575 Py_RETURN_NONE;
578 static PyObject *py_creds_set_krb_forwardable(PyObject *self, PyObject *args)
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;
586 if (!PyArg_ParseTuple(args, "i", &state))
587 return NULL;
589 cli_credentials_set_krb_forwardable(creds, state);
590 Py_RETURN_NONE;
594 static PyObject *py_creds_get_forced_sasl_mech(PyObject *self, PyObject *unused)
596 struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
597 if (creds == NULL) {
598 PyErr_Format(PyExc_TypeError, "Credentials expected");
599 return NULL;
601 return PyString_FromStringOrNULL(cli_credentials_get_forced_sasl_mech(creds));
604 static PyObject *py_creds_set_forced_sasl_mech(PyObject *self, PyObject *args)
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;
615 if (!PyArg_ParseTuple(args, "s", &newval)) {
616 return NULL;
618 obt = _obt;
620 cli_credentials_set_forced_sasl_mech(creds, newval);
621 Py_RETURN_NONE;
624 static PyObject *py_creds_guess(PyObject *self, PyObject *args)
626 PyObject *py_lp_ctx = Py_None;
627 struct loadparm_context *lp_ctx;
628 TALLOC_CTX *mem_ctx;
629 struct cli_credentials *creds;
631 creds = PyCredentials_AsCliCredentials(self);
632 if (creds == NULL) {
633 PyErr_Format(PyExc_TypeError, "Credentials expected");
634 return NULL;
637 if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
638 return NULL;
640 mem_ctx = talloc_new(NULL);
641 if (mem_ctx == NULL) {
642 PyErr_NoMemory();
643 return NULL;
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;
652 cli_credentials_guess(creds, lp_ctx);
654 talloc_free(mem_ctx);
656 Py_RETURN_NONE;
659 static PyObject *py_creds_set_machine_account(PyObject *self, PyObject *args)
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;
667 creds = PyCredentials_AsCliCredentials(self);
668 if (creds == NULL) {
669 PyErr_Format(PyExc_TypeError, "Credentials expected");
670 return NULL;
673 if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
674 return NULL;
676 mem_ctx = talloc_new(NULL);
677 if (mem_ctx == NULL) {
678 PyErr_NoMemory();
679 return NULL;
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;
688 status = cli_credentials_set_machine_account(creds, lp_ctx);
689 talloc_free(mem_ctx);
691 PyErr_NTSTATUS_IS_ERR_RAISE(status);
693 Py_RETURN_NONE;
696 static PyObject *PyCredentialCacheContainer_from_ccache_container(struct ccache_container *ccc)
698 return pytalloc_reference(&PyCredentialCacheContainer, ccc);
702 static PyObject *py_creds_get_named_ccache(PyObject *self, PyObject *args)
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;
714 creds = PyCredentials_AsCliCredentials(self);
715 if (creds == NULL) {
716 PyErr_Format(PyExc_TypeError, "Credentials expected");
717 return NULL;
720 if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name))
721 return NULL;
723 mem_ctx = talloc_new(NULL);
724 if (mem_ctx == NULL) {
725 PyErr_NoMemory();
726 return NULL;
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;
735 event_ctx = samba_tevent_context_init(mem_ctx);
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);
746 PyErr_SetString(PyExc_RuntimeError, error_string?error_string:"NULL");
748 talloc_free(mem_ctx);
749 return NULL;
752 static PyObject *py_creds_set_named_ccache(PyObject *self, PyObject *args)
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;
768 if (!PyArg_ParseTuple(args, "s|iO", &newval, &_obt, &py_lp_ctx))
769 return NULL;
771 mem_ctx = talloc_new(NULL);
772 if (mem_ctx == NULL) {
773 PyErr_NoMemory();
774 return NULL;
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;
783 ret = cli_credentials_set_ccache(creds,
784 lp_ctx,
785 newval, CRED_SPECIFIED,
786 &error_string);
788 if (ret != 0) {
789 PyErr_SetString(PyExc_RuntimeError,
790 error_string != NULL ? error_string : "NULL");
791 talloc_free(mem_ctx);
792 return NULL;
795 talloc_free(mem_ctx);
796 Py_RETURN_NONE;
799 static PyObject *py_creds_set_gensec_features(PyObject *self, PyObject *args)
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;
808 if (!PyArg_ParseTuple(args, "I", &gensec_features))
809 return NULL;
811 cli_credentials_set_gensec_features(creds, gensec_features);
813 Py_RETURN_NONE;
816 static PyObject *py_creds_get_gensec_features(PyObject *self, PyObject *args)
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;
825 gensec_features = cli_credentials_get_gensec_features(creds);
826 return PyLong_FromLong(gensec_features);
829 static PyObject *py_creds_new_client_authenticator(PyObject *self,
830 PyObject *args)
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;
838 creds = PyCredentials_AsCliCredentials(self);
839 if (creds == NULL) {
840 PyErr_SetString(PyExc_RuntimeError,
841 "Failed to get credentials from python");
842 return NULL;
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;
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;
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;
867 static PyObject *py_creds_set_secure_channel_type(PyObject *self, PyObject *args)
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;
876 if (!PyArg_ParseTuple(args, "I", &channel_type))
877 return NULL;
879 cli_credentials_set_secure_channel_type(
880 creds,
881 channel_type);
883 Py_RETURN_NONE;
886 static PyObject *py_creds_get_secure_channel_type(PyObject *self, PyObject *args)
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;
895 channel_type = cli_credentials_get_secure_channel_type(creds);
897 return PyLong_FromLong(channel_type);
900 static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self,
901 PyObject *args)
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;
909 creds = PyCredentials_AsCliCredentials(self);
910 if (creds == NULL) {
911 PyErr_Format(PyExc_TypeError, "Credentials expected");
912 return NULL;
915 if (!PyArg_ParseTuple(args, "O", &py_cp)) {
916 return NULL;
919 pwd = pytalloc_get_type(py_cp, struct netr_CryptPassword);
920 if (pwd == NULL) {
921 /* pytalloc_get_type sets TypeError */
922 return NULL;
924 data.length = sizeof(struct netr_CryptPassword);
925 data.data = (uint8_t *)pwd;
926 status = netlogon_creds_session_encrypt(creds->netlogon_creds, data);
928 PyErr_NTSTATUS_IS_ERR_RAISE(status);
930 Py_RETURN_NONE;
933 static PyObject *py_creds_get_smb_signing(PyObject *self, PyObject *unused)
935 enum smb_signing_setting signing_state;
936 struct cli_credentials *creds = NULL;
938 creds = PyCredentials_AsCliCredentials(self);
939 if (creds == NULL) {
940 PyErr_Format(PyExc_TypeError, "Credentials expected");
941 return NULL;
944 signing_state = cli_credentials_get_smb_signing(creds);
945 return PyLong_FromLong(signing_state);
948 static PyObject *py_creds_set_smb_signing(PyObject *self, PyObject *args)
950 enum smb_signing_setting signing_state;
951 struct cli_credentials *creds = NULL;
952 enum credentials_obtained obt = CRED_SPECIFIED;
954 creds = PyCredentials_AsCliCredentials(self);
955 if (creds == NULL) {
956 PyErr_Format(PyExc_TypeError, "Credentials expected");
957 return NULL;
959 if (!PyArg_ParseTuple(args, "i|i", &signing_state, &obt)) {
960 return NULL;
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;
975 cli_credentials_set_smb_signing(creds, signing_state, obt);
976 Py_RETURN_NONE;
979 static PyMethodDef py_creds_methods[] = {
981 .ml_name = "get_username",
982 .ml_meth = py_creds_get_username,
983 .ml_flags = METH_NOARGS,
984 .ml_doc = "S.get_username() -> username\nObtain username.",
987 .ml_name = "set_username",
988 .ml_meth = py_creds_set_username,
989 .ml_flags = METH_VARARGS,
990 .ml_doc = "S.set_username(name[, credentials.SPECIFIED]) -> None\n"
991 "Change username.",
994 .ml_name = "get_principal",
995 .ml_meth = py_creds_get_principal,
996 .ml_flags = METH_NOARGS,
997 .ml_doc = "S.get_principal() -> user@realm\nObtain user principal.",
1000 .ml_name = "set_principal",
1001 .ml_meth = py_creds_set_principal,
1002 .ml_flags = METH_VARARGS,
1003 .ml_doc = "S.set_principal(name[, credentials.SPECIFIED]) -> None\n"
1004 "Change principal.",
1007 .ml_name = "get_password",
1008 .ml_meth = py_creds_get_password,
1009 .ml_flags = METH_NOARGS,
1010 .ml_doc = "S.get_password() -> password\n"
1011 "Obtain password.",
1014 .ml_name = "get_ntlm_username_domain",
1015 .ml_meth = py_creds_get_ntlm_username_domain,
1016 .ml_flags = METH_NOARGS,
1017 .ml_doc = "S.get_ntlm_username_domain() -> (domain, username)\n"
1018 "Obtain NTLM username and domain, split up either as (DOMAIN, user) or (\"\", \"user@realm\").",
1021 .ml_name = "get_ntlm_response",
1022 .ml_meth = PY_DISCARD_FUNC_SIG(PyCFunction,
1023 py_creds_get_ntlm_response),
1024 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1025 .ml_doc = "S.get_ntlm_response"
1026 "(flags, challenge[, target_info]) -> "
1027 "(flags, lm_response, nt_response, lm_session_key, nt_session_key)\n"
1028 "Obtain LM or NTLM response.",
1031 .ml_name = "set_password",
1032 .ml_meth = py_creds_set_password,
1033 .ml_flags = METH_VARARGS,
1034 .ml_doc = "S.set_password(password[, credentials.SPECIFIED]) -> None\n"
1035 "Change password.",
1038 .ml_name = "set_utf16_password",
1039 .ml_meth = py_creds_set_utf16_password,
1040 .ml_flags = METH_VARARGS,
1041 .ml_doc = "S.set_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
1042 "Change password.",
1045 .ml_name = "get_old_password",
1046 .ml_meth = py_creds_get_old_password,
1047 .ml_flags = METH_NOARGS,
1048 .ml_doc = "S.get_old_password() -> password\n"
1049 "Obtain old password.",
1052 .ml_name = "set_old_password",
1053 .ml_meth = py_creds_set_old_password,
1054 .ml_flags = METH_VARARGS,
1055 .ml_doc = "S.set_old_password(password[, credentials.SPECIFIED]) -> None\n"
1056 "Change old password.",
1059 .ml_name = "set_old_utf16_password",
1060 .ml_meth = py_creds_set_old_utf16_password,
1061 .ml_flags = METH_VARARGS,
1062 .ml_doc = "S.set_old_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
1063 "Change old password.",
1066 .ml_name = "get_domain",
1067 .ml_meth = py_creds_get_domain,
1068 .ml_flags = METH_NOARGS,
1069 .ml_doc = "S.get_domain() -> domain\n"
1070 "Obtain domain name.",
1073 .ml_name = "set_domain",
1074 .ml_meth = py_creds_set_domain,
1075 .ml_flags = METH_VARARGS,
1076 .ml_doc = "S.set_domain(domain[, credentials.SPECIFIED]) -> None\n"
1077 "Change domain name.",
1080 .ml_name = "get_realm",
1081 .ml_meth = py_creds_get_realm,
1082 .ml_flags = METH_NOARGS,
1083 .ml_doc = "S.get_realm() -> realm\n"
1084 "Obtain realm name.",
1087 .ml_name = "set_realm",
1088 .ml_meth = py_creds_set_realm,
1089 .ml_flags = METH_VARARGS,
1090 .ml_doc = "S.set_realm(realm[, credentials.SPECIFIED]) -> None\n"
1091 "Change realm name.",
1094 .ml_name = "get_bind_dn",
1095 .ml_meth = py_creds_get_bind_dn,
1096 .ml_flags = METH_NOARGS,
1097 .ml_doc = "S.get_bind_dn() -> bind dn\n"
1098 "Obtain bind DN.",
1101 .ml_name = "set_bind_dn",
1102 .ml_meth = py_creds_set_bind_dn,
1103 .ml_flags = METH_VARARGS,
1104 .ml_doc = "S.set_bind_dn(bind_dn) -> None\n"
1105 "Change bind DN.",
1108 .ml_name = "is_anonymous",
1109 .ml_meth = py_creds_is_anonymous,
1110 .ml_flags = METH_NOARGS,
1113 .ml_name = "set_anonymous",
1114 .ml_meth = py_creds_set_anonymous,
1115 .ml_flags = METH_NOARGS,
1116 .ml_doc = "S.set_anonymous() -> None\n"
1117 "Use anonymous credentials.",
1120 .ml_name = "get_workstation",
1121 .ml_meth = py_creds_get_workstation,
1122 .ml_flags = METH_NOARGS,
1125 .ml_name = "set_workstation",
1126 .ml_meth = py_creds_set_workstation,
1127 .ml_flags = METH_VARARGS,
1130 .ml_name = "authentication_requested",
1131 .ml_meth = py_creds_authentication_requested,
1132 .ml_flags = METH_NOARGS,
1135 .ml_name = "wrong_password",
1136 .ml_meth = py_creds_wrong_password,
1137 .ml_flags = METH_NOARGS,
1138 .ml_doc = "S.wrong_password() -> bool\n"
1139 "Indicate the returned password was incorrect.",
1142 .ml_name = "set_cmdline_callbacks",
1143 .ml_meth = py_creds_set_cmdline_callbacks,
1144 .ml_flags = METH_NOARGS,
1145 .ml_doc = "S.set_cmdline_callbacks() -> bool\n"
1146 "Use command-line to obtain credentials not explicitly set.",
1149 .ml_name = "parse_string",
1150 .ml_meth = py_creds_parse_string,
1151 .ml_flags = METH_VARARGS,
1152 .ml_doc = "S.parse_string(text[, credentials.SPECIFIED]) -> None\n"
1153 "Parse credentials string.",
1156 .ml_name = "parse_file",
1157 .ml_meth = py_creds_parse_file,
1158 .ml_flags = METH_VARARGS,
1159 .ml_doc = "S.parse_file(filename[, credentials.SPECIFIED]) -> None\n"
1160 "Parse credentials file.",
1163 .ml_name = "set_password_will_be_nt_hash",
1164 .ml_meth = py_cli_credentials_set_password_will_be_nt_hash,
1165 .ml_flags = METH_VARARGS,
1166 .ml_doc = "S.set_password_will_be_nt_hash(bool) -> None\n"
1167 "Alters the behaviour of S.set_password() "
1168 "to expect the NTHASH as hexstring.",
1171 .ml_name = "get_nt_hash",
1172 .ml_meth = py_creds_get_nt_hash,
1173 .ml_flags = METH_NOARGS,
1176 .ml_name = "get_kerberos_state",
1177 .ml_meth = py_creds_get_kerberos_state,
1178 .ml_flags = METH_NOARGS,
1181 .ml_name = "set_kerberos_state",
1182 .ml_meth = py_creds_set_kerberos_state,
1183 .ml_flags = METH_VARARGS,
1186 .ml_name = "set_krb_forwardable",
1187 .ml_meth = py_creds_set_krb_forwardable,
1188 .ml_flags = METH_VARARGS,
1191 .ml_name = "guess",
1192 .ml_meth = py_creds_guess,
1193 .ml_flags = METH_VARARGS,
1196 .ml_name = "set_machine_account",
1197 .ml_meth = py_creds_set_machine_account,
1198 .ml_flags = METH_VARARGS,
1201 .ml_name = "get_named_ccache",
1202 .ml_meth = py_creds_get_named_ccache,
1203 .ml_flags = METH_VARARGS,
1206 .ml_name = "set_named_ccache",
1207 .ml_meth = py_creds_set_named_ccache,
1208 .ml_flags = METH_VARARGS,
1209 .ml_doc = "S.set_named_ccache(krb5_ccache_name, obtained, lp) -> None\n"
1210 "Set credentials to KRB5 Credentials Cache (by name).",
1213 .ml_name = "set_gensec_features",
1214 .ml_meth = py_creds_set_gensec_features,
1215 .ml_flags = METH_VARARGS,
1218 .ml_name = "get_gensec_features",
1219 .ml_meth = py_creds_get_gensec_features,
1220 .ml_flags = METH_NOARGS,
1223 .ml_name = "get_forced_sasl_mech",
1224 .ml_meth = py_creds_get_forced_sasl_mech,
1225 .ml_flags = METH_NOARGS,
1226 .ml_doc = "S.get_forced_sasl_mech() -> SASL mechanism\nObtain forced SASL mechanism.",
1229 .ml_name = "set_forced_sasl_mech",
1230 .ml_meth = py_creds_set_forced_sasl_mech,
1231 .ml_flags = METH_VARARGS,
1232 .ml_doc = "S.set_forced_sasl_mech(name) -> None\n"
1233 "Set forced SASL mechanism.",
1236 .ml_name = "new_client_authenticator",
1237 .ml_meth = py_creds_new_client_authenticator,
1238 .ml_flags = METH_NOARGS,
1239 .ml_doc = "S.new_client_authenticator() -> Authenticator\n"
1240 "Get a new client NETLOGON_AUTHENTICATOR"},
1242 .ml_name = "set_secure_channel_type",
1243 .ml_meth = py_creds_set_secure_channel_type,
1244 .ml_flags = METH_VARARGS,
1247 .ml_name = "get_secure_channel_type",
1248 .ml_meth = py_creds_get_secure_channel_type,
1249 .ml_flags = METH_VARARGS,
1252 .ml_name = "encrypt_netr_crypt_password",
1253 .ml_meth = py_creds_encrypt_netr_crypt_password,
1254 .ml_flags = METH_VARARGS,
1255 .ml_doc = "S.encrypt_netr_crypt_password(password) -> NTSTATUS\n"
1256 "Encrypt the supplied password using the session key and\n"
1257 "the negotiated encryption algorithm in place\n"
1258 "i.e. it overwrites the original data"},
1260 .ml_name = "get_smb_signing",
1261 .ml_meth = py_creds_get_smb_signing,
1262 .ml_flags = METH_NOARGS,
1265 .ml_name = "set_smb_signing",
1266 .ml_meth = py_creds_set_smb_signing,
1267 .ml_flags = METH_VARARGS,
1269 { .ml_name = NULL }
1272 static struct PyModuleDef moduledef = {
1273 PyModuleDef_HEAD_INIT,
1274 .m_name = "credentials",
1275 .m_doc = "Credentials management.",
1276 .m_size = -1,
1277 .m_methods = py_creds_methods,
1280 PyTypeObject PyCredentials = {
1281 .tp_name = "credentials.Credentials",
1282 .tp_new = py_creds_new,
1283 .tp_flags = Py_TPFLAGS_DEFAULT,
1284 .tp_methods = py_creds_methods,
1287 static PyObject *py_ccache_name(PyObject *self, PyObject *unused)
1289 struct ccache_container *ccc = NULL;
1290 char *name = NULL;
1291 PyObject *py_name = NULL;
1292 int ret;
1294 ccc = pytalloc_get_type(self, struct ccache_container);
1296 ret = krb5_cc_get_full_name(ccc->smb_krb5_context->krb5_context,
1297 ccc->ccache, &name);
1298 if (ret == 0) {
1299 py_name = PyString_FromStringOrNULL(name);
1300 SAFE_FREE(name);
1301 } else {
1302 PyErr_SetString(PyExc_RuntimeError,
1303 "Failed to get ccache name");
1304 return NULL;
1306 return py_name;
1309 static PyMethodDef py_ccache_container_methods[] = {
1310 { "get_name", py_ccache_name, METH_NOARGS,
1311 "S.get_name() -> name\nObtain KRB5 credentials cache name." },
1315 PyTypeObject PyCredentialCacheContainer = {
1316 .tp_name = "credentials.CredentialCacheContainer",
1317 .tp_flags = Py_TPFLAGS_DEFAULT,
1318 .tp_methods = py_ccache_container_methods,
1321 MODULE_INIT_FUNC(credentials)
1323 PyObject *m;
1324 if (pytalloc_BaseObject_PyType_Ready(&PyCredentials) < 0)
1325 return NULL;
1327 if (pytalloc_BaseObject_PyType_Ready(&PyCredentialCacheContainer) < 0)
1328 return NULL;
1330 m = PyModule_Create(&moduledef);
1331 if (m == NULL)
1332 return NULL;
1334 PyModule_AddObject(m, "UNINITIALISED", PyLong_FromLong(CRED_UNINITIALISED));
1335 PyModule_AddObject(m, "SMB_CONF", PyLong_FromLong(CRED_SMB_CONF));
1336 PyModule_AddObject(m, "CALLBACK", PyLong_FromLong(CRED_CALLBACK));
1337 PyModule_AddObject(m, "GUESS_ENV", PyLong_FromLong(CRED_GUESS_ENV));
1338 PyModule_AddObject(m, "GUESS_FILE", PyLong_FromLong(CRED_GUESS_FILE));
1339 PyModule_AddObject(m, "CALLBACK_RESULT", PyLong_FromLong(CRED_CALLBACK_RESULT));
1340 PyModule_AddObject(m, "SPECIFIED", PyLong_FromLong(CRED_SPECIFIED));
1342 PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyLong_FromLong(CRED_AUTO_USE_KERBEROS));
1343 PyModule_AddObject(m, "DONT_USE_KERBEROS", PyLong_FromLong(CRED_DONT_USE_KERBEROS));
1344 PyModule_AddObject(m, "MUST_USE_KERBEROS", PyLong_FromLong(CRED_MUST_USE_KERBEROS));
1346 PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE", PyLong_FromLong(CRED_AUTO_KRB_FORWARDABLE));
1347 PyModule_AddObject(m, "NO_KRB_FORWARDABLE", PyLong_FromLong(CRED_NO_KRB_FORWARDABLE));
1348 PyModule_AddObject(m, "FORCE_KRB_FORWARDABLE", PyLong_FromLong(CRED_FORCE_KRB_FORWARDABLE));
1349 PyModule_AddObject(m, "CLI_CRED_NTLM2", PyLong_FromLong(CLI_CRED_NTLM2));
1350 PyModule_AddObject(m, "CLI_CRED_NTLMv2_AUTH", PyLong_FromLong(CLI_CRED_NTLMv2_AUTH));
1351 PyModule_AddObject(m, "CLI_CRED_LANMAN_AUTH", PyLong_FromLong(CLI_CRED_LANMAN_AUTH));
1352 PyModule_AddObject(m, "CLI_CRED_NTLM_AUTH", PyLong_FromLong(CLI_CRED_NTLM_AUTH));
1353 PyModule_AddObject(m, "CLI_CRED_CLEAR_AUTH", PyLong_FromLong(CLI_CRED_CLEAR_AUTH));
1355 PyModule_AddObject(m, "SMB_SIGNING_DEFAULT", PyLong_FromLong(SMB_SIGNING_DEFAULT));
1356 PyModule_AddObject(m, "SMB_SIGNING_OFF", PyLong_FromLong(SMB_SIGNING_OFF));
1357 PyModule_AddObject(m, "SMB_SIGNING_IF_REQUIRED", PyLong_FromLong(SMB_SIGNING_IF_REQUIRED));
1358 PyModule_AddObject(m, "SMB_SIGNING_DESIRED", PyLong_FromLong(SMB_SIGNING_DESIRED));
1359 PyModule_AddObject(m, "SMB_SIGNING_REQUIRED", PyLong_FromLong(SMB_SIGNING_REQUIRED));
1361 Py_INCREF(&PyCredentials);
1362 PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
1363 Py_INCREF(&PyCredentialCacheContainer);
1364 PyModule_AddObject(m, "CredentialCacheContainer", (PyObject *)&PyCredentialCacheContainer);
1365 return m;