ok. got ntlogin command working. argh, it maintains a connection to
[ira/wip.git] / source3 / rpc_client / cli_login.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NT Domain Authentication SMB / MSRPC client
5    Copyright (C) Andrew Tridgell 1994-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
7    
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.
12    
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.
17    
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.
21 */
22
23 #include "includes.h"
24 #include "nterr.h"
25
26 extern int DEBUGLEVEL;
27
28 /****************************************************************************
29 Initialize domain session credentials.
30 ****************************************************************************/
31
32 uint32 cli_nt_setup_creds( const char* srv_name, const char* myhostname,
33                                 const char* trust_acct,
34                                 unsigned char trust_pwd[16],
35                                 uint16 sec_chan)
36 {
37         DOM_CHAL clnt_chal;
38         DOM_CHAL srv_chal;
39         uint32 ret;
40         UTIME zerotime;
41         uint8 sess_key[16];
42         DOM_CRED clnt_cred;
43
44         /******************* Request Challenge ********************/
45
46         generate_random_buffer( clnt_chal.data, 8, False);
47
48         /* send a client challenge; receive a server challenge */
49         ret = cli_net_req_chal(srv_name, myhostname, &clnt_chal, &srv_chal);
50         if (ret != 0)
51         {
52                 DEBUG(1,("cli_nt_setup_creds: request challenge failed\n"));
53                 return ret;
54         }
55
56         /**************** Long-term Session key **************/
57
58         /* calculate the session key */
59         cred_session_key(&clnt_chal, &srv_chal, (char *)trust_pwd, sess_key);
60         bzero(sess_key+8, 8);
61
62         /******************* Authenticate 2 ********************/
63
64         /* calculate auth-2 credentials */
65         zerotime.time = 0;
66         cred_create(sess_key, &clnt_chal, zerotime, &clnt_cred.challenge);
67
68         if (!cli_con_set_creds(srv_name, sess_key, &clnt_cred))
69         {
70                 return NT_STATUS_ACCESS_DENIED | 0xC0000000;
71         }
72
73         /*  
74          * Send client auth-2 challenge.
75          * Receive an auth-2 challenge response and check it.
76          */
77
78         ret = cli_net_auth2(srv_name, trust_acct, 
79                             sec_chan, 0x000001ff, &srv_chal);
80         if (ret != 0x0)
81         {
82                 DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed.  status: %x\n", ret));
83         }
84
85         return ret;
86 }
87
88 /****************************************************************************
89  Set machine password.
90  ****************************************************************************/
91
92 BOOL cli_nt_srv_pwset(const char* srv_name, const char* myhostname,
93                                 const char* trust_acct,
94                                 unsigned char *new_hashof_trust_pwd,
95                                 uint16 sec_chan)
96 {
97   DEBUG(5,("cli_nt_srv_pwset: %d\n", __LINE__));
98
99 #ifdef DEBUG_PASSWORD
100   dump_data(6, new_hashof_trust_pwd, 16);
101 #endif
102
103   /* send client srv_pwset challenge */
104   return cli_net_srv_pwset(srv_name, myhostname, trust_acct,
105                            new_hashof_trust_pwd, sec_chan);
106 }
107
108 /****************************************************************************
109 NT login - interactive.
110 *NEVER* use this code. This method of doing a logon (sending the cleartext
111 password equivalents, protected by the session key) is inherently insecure
112 given the current design of the NT Domain system. JRA.
113  ****************************************************************************/
114 BOOL cli_nt_login_interactive(const char* srv_name, const char* myhostname,
115                                 const char *domain, const char *username, 
116                                 uint32 luid_low, char *password,
117                                 NET_ID_INFO_CTR *ctr,
118                                 NET_USER_INFO_3 *user_info3)
119 {
120         uchar lm_owf_user_pwd[16];
121         uchar nt_owf_user_pwd[16];
122         BOOL ret;
123         uint8 sess_key[16];
124
125         DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
126
127         nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
128
129 #ifdef DEBUG_PASSWORD
130
131         DEBUG(100,("nt owf of user password: "));
132         dump_data(100, lm_owf_user_pwd, 16);
133
134         DEBUG(100,("nt owf of user password: "));
135         dump_data(100, nt_owf_user_pwd, 16);
136
137 #endif
138
139         if (!cli_get_sesskey_srv(srv_name, sess_key))
140         {
141                 DEBUG(1,("could not obtain session key for %s\n", srv_name));
142                 return False;
143         }
144
145         /* indicate an "interactive" login */
146         ctr->switch_value = INTERACTIVE_LOGON_TYPE;
147
148         /* Create the structure needed for SAM logon. */
149         make_id_info1(&ctr->auth.id1, domain, 0, 
150                                     luid_low, 0,
151                                     username, myhostname,
152                                     (char *)sess_key,
153                                     lm_owf_user_pwd, nt_owf_user_pwd);
154
155         /* Ensure we overwrite all the plaintext password
156         equivalents. */
157         memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd));
158         memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd));
159
160         /* Send client sam-logon request - update credentials on success. */
161         ret = cli_net_sam_logon(srv_name, myhostname, ctr, user_info3);
162
163         memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd));
164         memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd));
165
166         return ret;
167 }
168
169 /****************************************************************************
170 NT login - network.
171 *ALWAYS* use this call to validate a user as it does not expose plaintext
172 password equivalents over the network. JRA.
173 ****************************************************************************/
174
175 BOOL cli_nt_login_network(const char* srv_name, const char* myhostname,
176                                 const char *domain, const char *username, 
177                                 uint32 luid_low, char lm_chal[8],
178                                 char lm_chal_resp[24],
179                                 char nt_chal_resp[24],
180                                 NET_ID_INFO_CTR *ctr,
181                                 NET_USER_INFO_3 *user_info3)
182 {
183         uint8 sess_key[16];
184         BOOL ret;
185         DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
186
187         if (!cli_get_sesskey_srv(srv_name, sess_key))
188         {
189                 DEBUG(1,("could not obtain session key for %s\n", srv_name));
190                 return False;
191         }
192
193         /* indicate a "network" login */
194         ctr->switch_value = NET_LOGON_TYPE;
195
196         /* Create the structure needed for SAM logon. */
197         make_id_info2(&ctr->auth.id2, domain, 0, 
198                 luid_low, 0,
199                 username, myhostname,
200                 (uchar *)lm_chal, (uchar *)lm_chal_resp, (uchar *)nt_chal_resp);
201
202         /* Send client sam-logon request - update credentials on success. */
203         ret = cli_net_sam_logon(srv_name, myhostname, ctr, user_info3);
204
205 #ifdef DEBUG_PASSWORD
206         DEBUG(100,("cli sess key:"));
207         dump_data(100, sess_key, 8);
208         DEBUG(100,("enc user sess key:"));
209         dump_data(100, user_info3->user_sess_key, 16);
210 #endif
211
212         SamOEMhash(user_info3->user_sess_key, sess_key, False);
213
214 #ifdef DEBUG_PASSWORD
215         DEBUG(100,("dec user sess key:"));
216         dump_data(100, user_info3->user_sess_key, 16);
217 #endif
218         return ret;
219 }
220
221 /****************************************************************************
222 NT Logoff.
223 ****************************************************************************/
224 BOOL cli_nt_logoff(const char* srv_name, const char* myhostname,
225                                 NET_ID_INFO_CTR *ctr)
226 {
227   DEBUG(5,("cli_nt_logoff: %d\n", __LINE__));
228
229   /* Send client sam-logoff request - update credentials on success. */
230   return cli_net_sam_logoff(srv_name, myhostname, ctr);
231 }
232
233 /****************************************************************************
234 NT SAM database sync
235 ****************************************************************************/
236 BOOL net_sam_sync(const char* srv_name, const char* myhostname,
237                                 const char* trust_acct,
238                                 uchar trust_passwd[16],
239                                 SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS],
240                                 SAM_DELTA_CTR deltas    [MAX_SAM_DELTAS],
241                                 uint32 *num_deltas)
242 {
243         BOOL res = True;
244
245         *num_deltas = 0;
246
247         DEBUG(5,("Attempting SAM sync with PDC: %s\n",
248                 srv_name));
249
250         res = res ? cli_nt_setup_creds( srv_name, myhostname,
251                                        trust_acct, 
252                                        trust_passwd, SEC_CHAN_BDC) == 0x0 : False;
253
254         memset(trust_passwd, 0, 16);
255
256         res = res ? cli_net_sam_sync(srv_name, myhostname,
257                                      0, num_deltas, hdr_deltas, deltas) : False;
258
259         if (!res)
260         {
261                 DEBUG(5, ("SAM synchronisation FAILED\n"));
262                 return False;
263         }
264
265         DEBUG(5, ("SAM synchronisation returned %d entries\n", *num_deltas));
266
267         return True;
268 }
269