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/>.
20 #include "python/py3compat.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"
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
);
49 PyErr_Format(PyExc_TypeError
, "Credentials expected");
52 return PyString_FromStringOrNULL(cli_credentials_get_username(creds
));
55 static PyObject
*py_creds_set_username(PyObject
*self
, PyObject
*args
)
58 enum credentials_obtained obt
= CRED_SPECIFIED
;
60 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
62 PyErr_Format(PyExc_TypeError
, "Credentials expected");
66 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
;
80 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
82 PyErr_Format(PyExc_TypeError
, "Credentials expected");
85 cli_credentials_get_ntlm_username_domain(creds
,
86 frame
, &user
, &domain
);
87 ret
= Py_BuildValue("(ss)",
95 static PyObject
*py_creds_get_ntlm_response(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
97 TALLOC_CTX
*frame
= talloc_stackframe();
100 struct timeval tv_now
;
101 NTTIME server_timestamp
;
102 DATA_BLOB challenge
= data_blob_null
;
103 DATA_BLOB target_info
= data_blob_null
;
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",
112 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
114 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
),
127 &target_info
.length
)) {
131 status
= cli_credentials_get_ntlm_response(creds
,
136 &lm_response
, &nt_response
,
137 &lm_session_key
, &nt_session_key
);
139 if (!NT_STATUS_IS_OK(status
)) {
140 PyErr_SetNTSTATUS(status
);
145 ret
= Py_BuildValue("{sis" PYARG_BYTES_LEN
"s" PYARG_BYTES_LEN
146 "s" PYARG_BYTES_LEN
"s" PYARG_BYTES_LEN
"}",
149 (const char *)lm_response
.data
, lm_response
.length
,
151 (const char *)nt_response
.data
, nt_response
.length
,
153 (const char *)lm_session_key
.data
, lm_session_key
.length
,
155 (const char *)nt_session_key
.data
, nt_session_key
.length
);
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
);
166 PyErr_Format(PyExc_TypeError
, "Credentials expected");
169 ret
= PyString_FromStringOrNULL(cli_credentials_get_principal(creds
, frame
));
174 static PyObject
*py_creds_set_principal(PyObject
*self
, PyObject
*args
)
177 enum credentials_obtained obt
= CRED_SPECIFIED
;
179 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
181 PyErr_Format(PyExc_TypeError
, "Credentials expected");
185 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
);
197 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
;
208 PyObject
*result
= NULL
;
209 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
211 PyErr_Format(PyExc_TypeError
, "Credentials expected");
215 if (!PyArg_ParseTuple(args
, PYARG_STR_UNI
"|i", "utf8", &newval
, &_obt
)) {
220 result
= PyBool_FromLong(cli_credentials_set_password(creds
, newval
, obt
));
221 PyMem_Free(discard_const_p(void*, newval
));
225 static PyObject
*py_creds_set_utf16_password(PyObject
*self
, PyObject
*args
)
227 enum credentials_obtained obt
= CRED_SPECIFIED
;
229 PyObject
*newval
= NULL
;
230 DATA_BLOB blob
= data_blob_null
;
234 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
236 PyErr_Format(PyExc_TypeError
, "Credentials expected");
240 if (!PyArg_ParseTuple(args
, "O|i", &newval
, &_obt
)) {
245 result
= PyBytes_AsStringAndSize(newval
, (char **)&blob
.data
, &size
);
247 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to Bytes");
252 ok
= cli_credentials_set_utf16_password(creds
,
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
);
262 PyErr_Format(PyExc_TypeError
, "Credentials expected");
265 return PyString_FromStringOrNULL(cli_credentials_get_old_password(creds
));
268 static PyObject
*py_creds_set_old_password(PyObject
*self
, PyObject
*args
)
271 enum credentials_obtained obt
= CRED_SPECIFIED
;
273 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
275 PyErr_Format(PyExc_TypeError
, "Credentials expected");
279 if (!PyArg_ParseTuple(args
, "s|i", &oldval
, &_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
;
294 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
296 PyErr_Format(PyExc_TypeError
, "Credentials expected");
300 if (!PyArg_ParseTuple(args
, "O", &oldval
)) {
304 result
= PyBytes_AsStringAndSize(oldval
, (char **)&blob
.data
, &size
);
306 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to Bytes");
311 ok
= cli_credentials_set_old_utf16_password(creds
,
314 return PyBool_FromLong(ok
);
317 static PyObject
*py_creds_get_domain(PyObject
*self
, PyObject
*unused
)
319 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
321 PyErr_Format(PyExc_TypeError
, "Credentials expected");
324 return PyString_FromStringOrNULL(cli_credentials_get_domain(creds
));
327 static PyObject
*py_creds_set_domain(PyObject
*self
, PyObject
*args
)
330 enum credentials_obtained obt
= CRED_SPECIFIED
;
332 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
334 PyErr_Format(PyExc_TypeError
, "Credentials expected");
338 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
);
350 PyErr_Format(PyExc_TypeError
, "Credentials expected");
353 return PyString_FromStringOrNULL(cli_credentials_get_realm(creds
));
356 static PyObject
*py_creds_set_realm(PyObject
*self
, PyObject
*args
)
359 enum credentials_obtained obt
= CRED_SPECIFIED
;
361 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
363 PyErr_Format(PyExc_TypeError
, "Credentials expected");
367 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
);
379 PyErr_Format(PyExc_TypeError
, "Credentials expected");
382 return PyString_FromStringOrNULL(cli_credentials_get_bind_dn(creds
));
385 static PyObject
*py_creds_set_bind_dn(PyObject
*self
, PyObject
*args
)
388 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
390 PyErr_Format(PyExc_TypeError
, "Credentials expected");
393 if (!PyArg_ParseTuple(args
, "s", &newval
))
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
);
403 PyErr_Format(PyExc_TypeError
, "Credentials expected");
406 return PyString_FromStringOrNULL(cli_credentials_get_workstation(creds
));
409 static PyObject
*py_creds_set_workstation(PyObject
*self
, PyObject
*args
)
412 enum credentials_obtained obt
= CRED_SPECIFIED
;
414 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
416 PyErr_Format(PyExc_TypeError
, "Credentials expected");
420 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
);
432 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
);
442 PyErr_Format(PyExc_TypeError
, "Credentials expected");
445 cli_credentials_set_anonymous(creds
);
449 static PyObject
*py_creds_authentication_requested(PyObject
*self
, PyObject
*unused
)
451 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
453 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
);
463 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
);
473 PyErr_Format(PyExc_TypeError
, "Credentials expected");
476 return PyBool_FromLong(cli_credentials_set_cmdline_callbacks(creds
));
479 static PyObject
*py_creds_parse_string(PyObject
*self
, PyObject
*args
)
482 enum credentials_obtained obt
= CRED_SPECIFIED
;
484 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
486 PyErr_Format(PyExc_TypeError
, "Credentials expected");
490 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_obt
)) {
495 cli_credentials_parse_string(creds
, newval
, obt
);
499 static PyObject
*py_creds_parse_file(PyObject
*self
, PyObject
*args
)
502 enum credentials_obtained obt
= CRED_SPECIFIED
;
504 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
506 PyErr_Format(PyExc_TypeError
, "Credentials expected");
510 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_obt
)) {
515 cli_credentials_parse_file(creds
, newval
, obt
);
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
;
525 if (!PyArg_ParseTuple(args
, "O!", &PyBool_Type
, &py_val
)) {
528 val
= PyObject_IsTrue(py_val
);
530 cli_credentials_set_password_will_be_nt_hash(creds
, val
);
534 static PyObject
*py_creds_get_nt_hash(PyObject
*self
, PyObject
*unused
)
537 struct samr_Password
*ntpw
= NULL
;
538 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
540 PyErr_Format(PyExc_TypeError
, "Credentials expected");
543 ntpw
= cli_credentials_get_nt_hash(creds
, creds
);
545 ret
= PyBytes_FromStringAndSize(discard_const_p(char, ntpw
->hash
), 16);
550 static PyObject
*py_creds_get_kerberos_state(PyObject
*self
, PyObject
*unused
)
553 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
555 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
)
565 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
567 PyErr_Format(PyExc_TypeError
, "Credentials expected");
570 if (!PyArg_ParseTuple(args
, "i", &state
))
573 cli_credentials_set_kerberos_state(creds
, state
);
577 static PyObject
*py_creds_set_krb_forwardable(PyObject
*self
, PyObject
*args
)
580 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
582 PyErr_Format(PyExc_TypeError
, "Credentials expected");
585 if (!PyArg_ParseTuple(args
, "i", &state
))
588 cli_credentials_set_krb_forwardable(creds
, state
);
593 static PyObject
*py_creds_get_forced_sasl_mech(PyObject
*self
, PyObject
*unused
)
595 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
597 PyErr_Format(PyExc_TypeError
, "Credentials expected");
600 return PyString_FromStringOrNULL(cli_credentials_get_forced_sasl_mech(creds
));
603 static PyObject
*py_creds_set_forced_sasl_mech(PyObject
*self
, PyObject
*args
)
606 enum credentials_obtained obt
= CRED_SPECIFIED
;
608 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
610 PyErr_Format(PyExc_TypeError
, "Credentials expected");
614 if (!PyArg_ParseTuple(args
, "s", &newval
)) {
619 cli_credentials_set_forced_sasl_mech(creds
, newval
);
623 static PyObject
*py_creds_guess(PyObject
*self
, PyObject
*args
)
625 PyObject
*py_lp_ctx
= Py_None
;
626 struct loadparm_context
*lp_ctx
;
628 struct cli_credentials
*creds
;
630 creds
= PyCredentials_AsCliCredentials(self
);
632 PyErr_Format(PyExc_TypeError
, "Credentials expected");
636 if (!PyArg_ParseTuple(args
, "|O", &py_lp_ctx
))
639 mem_ctx
= talloc_new(NULL
);
640 if (mem_ctx
== NULL
) {
645 lp_ctx
= lpcfg_from_py_object(mem_ctx
, py_lp_ctx
);
646 if (lp_ctx
== NULL
) {
647 talloc_free(mem_ctx
);
651 cli_credentials_guess(creds
, lp_ctx
);
653 talloc_free(mem_ctx
);
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
;
663 struct cli_credentials
*creds
;
666 creds
= PyCredentials_AsCliCredentials(self
);
668 PyErr_Format(PyExc_TypeError
, "Credentials expected");
672 if (!PyArg_ParseTuple(args
, "|O", &py_lp_ctx
))
675 mem_ctx
= talloc_new(NULL
);
676 if (mem_ctx
== NULL
) {
681 lp_ctx
= lpcfg_from_py_object(mem_ctx
, py_lp_ctx
);
682 if (lp_ctx
== NULL
) {
683 talloc_free(mem_ctx
);
687 status
= cli_credentials_set_machine_account(creds
, lp_ctx
);
688 talloc_free(mem_ctx
);
690 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
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
;
709 const char *error_string
;
710 struct cli_credentials
*creds
;
713 creds
= PyCredentials_AsCliCredentials(self
);
715 PyErr_Format(PyExc_TypeError
, "Credentials expected");
719 if (!PyArg_ParseTuple(args
, "|Os", &py_lp_ctx
, &ccache_name
))
722 mem_ctx
= talloc_new(NULL
);
723 if (mem_ctx
== NULL
) {
728 lp_ctx
= lpcfg_from_py_object(mem_ctx
, py_lp_ctx
);
729 if (lp_ctx
== NULL
) {
730 talloc_free(mem_ctx
);
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
);
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
);
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
;
758 PyObject
*py_lp_ctx
= Py_None
;
761 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
763 PyErr_Format(PyExc_TypeError
, "Credentials expected");
767 if (!PyArg_ParseTuple(args
, "s|iO", &newval
, &_obt
, &py_lp_ctx
))
770 mem_ctx
= talloc_new(NULL
);
771 if (mem_ctx
== NULL
) {
776 lp_ctx
= lpcfg_from_py_object(mem_ctx
, py_lp_ctx
);
777 if (lp_ctx
== NULL
) {
778 talloc_free(mem_ctx
);
782 ret
= cli_credentials_set_ccache(creds
,
784 newval
, CRED_SPECIFIED
,
788 PyErr_SetString(PyExc_RuntimeError
,
789 error_string
!= NULL
? error_string
: "NULL");
790 talloc_free(mem_ctx
);
794 talloc_free(mem_ctx
);
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
);
803 PyErr_Format(PyExc_TypeError
, "Credentials expected");
807 if (!PyArg_ParseTuple(args
, "I", &gensec_features
))
810 cli_credentials_set_gensec_features(creds
, gensec_features
);
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
);
820 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
,
831 struct netr_Authenticator auth
;
832 struct cli_credentials
*creds
= NULL
;
833 struct netlogon_creds_CredentialState
*nc
= NULL
;
834 PyObject
*ret
= NULL
;
837 creds
= PyCredentials_AsCliCredentials(self
);
839 PyErr_SetString(PyExc_RuntimeError
,
840 "Failed to get credentials from python");
844 nc
= creds
->netlogon_creds
;
846 PyErr_SetString(PyExc_ValueError
,
847 "No netlogon credentials cannot make "
848 "client authenticator");
852 status
= netlogon_creds_client_authenticator(nc
, &auth
);
853 if (!NT_STATUS_IS_OK(status
)) {
854 PyErr_SetString(PyExc_ValueError
,
855 "Failed to create client authenticator");
859 ret
= Py_BuildValue("{s"PYARG_BYTES_LEN
"si}",
861 (const char *) &auth
.cred
, sizeof(auth
.cred
),
862 "timestamp", auth
.timestamp
);
866 static PyObject
*py_creds_set_secure_channel_type(PyObject
*self
, PyObject
*args
)
868 unsigned int channel_type
;
869 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
871 PyErr_Format(PyExc_TypeError
, "Credentials expected");
875 if (!PyArg_ParseTuple(args
, "I", &channel_type
))
878 cli_credentials_set_secure_channel_type(
885 static PyObject
*py_creds_get_secure_channel_type(PyObject
*self
, PyObject
*args
)
887 enum netr_SchannelType channel_type
= SEC_CHAN_NULL
;
888 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
890 PyErr_Format(PyExc_TypeError
, "Credentials expected");
894 channel_type
= cli_credentials_get_secure_channel_type(creds
);
896 return PyInt_FromLong(channel_type
);
899 static PyObject
*py_creds_encrypt_netr_crypt_password(PyObject
*self
,
902 DATA_BLOB data
= data_blob_null
;
903 struct cli_credentials
*creds
= NULL
;
904 struct netr_CryptPassword
*pwd
= NULL
;
906 PyObject
*py_cp
= Py_None
;
908 creds
= PyCredentials_AsCliCredentials(self
);
910 PyErr_Format(PyExc_TypeError
, "Credentials expected");
914 if (!PyArg_ParseTuple(args
, "O", &py_cp
)) {
918 pwd
= pytalloc_get_type(py_cp
, struct netr_CryptPassword
);
920 /* pytalloc_get_type sets TypeError */
923 data
.length
= sizeof(struct netr_CryptPassword
);
924 data
.data
= (uint8_t *)pwd
;
925 status
= netlogon_creds_session_encrypt(creds
->netlogon_creds
, data
);
927 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
932 static PyMethodDef py_creds_methods
[] = {
934 .ml_name
= "get_username",
935 .ml_meth
= py_creds_get_username
,
936 .ml_flags
= METH_NOARGS
,
937 .ml_doc
= "S.get_username() -> username\nObtain username.",
940 .ml_name
= "set_username",
941 .ml_meth
= py_creds_set_username
,
942 .ml_flags
= METH_VARARGS
,
943 .ml_doc
= "S.set_username(name[, credentials.SPECIFIED]) -> None\n"
947 .ml_name
= "get_principal",
948 .ml_meth
= py_creds_get_principal
,
949 .ml_flags
= METH_NOARGS
,
950 .ml_doc
= "S.get_principal() -> user@realm\nObtain user principal.",
953 .ml_name
= "set_principal",
954 .ml_meth
= py_creds_set_principal
,
955 .ml_flags
= METH_VARARGS
,
956 .ml_doc
= "S.set_principal(name[, credentials.SPECIFIED]) -> None\n"
960 .ml_name
= "get_password",
961 .ml_meth
= py_creds_get_password
,
962 .ml_flags
= METH_NOARGS
,
963 .ml_doc
= "S.get_password() -> password\n"
967 .ml_name
= "get_ntlm_username_domain",
968 .ml_meth
= py_creds_get_ntlm_username_domain
,
969 .ml_flags
= METH_NOARGS
,
970 .ml_doc
= "S.get_ntlm_username_domain() -> (domain, username)\n"
971 "Obtain NTLM username and domain, split up either as (DOMAIN, user) or (\"\", \"user@realm\").",
974 .ml_name
= "get_ntlm_response",
975 .ml_meth
= PY_DISCARD_FUNC_SIG(PyCFunction
,
976 py_creds_get_ntlm_response
),
977 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
978 .ml_doc
= "S.get_ntlm_response"
979 "(flags, challenge[, target_info]) -> "
980 "(flags, lm_response, nt_response, lm_session_key, nt_session_key)\n"
981 "Obtain LM or NTLM response.",
984 .ml_name
= "set_password",
985 .ml_meth
= py_creds_set_password
,
986 .ml_flags
= METH_VARARGS
,
987 .ml_doc
= "S.set_password(password[, credentials.SPECIFIED]) -> None\n"
991 .ml_name
= "set_utf16_password",
992 .ml_meth
= py_creds_set_utf16_password
,
993 .ml_flags
= METH_VARARGS
,
994 .ml_doc
= "S.set_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
998 .ml_name
= "get_old_password",
999 .ml_meth
= py_creds_get_old_password
,
1000 .ml_flags
= METH_NOARGS
,
1001 .ml_doc
= "S.get_old_password() -> password\n"
1002 "Obtain old password.",
1005 .ml_name
= "set_old_password",
1006 .ml_meth
= py_creds_set_old_password
,
1007 .ml_flags
= METH_VARARGS
,
1008 .ml_doc
= "S.set_old_password(password[, credentials.SPECIFIED]) -> None\n"
1009 "Change old password.",
1012 .ml_name
= "set_old_utf16_password",
1013 .ml_meth
= py_creds_set_old_utf16_password
,
1014 .ml_flags
= METH_VARARGS
,
1015 .ml_doc
= "S.set_old_utf16_password(password[, credentials.SPECIFIED]) -> None\n"
1016 "Change old password.",
1019 .ml_name
= "get_domain",
1020 .ml_meth
= py_creds_get_domain
,
1021 .ml_flags
= METH_NOARGS
,
1022 .ml_doc
= "S.get_domain() -> domain\n"
1023 "Obtain domain name.",
1026 .ml_name
= "set_domain",
1027 .ml_meth
= py_creds_set_domain
,
1028 .ml_flags
= METH_VARARGS
,
1029 .ml_doc
= "S.set_domain(domain[, credentials.SPECIFIED]) -> None\n"
1030 "Change domain name.",
1033 .ml_name
= "get_realm",
1034 .ml_meth
= py_creds_get_realm
,
1035 .ml_flags
= METH_NOARGS
,
1036 .ml_doc
= "S.get_realm() -> realm\n"
1037 "Obtain realm name.",
1040 .ml_name
= "set_realm",
1041 .ml_meth
= py_creds_set_realm
,
1042 .ml_flags
= METH_VARARGS
,
1043 .ml_doc
= "S.set_realm(realm[, credentials.SPECIFIED]) -> None\n"
1044 "Change realm name.",
1047 .ml_name
= "get_bind_dn",
1048 .ml_meth
= py_creds_get_bind_dn
,
1049 .ml_flags
= METH_NOARGS
,
1050 .ml_doc
= "S.get_bind_dn() -> bind dn\n"
1054 .ml_name
= "set_bind_dn",
1055 .ml_meth
= py_creds_set_bind_dn
,
1056 .ml_flags
= METH_VARARGS
,
1057 .ml_doc
= "S.set_bind_dn(bind_dn) -> None\n"
1061 .ml_name
= "is_anonymous",
1062 .ml_meth
= py_creds_is_anonymous
,
1063 .ml_flags
= METH_NOARGS
,
1066 .ml_name
= "set_anonymous",
1067 .ml_meth
= py_creds_set_anonymous
,
1068 .ml_flags
= METH_NOARGS
,
1069 .ml_doc
= "S.set_anonymous() -> None\n"
1070 "Use anonymous credentials.",
1073 .ml_name
= "get_workstation",
1074 .ml_meth
= py_creds_get_workstation
,
1075 .ml_flags
= METH_NOARGS
,
1078 .ml_name
= "set_workstation",
1079 .ml_meth
= py_creds_set_workstation
,
1080 .ml_flags
= METH_VARARGS
,
1083 .ml_name
= "authentication_requested",
1084 .ml_meth
= py_creds_authentication_requested
,
1085 .ml_flags
= METH_NOARGS
,
1088 .ml_name
= "wrong_password",
1089 .ml_meth
= py_creds_wrong_password
,
1090 .ml_flags
= METH_NOARGS
,
1091 .ml_doc
= "S.wrong_password() -> bool\n"
1092 "Indicate the returned password was incorrect.",
1095 .ml_name
= "set_cmdline_callbacks",
1096 .ml_meth
= py_creds_set_cmdline_callbacks
,
1097 .ml_flags
= METH_NOARGS
,
1098 .ml_doc
= "S.set_cmdline_callbacks() -> bool\n"
1099 "Use command-line to obtain credentials not explicitly set.",
1102 .ml_name
= "parse_string",
1103 .ml_meth
= py_creds_parse_string
,
1104 .ml_flags
= METH_VARARGS
,
1105 .ml_doc
= "S.parse_string(text[, credentials.SPECIFIED]) -> None\n"
1106 "Parse credentials string.",
1109 .ml_name
= "parse_file",
1110 .ml_meth
= py_creds_parse_file
,
1111 .ml_flags
= METH_VARARGS
,
1112 .ml_doc
= "S.parse_file(filename[, credentials.SPECIFIED]) -> None\n"
1113 "Parse credentials file.",
1116 .ml_name
= "set_password_will_be_nt_hash",
1117 .ml_meth
= py_cli_credentials_set_password_will_be_nt_hash
,
1118 .ml_flags
= METH_VARARGS
,
1119 .ml_doc
= "S.set_password_will_be_nt_hash(bool) -> None\n"
1120 "Alters the behaviour of S.set_password() "
1121 "to expect the NTHASH as hexstring.",
1124 .ml_name
= "get_nt_hash",
1125 .ml_meth
= py_creds_get_nt_hash
,
1126 .ml_flags
= METH_NOARGS
,
1129 .ml_name
= "get_kerberos_state",
1130 .ml_meth
= py_creds_get_kerberos_state
,
1131 .ml_flags
= METH_NOARGS
,
1134 .ml_name
= "set_kerberos_state",
1135 .ml_meth
= py_creds_set_kerberos_state
,
1136 .ml_flags
= METH_VARARGS
,
1139 .ml_name
= "set_krb_forwardable",
1140 .ml_meth
= py_creds_set_krb_forwardable
,
1141 .ml_flags
= METH_VARARGS
,
1145 .ml_meth
= py_creds_guess
,
1146 .ml_flags
= METH_VARARGS
,
1149 .ml_name
= "set_machine_account",
1150 .ml_meth
= py_creds_set_machine_account
,
1151 .ml_flags
= METH_VARARGS
,
1154 .ml_name
= "get_named_ccache",
1155 .ml_meth
= py_creds_get_named_ccache
,
1156 .ml_flags
= METH_VARARGS
,
1159 .ml_name
= "set_named_ccache",
1160 .ml_meth
= py_creds_set_named_ccache
,
1161 .ml_flags
= METH_VARARGS
,
1162 .ml_doc
= "S.set_named_ccache(krb5_ccache_name, obtained, lp) -> None\n"
1163 "Set credentials to KRB5 Credentials Cache (by name).",
1166 .ml_name
= "set_gensec_features",
1167 .ml_meth
= py_creds_set_gensec_features
,
1168 .ml_flags
= METH_VARARGS
,
1171 .ml_name
= "get_gensec_features",
1172 .ml_meth
= py_creds_get_gensec_features
,
1173 .ml_flags
= METH_NOARGS
,
1176 .ml_name
= "get_forced_sasl_mech",
1177 .ml_meth
= py_creds_get_forced_sasl_mech
,
1178 .ml_flags
= METH_NOARGS
,
1179 .ml_doc
= "S.get_forced_sasl_mech() -> SASL mechanism\nObtain forced SASL mechanism.",
1182 .ml_name
= "set_forced_sasl_mech",
1183 .ml_meth
= py_creds_set_forced_sasl_mech
,
1184 .ml_flags
= METH_VARARGS
,
1185 .ml_doc
= "S.set_forced_sasl_mech(name) -> None\n"
1186 "Set forced SASL mechanism.",
1189 .ml_name
= "new_client_authenticator",
1190 .ml_meth
= py_creds_new_client_authenticator
,
1191 .ml_flags
= METH_NOARGS
,
1192 .ml_doc
= "S.new_client_authenticator() -> Authenticator\n"
1193 "Get a new client NETLOGON_AUTHENTICATOR"},
1195 .ml_name
= "set_secure_channel_type",
1196 .ml_meth
= py_creds_set_secure_channel_type
,
1197 .ml_flags
= METH_VARARGS
,
1200 .ml_name
= "get_secure_channel_type",
1201 .ml_meth
= py_creds_get_secure_channel_type
,
1202 .ml_flags
= METH_VARARGS
,
1205 .ml_name
= "encrypt_netr_crypt_password",
1206 .ml_meth
= py_creds_encrypt_netr_crypt_password
,
1207 .ml_flags
= METH_VARARGS
,
1208 .ml_doc
= "S.encrypt_netr_crypt_password(password) -> NTSTATUS\n"
1209 "Encrypt the supplied password using the session key and\n"
1210 "the negotiated encryption algorithm in place\n"
1211 "i.e. it overwrites the original data"},
1215 static struct PyModuleDef moduledef
= {
1216 PyModuleDef_HEAD_INIT
,
1217 .m_name
= "credentials",
1218 .m_doc
= "Credentials management.",
1220 .m_methods
= py_creds_methods
,
1223 PyTypeObject PyCredentials
= {
1224 .tp_name
= "credentials.Credentials",
1225 .tp_new
= py_creds_new
,
1226 .tp_flags
= Py_TPFLAGS_DEFAULT
,
1227 .tp_methods
= py_creds_methods
,
1230 static PyObject
*py_ccache_name(PyObject
*self
, PyObject
*unused
)
1232 struct ccache_container
*ccc
= NULL
;
1234 PyObject
*py_name
= NULL
;
1237 ccc
= pytalloc_get_type(self
, struct ccache_container
);
1239 ret
= krb5_cc_get_full_name(ccc
->smb_krb5_context
->krb5_context
,
1240 ccc
->ccache
, &name
);
1242 py_name
= PyString_FromStringOrNULL(name
);
1245 PyErr_SetString(PyExc_RuntimeError
,
1246 "Failed to get ccache name");
1252 static PyMethodDef py_ccache_container_methods
[] = {
1253 { "get_name", py_ccache_name
, METH_NOARGS
,
1254 "S.get_name() -> name\nObtain KRB5 credentials cache name." },
1258 PyTypeObject PyCredentialCacheContainer
= {
1259 .tp_name
= "credentials.CredentialCacheContainer",
1260 .tp_flags
= Py_TPFLAGS_DEFAULT
,
1261 .tp_methods
= py_ccache_container_methods
,
1264 MODULE_INIT_FUNC(credentials
)
1267 if (pytalloc_BaseObject_PyType_Ready(&PyCredentials
) < 0)
1270 if (pytalloc_BaseObject_PyType_Ready(&PyCredentialCacheContainer
) < 0)
1273 m
= PyModule_Create(&moduledef
);
1277 PyModule_AddObject(m
, "UNINITIALISED", PyInt_FromLong(CRED_UNINITIALISED
));
1278 PyModule_AddObject(m
, "CALLBACK", PyInt_FromLong(CRED_CALLBACK
));
1279 PyModule_AddObject(m
, "GUESS_ENV", PyInt_FromLong(CRED_GUESS_ENV
));
1280 PyModule_AddObject(m
, "GUESS_FILE", PyInt_FromLong(CRED_GUESS_FILE
));
1281 PyModule_AddObject(m
, "CALLBACK_RESULT", PyInt_FromLong(CRED_CALLBACK_RESULT
));
1282 PyModule_AddObject(m
, "SPECIFIED", PyInt_FromLong(CRED_SPECIFIED
));
1284 PyModule_AddObject(m
, "AUTO_USE_KERBEROS", PyInt_FromLong(CRED_AUTO_USE_KERBEROS
));
1285 PyModule_AddObject(m
, "DONT_USE_KERBEROS", PyInt_FromLong(CRED_DONT_USE_KERBEROS
));
1286 PyModule_AddObject(m
, "MUST_USE_KERBEROS", PyInt_FromLong(CRED_MUST_USE_KERBEROS
));
1288 PyModule_AddObject(m
, "AUTO_KRB_FORWARDABLE", PyInt_FromLong(CRED_AUTO_KRB_FORWARDABLE
));
1289 PyModule_AddObject(m
, "NO_KRB_FORWARDABLE", PyInt_FromLong(CRED_NO_KRB_FORWARDABLE
));
1290 PyModule_AddObject(m
, "FORCE_KRB_FORWARDABLE", PyInt_FromLong(CRED_FORCE_KRB_FORWARDABLE
));
1291 PyModule_AddObject(m
, "CLI_CRED_NTLM2", PyInt_FromLong(CLI_CRED_NTLM2
));
1292 PyModule_AddObject(m
, "CLI_CRED_NTLMv2_AUTH", PyInt_FromLong(CLI_CRED_NTLMv2_AUTH
));
1293 PyModule_AddObject(m
, "CLI_CRED_LANMAN_AUTH", PyInt_FromLong(CLI_CRED_LANMAN_AUTH
));
1294 PyModule_AddObject(m
, "CLI_CRED_NTLM_AUTH", PyInt_FromLong(CLI_CRED_NTLM_AUTH
));
1295 PyModule_AddObject(m
, "CLI_CRED_CLEAR_AUTH", PyInt_FromLong(CLI_CRED_CLEAR_AUTH
));
1297 Py_INCREF(&PyCredentials
);
1298 PyModule_AddObject(m
, "Credentials", (PyObject
*)&PyCredentials
);
1299 Py_INCREF(&PyCredentialCacheContainer
);
1300 PyModule_AddObject(m
, "CredentialCacheContainer", (PyObject
*)&PyCredentialCacheContainer
);