2 Unix SMB/Netbios implementation.
4 NT Domain Authentication SMB / MSRPC client
5 Copyright (C) Andrew Tridgell 1994-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "rpc_parse.h"
25 #include "rpc_client.h"
28 extern int DEBUGLEVEL
;
30 /****************************************************************************
31 Initialize domain session credentials.
32 ****************************************************************************/
34 uint32
cli_nt_setup_creds(const char *srv_name
,
36 const char *cli_hostname
,
37 const char *trust_acct
,
38 const uchar trust_pwd
[16], uint16 sec_chan
,
39 uint16
* validation_level
)
47 uint32 neg_flags
= !lp_client_schannel()? 0x000001ff : 0x400001ff;
49 /******************* Request Challenge ********************/
51 generate_random_buffer(clnt_chal
.data
, 8, False
);
53 /* send a client challenge; receive a server challenge */
55 cli_net_req_chal(srv_name
, cli_hostname
, &clnt_chal
, &srv_chal
);
58 DEBUG(1, ("cli_nt_setup_creds: request challenge failed\n"));
62 /**************** Long-term Session key **************/
64 /* calculate the session key */
65 cred_session_key(&clnt_chal
, &srv_chal
, trust_pwd
, sess_key
);
66 memset(sess_key
+ 8, 0, 8);
68 /******************* Authenticate 2 ********************/
70 /* calculate auth-2 credentials */
72 cred_create(sess_key
, &clnt_chal
, zerotime
, &clnt_cred
.challenge
);
74 if (!cli_con_set_creds(srv_name
, sess_key
, &clnt_cred
))
76 return NT_STATUS_ACCESS_DENIED
| 0xC0000000;
80 * Send client auth-2 challenge.
81 * Receive an auth-2 challenge response and check it.
83 status
= cli_net_auth2(srv_name
, trust_acct
, cli_hostname
,
84 sec_chan
, &neg_flags
, &srv_chal
);
88 ("cli_nt_setup_creds: auth2 challenge failed. status: %x\n",
92 /* check the client secure channel status */
94 lp_client_schannel() == True
&&
95 IS_BITS_CLR_ALL(neg_flags
, 0x40000000))
97 /* netlogon secure channel was required, and not negotiated */
98 return NT_STATUS_ACCESS_DENIED
| 0xC0000000;
101 if (status
== 0x0 && IS_BITS_SET_ALL(neg_flags
, 0x40000000))
103 extern cli_auth_fns cli_netsec_fns
;
104 struct cli_connection
*con
= NULL
;
105 struct netsec_creds creds
;
107 safe_strcpy(creds
.domain
, domain
, sizeof(creds
.myname
) - 1);
108 safe_strcpy(creds
.myname
, cli_hostname
,
109 sizeof(creds
.myname
) - 1);
110 memcpy(creds
.sess_key
, sess_key
, sizeof(creds
.sess_key
));
112 if (!cli_connection_init_auth(srv_name
, PIPE_NETLOGON
, &con
,
116 return NT_STATUS_ACCESS_DENIED
| 0xC0000000;
118 if (!cli_con_set_creds(srv_name
, sess_key
, &clnt_cred
))
120 cli_connection_free(con
);
121 return NT_STATUS_ACCESS_DENIED
| 0xC0000000;
125 if (IS_BITS_SET_ALL(neg_flags
, 0x40))
127 (*validation_level
) = 3;
131 (*validation_level
) = 2;
137 /****************************************************************************
138 Set machine password.
139 ****************************************************************************/
141 BOOL
cli_nt_srv_pwset(const char *srv_name
, const char *cli_hostname
,
142 const char *trust_acct
,
143 const uchar
* new_hashof_trust_pwd
, uint16 sec_chan
)
145 DEBUG(5, ("cli_nt_srv_pwset: %d\n", __LINE__
));
147 #ifdef DEBUG_PASSWORD
148 dump_data(6, new_hashof_trust_pwd
, 16);
151 /* send client srv_pwset challenge */
152 return cli_net_srv_pwset(srv_name
, cli_hostname
, trust_acct
,
153 new_hashof_trust_pwd
, sec_chan
);
156 /****************************************************************************
158 *NEVER* use this code. This method of doing a logon (sending the cleartext
159 password equivalents, protected by the session key) is inherently insecure
160 given the current design of the NT Domain system. JRA.
161 ****************************************************************************/
162 BOOL
cli_nt_login_general(const char *srv_name
, const char *cli_hostname
,
163 const char *domain
, const char *username
,
166 NET_ID_INFO_CTR
* ctr
,
167 uint16 validation_level
,
168 NET_USER_INFO_3
* user_info3
)
171 NET_USER_INFO_CTR user_ctr
;
173 ZERO_STRUCT(user_ctr
);
174 user_ctr
.switch_value
= validation_level
;
176 DEBUG(5, ("cli_nt_login_general: %d\n", __LINE__
));
178 #ifdef DEBUG_PASSWORD
180 DEBUG(100, ("\"general\" user password: "));
181 dump_data(100, general
, strlen(general
));
184 if (!cli_get_sesskey_srv(srv_name
, sess_key
))
186 DEBUG(1, ("could not obtain session key for %s\n", srv_name
));
187 return NT_STATUS_ACCESS_DENIED
;
190 /* indicate an "general" login */
191 ctr
->switch_value
= GENERAL_LOGON_TYPE
;
193 /* Create the structure needed for SAM logon. */
194 make_id_info4(&ctr
->auth
.id4
, domain
, 0,
195 luid_low
, 0, username
, cli_hostname
, general
);
197 /* Send client sam-logon request - update credentials on success. */
198 status
= cli_net_sam_logon(srv_name
, cli_hostname
, ctr
, &user_ctr
);
199 if (!net_user_info_3_copy_from_ctr(user_info3
, &user_ctr
))
201 status
= NT_STATUS_INVALID_PARAMETER
;
203 free_net_user_info_ctr(&user_ctr
);
207 /****************************************************************************
208 NT login - interactive.
209 *NEVER* use this code. This method of doing a logon (sending the cleartext
210 password equivalents, protected by the session key) is inherently insecure
211 given the current design of the NT Domain system. JRA.
212 ****************************************************************************/
213 uint32
cli_nt_login_interactive(const char *srv_name
, const char *cli_hostname
,
214 const char *domain
, const char *username
,
216 const uchar
* lm_owf_user_pwd
,
217 const uchar
* nt_owf_user_pwd
,
218 NET_ID_INFO_CTR
* ctr
,
219 uint16 validation_level
,
220 NET_USER_INFO_3
* user_info3
)
224 NET_USER_INFO_CTR user_ctr
;
225 ZERO_STRUCT(user_ctr
);
226 user_ctr
.switch_value
= validation_level
;
228 DEBUG(5, ("cli_nt_login_interactive: %d\n", __LINE__
));
230 dump_data_pw("nt owf of user password:\n", lm_owf_user_pwd
, 16);
231 dump_data_pw("nt owf of user password:\n", nt_owf_user_pwd
, 16);
233 if (!cli_get_sesskey_srv(srv_name
, sess_key
))
235 DEBUG(1, ("could not obtain session key for %s\n", srv_name
));
236 return NT_STATUS_ACCESS_DENIED
;
239 /* indicate an "interactive" login */
240 ctr
->switch_value
= INTERACTIVE_LOGON_TYPE
;
242 /* Create the structure needed for SAM logon. */
243 make_id_info1(&ctr
->auth
.id1
, domain
, 0,
245 username
, cli_hostname
,
246 (char *)sess_key
, lm_owf_user_pwd
, nt_owf_user_pwd
);
248 /* Send client sam-logon request - update credentials on success. */
249 status
= cli_net_sam_logon(srv_name
, cli_hostname
, ctr
, &user_ctr
);
250 if (!net_user_info_3_copy_from_ctr(user_info3
, &user_ctr
))
252 status
= NT_STATUS_INVALID_PARAMETER
;
254 free_net_user_info_ctr(&user_ctr
);
256 memset(ctr
->auth
.id1
.lm_owf
.data
, '\0',
257 sizeof(ctr
->auth
.id1
.lm_owf
.data
));
258 memset(ctr
->auth
.id1
.nt_owf
.data
, '\0',
259 sizeof(ctr
->auth
.id1
.nt_owf
.data
));
264 /****************************************************************************
266 *ALWAYS* use this call to validate a user as it does not expose plaintext
267 password equivalents over the network. JRA.
268 ****************************************************************************/
270 uint32
cli_nt_login_network(const char *srv_name
, const char *cli_hostname
,
271 const char *domain
, const char *username
,
272 uint32 luid_low
, const char lm_chal
[8],
273 const char *lm_chal_resp
,
275 const char *nt_chal_resp
,
277 NET_ID_INFO_CTR
* ctr
,
278 uint16 validation_level
,
279 NET_USER_INFO_3
* user_info3
)
283 NET_USER_INFO_CTR user_ctr
;
284 ZERO_STRUCT(user_ctr
);
285 user_ctr
.switch_value
= validation_level
;
287 DEBUG(5, ("cli_nt_login_network: %d\n", __LINE__
));
289 if (!cli_get_sesskey_srv(srv_name
, sess_key
))
291 DEBUG(1, ("could not obtain session key for %s\n", srv_name
));
292 return NT_STATUS_ACCESS_DENIED
;
295 /* indicate a "network" login */
296 ctr
->switch_value
= NETWORK_LOGON_TYPE
;
298 /* Create the structure needed for SAM logon. */
299 make_id_info2(&ctr
->auth
.id2
, domain
, 0,
301 username
, cli_hostname
,
303 lm_chal_resp
, lm_chal_len
, nt_chal_resp
, nt_chal_len
);
305 /* Send client sam-logon request - update credentials on success. */
306 status
= cli_net_sam_logon(srv_name
, cli_hostname
, ctr
, &user_ctr
);
308 if (!net_user_info_3_copy_from_ctr(user_info3
, &user_ctr
))
310 status
= NT_STATUS_INVALID_PARAMETER
;
312 free_net_user_info_ctr(&user_ctr
);
314 dump_data_pw("cli sess key:", sess_key
, 8);
315 dump_data_pw("enc padding:", user_info3
->padding
, 8);
316 dump_data_pw("enc user sess key:", user_info3
->user_sess_key
, 16);
318 SamOEMhash(user_info3
->user_sess_key
, sess_key
, 0);
319 SamOEMhash(user_info3
->padding
, sess_key
, 3);
321 dump_data_pw("dec padding:", user_info3
->padding
, 8);
322 dump_data_pw("dec user sess key:", user_info3
->user_sess_key
, 16);
327 /****************************************************************************
329 ****************************************************************************/
330 BOOL
cli_nt_logoff(const char *srv_name
, const char *cli_hostname
,
331 NET_ID_INFO_CTR
* ctr
)
333 DEBUG(5, ("cli_nt_logoff: %d\n", __LINE__
));
335 /* Send client sam-logoff request - update credentials on success. */
336 return cli_net_sam_logoff(srv_name
, cli_hostname
, ctr
);
339 /****************************************************************************
341 ****************************************************************************/
342 BOOL
net_sam_sync(const char *srv_name
,
344 const char *cli_hostname
,
345 const char *trust_acct
,
346 uchar trust_passwd
[16],
347 SAM_DELTA_HDR hdr_deltas
[MAX_SAM_DELTAS
],
348 SAM_DELTA_CTR deltas
[MAX_SAM_DELTAS
], uint32
* num_deltas
)
351 uint16 validation_level
;
355 DEBUG(5, ("Attempting SAM sync with PDC: %s\n", srv_name
));
357 res
= res
? cli_nt_setup_creds(srv_name
, domain
, cli_hostname
,
361 &validation_level
) == 0x0 : False
;
363 memset(trust_passwd
, 0, 16);
365 res
= res
? cli_net_sam_sync(srv_name
, cli_hostname
,
366 0, num_deltas
, hdr_deltas
,
371 DEBUG(5, ("SAM synchronisation FAILED\n"));
375 DEBUG(5, ("SAM synchronisation returned %d entries\n", *num_deltas
));