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"
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
);
50 PyErr_Format(PyExc_TypeError
, "Credentials expected");
53 return PyString_FromStringOrNULL(cli_credentials_get_username(creds
));
56 static PyObject
*py_creds_set_username(PyObject
*self
, PyObject
*args
)
59 enum credentials_obtained obt
= CRED_SPECIFIED
;
61 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
63 PyErr_Format(PyExc_TypeError
, "Credentials expected");
67 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
;
81 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
83 PyErr_Format(PyExc_TypeError
, "Credentials expected");
86 cli_credentials_get_ntlm_username_domain(creds
,
87 frame
, &user
, &domain
);
88 ret
= Py_BuildValue("(ss)",
96 static PyObject
*py_creds_get_ntlm_response(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
98 TALLOC_CTX
*frame
= talloc_stackframe();
101 struct timeval tv_now
;
102 NTTIME server_timestamp
;
103 DATA_BLOB challenge
= data_blob_null
;
104 DATA_BLOB target_info
= data_blob_null
;
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",
113 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
115 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
),
128 &target_info
.length
)) {
132 status
= cli_credentials_get_ntlm_response(creds
,
137 &lm_response
, &nt_response
,
138 &lm_session_key
, &nt_session_key
);
140 if (!NT_STATUS_IS_OK(status
)) {
141 PyErr_SetNTSTATUS(status
);
146 ret
= Py_BuildValue("{sis" PYARG_BYTES_LEN
"s" PYARG_BYTES_LEN
147 "s" PYARG_BYTES_LEN
"s" PYARG_BYTES_LEN
"}",
150 (const char *)lm_response
.data
, lm_response
.length
,
152 (const char *)nt_response
.data
, nt_response
.length
,
154 (const char *)lm_session_key
.data
, lm_session_key
.length
,
156 (const char *)nt_session_key
.data
, nt_session_key
.length
);
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
);
167 PyErr_Format(PyExc_TypeError
, "Credentials expected");
170 ret
= PyString_FromStringOrNULL(cli_credentials_get_principal(creds
, frame
));
175 static PyObject
*py_creds_set_principal(PyObject
*self
, PyObject
*args
)
178 enum credentials_obtained obt
= CRED_SPECIFIED
;
180 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
182 PyErr_Format(PyExc_TypeError
, "Credentials expected");
186 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
);
198 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
;
209 PyObject
*result
= NULL
;
210 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
212 PyErr_Format(PyExc_TypeError
, "Credentials expected");
216 if (!PyArg_ParseTuple(args
, PYARG_STR_UNI
"|i", "utf8", &newval
, &_obt
)) {
221 result
= PyBool_FromLong(cli_credentials_set_password(creds
, newval
, obt
));
222 PyMem_Free(discard_const_p(void*, newval
));
226 static PyObject
*py_creds_set_utf16_password(PyObject
*self
, PyObject
*args
)
228 enum credentials_obtained obt
= CRED_SPECIFIED
;
230 PyObject
*newval
= NULL
;
231 DATA_BLOB blob
= data_blob_null
;
235 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
237 PyErr_Format(PyExc_TypeError
, "Credentials expected");
241 if (!PyArg_ParseTuple(args
, "O|i", &newval
, &_obt
)) {
246 result
= PyBytes_AsStringAndSize(newval
, (char **)&blob
.data
, &size
);
248 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to Bytes");
253 ok
= cli_credentials_set_utf16_password(creds
,
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
);
263 PyErr_Format(PyExc_TypeError
, "Credentials expected");
266 return PyString_FromStringOrNULL(cli_credentials_get_old_password(creds
));
269 static PyObject
*py_creds_set_old_password(PyObject
*self
, PyObject
*args
)
272 enum credentials_obtained obt
= CRED_SPECIFIED
;
274 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
276 PyErr_Format(PyExc_TypeError
, "Credentials expected");
280 if (!PyArg_ParseTuple(args
, "s|i", &oldval
, &_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
;
295 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
297 PyErr_Format(PyExc_TypeError
, "Credentials expected");
301 if (!PyArg_ParseTuple(args
, "O", &oldval
)) {
305 result
= PyBytes_AsStringAndSize(oldval
, (char **)&blob
.data
, &size
);
307 PyErr_SetString(PyExc_RuntimeError
, "Failed to convert passed value to Bytes");
312 ok
= cli_credentials_set_old_utf16_password(creds
,
315 return PyBool_FromLong(ok
);
318 static PyObject
*py_creds_get_domain(PyObject
*self
, PyObject
*unused
)
320 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
322 PyErr_Format(PyExc_TypeError
, "Credentials expected");
325 return PyString_FromStringOrNULL(cli_credentials_get_domain(creds
));
328 static PyObject
*py_creds_set_domain(PyObject
*self
, PyObject
*args
)
331 enum credentials_obtained obt
= CRED_SPECIFIED
;
333 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
335 PyErr_Format(PyExc_TypeError
, "Credentials expected");
339 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
);
351 PyErr_Format(PyExc_TypeError
, "Credentials expected");
354 return PyString_FromStringOrNULL(cli_credentials_get_realm(creds
));
357 static PyObject
*py_creds_set_realm(PyObject
*self
, PyObject
*args
)
360 enum credentials_obtained obt
= CRED_SPECIFIED
;
362 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
364 PyErr_Format(PyExc_TypeError
, "Credentials expected");
368 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
);
380 PyErr_Format(PyExc_TypeError
, "Credentials expected");
383 return PyString_FromStringOrNULL(cli_credentials_get_bind_dn(creds
));
386 static PyObject
*py_creds_set_bind_dn(PyObject
*self
, PyObject
*args
)
389 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
391 PyErr_Format(PyExc_TypeError
, "Credentials expected");
394 if (!PyArg_ParseTuple(args
, "s", &newval
))
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
);
404 PyErr_Format(PyExc_TypeError
, "Credentials expected");
407 return PyString_FromStringOrNULL(cli_credentials_get_workstation(creds
));
410 static PyObject
*py_creds_set_workstation(PyObject
*self
, PyObject
*args
)
413 enum credentials_obtained obt
= CRED_SPECIFIED
;
415 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
417 PyErr_Format(PyExc_TypeError
, "Credentials expected");
421 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_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
);
433 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
);
443 PyErr_Format(PyExc_TypeError
, "Credentials expected");
446 cli_credentials_set_anonymous(creds
);
450 static PyObject
*py_creds_authentication_requested(PyObject
*self
, PyObject
*unused
)
452 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
454 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
);
464 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
);
474 PyErr_Format(PyExc_TypeError
, "Credentials expected");
477 return PyBool_FromLong(cli_credentials_set_cmdline_callbacks(creds
));
480 static PyObject
*py_creds_parse_string(PyObject
*self
, PyObject
*args
)
483 enum credentials_obtained obt
= CRED_SPECIFIED
;
485 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
487 PyErr_Format(PyExc_TypeError
, "Credentials expected");
491 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_obt
)) {
496 cli_credentials_parse_string(creds
, newval
, obt
);
500 static PyObject
*py_creds_parse_file(PyObject
*self
, PyObject
*args
)
503 enum credentials_obtained obt
= CRED_SPECIFIED
;
505 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
507 PyErr_Format(PyExc_TypeError
, "Credentials expected");
511 if (!PyArg_ParseTuple(args
, "s|i", &newval
, &_obt
)) {
516 cli_credentials_parse_file(creds
, newval
, obt
);
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
;
526 if (!PyArg_ParseTuple(args
, "O!", &PyBool_Type
, &py_val
)) {
529 val
= PyObject_IsTrue(py_val
);
531 cli_credentials_set_password_will_be_nt_hash(creds
, val
);
535 static PyObject
*py_creds_get_nt_hash(PyObject
*self
, PyObject
*unused
)
538 struct samr_Password
*ntpw
= NULL
;
539 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
541 PyErr_Format(PyExc_TypeError
, "Credentials expected");
544 ntpw
= cli_credentials_get_nt_hash(creds
, creds
);
546 ret
= PyBytes_FromStringAndSize(discard_const_p(char, ntpw
->hash
), 16);
551 static PyObject
*py_creds_get_kerberos_state(PyObject
*self
, PyObject
*unused
)
554 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
556 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
)
566 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
568 PyErr_Format(PyExc_TypeError
, "Credentials expected");
571 if (!PyArg_ParseTuple(args
, "i", &state
))
574 cli_credentials_set_kerberos_state(creds
, state
);
578 static PyObject
*py_creds_set_krb_forwardable(PyObject
*self
, PyObject
*args
)
581 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
583 PyErr_Format(PyExc_TypeError
, "Credentials expected");
586 if (!PyArg_ParseTuple(args
, "i", &state
))
589 cli_credentials_set_krb_forwardable(creds
, state
);
594 static PyObject
*py_creds_get_forced_sasl_mech(PyObject
*self
, PyObject
*unused
)
596 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
598 PyErr_Format(PyExc_TypeError
, "Credentials expected");
601 return PyString_FromStringOrNULL(cli_credentials_get_forced_sasl_mech(creds
));
604 static PyObject
*py_creds_set_forced_sasl_mech(PyObject
*self
, PyObject
*args
)
607 enum credentials_obtained obt
= CRED_SPECIFIED
;
609 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
611 PyErr_Format(PyExc_TypeError
, "Credentials expected");
615 if (!PyArg_ParseTuple(args
, "s", &newval
)) {
620 cli_credentials_set_forced_sasl_mech(creds
, newval
);
624 static PyObject
*py_creds_guess(PyObject
*self
, PyObject
*args
)
626 PyObject
*py_lp_ctx
= Py_None
;
627 struct loadparm_context
*lp_ctx
;
629 struct cli_credentials
*creds
;
631 creds
= PyCredentials_AsCliCredentials(self
);
633 PyErr_Format(PyExc_TypeError
, "Credentials expected");
637 if (!PyArg_ParseTuple(args
, "|O", &py_lp_ctx
))
640 mem_ctx
= talloc_new(NULL
);
641 if (mem_ctx
== NULL
) {
646 lp_ctx
= lpcfg_from_py_object(mem_ctx
, py_lp_ctx
);
647 if (lp_ctx
== NULL
) {
648 talloc_free(mem_ctx
);
652 cli_credentials_guess(creds
, lp_ctx
);
654 talloc_free(mem_ctx
);
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
;
664 struct cli_credentials
*creds
;
667 creds
= PyCredentials_AsCliCredentials(self
);
669 PyErr_Format(PyExc_TypeError
, "Credentials expected");
673 if (!PyArg_ParseTuple(args
, "|O", &py_lp_ctx
))
676 mem_ctx
= talloc_new(NULL
);
677 if (mem_ctx
== NULL
) {
682 lp_ctx
= lpcfg_from_py_object(mem_ctx
, py_lp_ctx
);
683 if (lp_ctx
== NULL
) {
684 talloc_free(mem_ctx
);
688 status
= cli_credentials_set_machine_account(creds
, lp_ctx
);
689 talloc_free(mem_ctx
);
691 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
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
;
710 const char *error_string
;
711 struct cli_credentials
*creds
;
714 creds
= PyCredentials_AsCliCredentials(self
);
716 PyErr_Format(PyExc_TypeError
, "Credentials expected");
720 if (!PyArg_ParseTuple(args
, "|Os", &py_lp_ctx
, &ccache_name
))
723 mem_ctx
= talloc_new(NULL
);
724 if (mem_ctx
== NULL
) {
729 lp_ctx
= lpcfg_from_py_object(mem_ctx
, py_lp_ctx
);
730 if (lp_ctx
== NULL
) {
731 talloc_free(mem_ctx
);
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
);
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
);
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
;
759 PyObject
*py_lp_ctx
= Py_None
;
762 struct cli_credentials
*creds
= PyCredentials_AsCliCredentials(self
);
764 PyErr_Format(PyExc_TypeError
, "Credentials expected");
768 if (!PyArg_ParseTuple(args
, "s|iO", &newval
, &_obt
, &py_lp_ctx
))
771 mem_ctx
= talloc_new(NULL
);
772 if (mem_ctx
== NULL
) {
777 lp_ctx
= lpcfg_from_py_object(mem_ctx
, py_lp_ctx
);
778 if (lp_ctx
== NULL
) {
779 talloc_free(mem_ctx
);
783 ret
= cli_credentials_set_ccache(creds
,
785 newval
, CRED_SPECIFIED
,
789 PyErr_SetString(PyExc_RuntimeError
,
790 error_string
!= NULL
? error_string
: "NULL");
791 talloc_free(mem_ctx
);
795 talloc_free(mem_ctx
);
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
);
804 PyErr_Format(PyExc_TypeError
, "Credentials expected");
808 if (!PyArg_ParseTuple(args
, "I", &gensec_features
))
811 cli_credentials_set_gensec_features(creds
, gensec_features
);
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
);
821 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
,
832 struct netr_Authenticator auth
;
833 struct cli_credentials
*creds
= NULL
;
834 struct netlogon_creds_CredentialState
*nc
= NULL
;
835 PyObject
*ret
= NULL
;
838 creds
= PyCredentials_AsCliCredentials(self
);
840 PyErr_SetString(PyExc_RuntimeError
,
841 "Failed to get credentials from python");
845 nc
= creds
->netlogon_creds
;
847 PyErr_SetString(PyExc_ValueError
,
848 "No netlogon credentials cannot make "
849 "client authenticator");
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");
860 ret
= Py_BuildValue("{s"PYARG_BYTES_LEN
"si}",
862 (const char *) &auth
.cred
, sizeof(auth
.cred
),
863 "timestamp", auth
.timestamp
);
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
);
872 PyErr_Format(PyExc_TypeError
, "Credentials expected");
876 if (!PyArg_ParseTuple(args
, "I", &channel_type
))
879 cli_credentials_set_secure_channel_type(
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
);
891 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
,
903 DATA_BLOB data
= data_blob_null
;
904 struct cli_credentials
*creds
= NULL
;
905 struct netr_CryptPassword
*pwd
= NULL
;
907 PyObject
*py_cp
= Py_None
;
909 creds
= PyCredentials_AsCliCredentials(self
);
911 PyErr_Format(PyExc_TypeError
, "Credentials expected");
915 if (!PyArg_ParseTuple(args
, "O", &py_cp
)) {
919 pwd
= pytalloc_get_type(py_cp
, struct netr_CryptPassword
);
921 /* pytalloc_get_type sets TypeError */
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
);
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
);
940 PyErr_Format(PyExc_TypeError
, "Credentials expected");
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
);
956 PyErr_Format(PyExc_TypeError
, "Credentials expected");
959 if (!PyArg_ParseTuple(args
, "i|i", &signing_state
, &obt
)) {
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
:
971 PyErr_Format(PyExc_TypeError
, "Invalid signing state value");
975 cli_credentials_set_smb_signing(creds
, signing_state
, obt
);
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"
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"
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"
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"
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"
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"
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
,
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
,
1272 static struct PyModuleDef moduledef
= {
1273 PyModuleDef_HEAD_INIT
,
1274 .m_name
= "credentials",
1275 .m_doc
= "Credentials management.",
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
;
1291 PyObject
*py_name
= NULL
;
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
);
1299 py_name
= PyString_FromStringOrNULL(name
);
1302 PyErr_SetString(PyExc_RuntimeError
,
1303 "Failed to get ccache 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
)
1324 if (pytalloc_BaseObject_PyType_Ready(&PyCredentials
) < 0)
1327 if (pytalloc_BaseObject_PyType_Ready(&PyCredentialCacheContainer
) < 0)
1330 m
= PyModule_Create(&moduledef
);
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
);