4 Copyright (C) Andrew Tridgell 2001
5 Copyright (C) Andrew Bartlett 2001-2003,2011
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "auth/ntlmssp/ntlmssp.h"
23 #include "ntlmssp_wrap.h"
24 #include "auth/gensec/gensec.h"
25 #include "auth/credentials/credentials.h"
26 #include "librpc/rpc/dcerpc.h"
27 #include "lib/param/param.h"
29 NTSTATUS
auth_ntlmssp_set_username(struct auth_ntlmssp_state
*ans
,
32 cli_credentials_set_username(ans
->credentials
, user
, CRED_SPECIFIED
);
36 NTSTATUS
auth_ntlmssp_set_domain(struct auth_ntlmssp_state
*ans
,
39 cli_credentials_set_domain(ans
->credentials
, domain
, CRED_SPECIFIED
);
43 NTSTATUS
auth_ntlmssp_set_password(struct auth_ntlmssp_state
*ans
,
46 cli_credentials_set_password(ans
->credentials
, password
, CRED_SPECIFIED
);
50 static NTSTATUS
gensec_ntlmssp3_client_update(struct gensec_security
*gensec_security
,
51 TALLOC_CTX
*out_mem_ctx
,
52 struct tevent_context
*ev
,
53 const DATA_BLOB request
,
57 struct gensec_ntlmssp_context
*gensec_ntlmssp
=
58 talloc_get_type_abort(gensec_security
->private_data
,
59 struct gensec_ntlmssp_context
);
61 status
= ntlmssp_update(gensec_ntlmssp
->ntlmssp_state
, request
, reply
);
62 if (NT_STATUS_IS_OK(status
) ||
63 NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
64 talloc_steal(out_mem_ctx
, reply
->data
);
70 static NTSTATUS
gensec_ntlmssp3_client_start(struct gensec_security
*gensec_security
)
73 struct gensec_ntlmssp_context
*gensec_ntlmssp
;
74 const char *user
, *domain
;
77 nt_status
= gensec_ntlmssp_start(gensec_security
);
78 NT_STATUS_NOT_OK_RETURN(nt_status
);
81 talloc_get_type_abort(gensec_security
->private_data
,
82 struct gensec_ntlmssp_context
);
84 nt_status
= ntlmssp_client_start(gensec_ntlmssp
,
85 lp_netbios_name(), lp_workgroup(),
86 lp_client_ntlmv2_auth(), &gensec_ntlmssp
->ntlmssp_state
);
87 if (!NT_STATUS_IS_OK(nt_status
)) {
91 cli_credentials_get_ntlm_username_domain(gensec_security
->credentials
, gensec_ntlmssp
, &user
, &domain
);
92 if (!user
|| !domain
) {
93 return NT_STATUS_NO_MEMORY
;
96 nt_status
= ntlmssp_set_username(gensec_ntlmssp
->ntlmssp_state
, user
);
97 if (!NT_STATUS_IS_OK(nt_status
)) {
101 nt_status
= ntlmssp_set_domain(gensec_ntlmssp
->ntlmssp_state
, domain
);
102 if (!NT_STATUS_IS_OK(nt_status
)) {
106 password
= cli_credentials_get_password(gensec_security
->credentials
);
108 return NT_STATUS_NO_MEMORY
;
111 nt_status
= ntlmssp_set_password(gensec_ntlmssp
->ntlmssp_state
, password
);
112 if (!NT_STATUS_IS_OK(nt_status
)) {
116 if (gensec_ntlmssp
->gensec_security
->want_features
& GENSEC_FEATURE_SESSION_KEY
) {
117 gensec_ntlmssp
->ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
119 if (gensec_ntlmssp
->gensec_security
->want_features
& GENSEC_FEATURE_SIGN
) {
120 gensec_ntlmssp
->ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
122 if (gensec_ntlmssp
->gensec_security
->want_features
& GENSEC_FEATURE_SEAL
) {
123 gensec_ntlmssp
->ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
124 gensec_ntlmssp
->ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SEAL
;
130 static const char *gensec_ntlmssp3_client_oids
[] = {
135 static const struct gensec_security_ops gensec_ntlmssp3_client_ops
= {
136 .name
= "ntlmssp3_client",
137 .sasl_name
= GENSEC_SASL_NAME_NTLMSSP
, /* "NTLM" */
138 .auth_type
= DCERPC_AUTH_TYPE_NTLMSSP
,
139 .oid
= gensec_ntlmssp3_client_oids
,
140 .client_start
= gensec_ntlmssp3_client_start
,
141 .magic
= gensec_ntlmssp_magic
,
142 .update
= gensec_ntlmssp3_client_update
,
143 .sig_size
= gensec_ntlmssp_sig_size
,
144 .sign_packet
= gensec_ntlmssp_sign_packet
,
145 .check_packet
= gensec_ntlmssp_check_packet
,
146 .seal_packet
= gensec_ntlmssp_seal_packet
,
147 .unseal_packet
= gensec_ntlmssp_unseal_packet
,
148 .wrap
= gensec_ntlmssp_wrap
,
149 .unwrap
= gensec_ntlmssp_unwrap
,
150 .session_key
= gensec_ntlmssp_session_key
,
151 .have_feature
= gensec_ntlmssp_have_feature
,
153 .priority
= GENSEC_NTLMSSP
156 NTSTATUS
auth_ntlmssp_client_prepare(TALLOC_CTX
*mem_ctx
, struct auth_ntlmssp_state
**auth_ntlmssp_state
)
158 struct auth_ntlmssp_state
*ans
;
161 struct gensec_settings
*gensec_settings
;
162 struct loadparm_context
*lp_ctx
;
164 ans
= talloc_zero(mem_ctx
, struct auth_ntlmssp_state
);
166 DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
167 return NT_STATUS_NO_MEMORY
;
170 lp_ctx
= loadparm_init_s3(ans
, loadparm_s3_context());
171 if (lp_ctx
== NULL
) {
172 DEBUG(10, ("loadparm_init_s3 failed\n"));
174 return NT_STATUS_INVALID_SERVER_STATE
;
177 gensec_settings
= lpcfg_gensec_settings(ans
, lp_ctx
);
178 if (lp_ctx
== NULL
) {
179 DEBUG(10, ("lpcfg_gensec_settings failed\n"));
181 return NT_STATUS_NO_MEMORY
;
184 nt_status
= gensec_client_start(ans
, &ans
->gensec_security
, gensec_settings
);
186 if (!NT_STATUS_IS_OK(nt_status
)) {
191 ans
->credentials
= cli_credentials_init(ans
);
192 if (!ans
->credentials
) {
194 return NT_STATUS_NO_MEMORY
;
197 cli_credentials_guess(ans
->credentials
, lp_ctx
);
199 talloc_unlink(ans
, lp_ctx
);
200 talloc_unlink(ans
, gensec_settings
);
202 *auth_ntlmssp_state
= ans
;
206 NTSTATUS
auth_ntlmssp_client_start(struct auth_ntlmssp_state
*ans
)
210 /* Transfer the credentials to gensec */
211 status
= gensec_set_credentials(ans
->gensec_security
, ans
->credentials
);
212 if (!NT_STATUS_IS_OK(status
)) {
213 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
217 talloc_unlink(ans
, ans
->credentials
);
218 ans
->credentials
= NULL
;
220 status
= gensec_start_mech_by_ops(ans
->gensec_security
,
221 &gensec_ntlmssp3_client_ops
);
222 if (!NT_STATUS_IS_OK(status
)) {