cool! a unix socket smb redirector. code based on smbfilter and
[kai/samba.git] / source3 / libsmb / pwd_cache.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Password cacheing.  obfuscation is planned
5    Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6    
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 2 of the License, or
10    (at your option) any later version.
11    
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.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26
27 /****************************************************************************
28 initialises a password structure
29 ****************************************************************************/
30 void pwd_init(struct pwd_info *pwd)
31 {
32         ZERO_STRUCT(pwd->password  );
33         ZERO_STRUCT(pwd->smb_lm_pwd);
34         ZERO_STRUCT(pwd->smb_nt_pwd);
35         ZERO_STRUCT(pwd->smb_lm_owf);
36         ZERO_STRUCT(pwd->smb_nt_owf);
37         ZERO_STRUCT(pwd->sess_key  );
38         pwd->nt_owf_len = 0;
39
40         pwd->null_pwd  = True; /* safest option... */
41         pwd->cleartext = False;
42         pwd->crypted   = False;
43 }
44
45 /****************************************************************************
46 returns NULL password flag
47 ****************************************************************************/
48 BOOL pwd_is_nullpwd(const struct pwd_info *pwd)
49 {
50         return pwd->null_pwd;
51 }
52
53 /****************************************************************************
54 de-obfuscates a password
55 ****************************************************************************/
56 static void pwd_deobfuscate(const struct pwd_info *pwd)
57 {
58 }
59
60 /****************************************************************************
61 obfuscates a password
62 ****************************************************************************/
63 static void pwd_obfuscate(const struct pwd_info *pwd)
64 {
65 }
66
67 /****************************************************************************
68 sets the obfuscation key info
69 ****************************************************************************/
70 void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key)
71 {
72 }
73
74 /****************************************************************************
75 compares two passwords.  hmm, not as trivial as expected.  hmm.
76 ****************************************************************************/
77 BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2)
78 {
79         pwd_deobfuscate(pwd1);
80         pwd_deobfuscate(pwd2);
81         if (pwd1->cleartext && pwd2->cleartext)
82         {
83                 if (strequal(pwd1->password, pwd2->password))
84                 {
85                         pwd_obfuscate(pwd1);
86                         pwd_obfuscate(pwd2);
87                         return True;
88                 }
89         }
90         if (pwd1->null_pwd && pwd2->null_pwd)
91         {
92                 pwd_obfuscate(pwd1);
93                 pwd_obfuscate(pwd2);
94                 return True;
95         }
96
97         if (!pwd1->null_pwd  && !pwd2->null_pwd &&
98             !pwd1->cleartext && !pwd2->cleartext)
99         {
100                 if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
101                 {
102                         pwd_obfuscate(pwd1);
103                         pwd_obfuscate(pwd2);
104                         return True;
105                 }
106                 if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
107                 {
108                         pwd_obfuscate(pwd1);
109                         pwd_obfuscate(pwd2);
110                         return True;
111                 }
112         }
113         pwd_obfuscate(pwd1);
114         pwd_obfuscate(pwd2);
115         return False;
116 }
117 /****************************************************************************
118 reads a password
119 ****************************************************************************/
120 void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt)
121 {
122         /* grab a password */
123         char *user_pass;
124
125         pwd_init(pwd);
126
127         user_pass = (char*)getpass(passwd_report);
128
129         if (user_pass == NULL || user_pass[0] == 0)
130         {
131                 pwd_set_nullpwd(pwd);
132         }
133         else if (do_encrypt)
134         {
135                 pwd_make_lm_nt_16(pwd, user_pass);
136         }
137         else
138         {
139                 pwd_set_cleartext(pwd, user_pass);
140         }
141 }
142
143 /****************************************************************************
144  stores a cleartext password
145  ****************************************************************************/
146 void pwd_set_nullpwd(struct pwd_info *pwd)
147 {
148         pwd_init(pwd);
149
150         pwd->cleartext = False;
151         pwd->null_pwd  = True;
152         pwd->crypted   = False;
153 }
154
155 /****************************************************************************
156  stores a cleartext password
157  ****************************************************************************/
158 void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
159 {
160         pwd_init(pwd);
161         fstrcpy(pwd->password, clr);
162         pwd->cleartext = True;
163         pwd->null_pwd  = False;
164         pwd->crypted   = False;
165
166         pwd_obfuscate(pwd);
167 }
168
169 /****************************************************************************
170  gets a cleartext password
171  ****************************************************************************/
172 void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
173 {
174         pwd_deobfuscate(pwd);
175         if (pwd->cleartext)
176         {
177                 fstrcpy(clr, pwd->password);
178         }
179         else
180         {
181                 clr[0] = 0;
182         }
183         pwd_obfuscate(pwd);
184 }
185
186 /****************************************************************************
187  stores lm and nt hashed passwords
188  ****************************************************************************/
189 void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
190 {
191         pwd_init(pwd);
192
193         if (lm_pwd)
194         {
195                 memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
196         }
197         else
198         {
199                 bzero(pwd->smb_lm_pwd, 16);
200         }
201
202         if (nt_pwd)
203         {
204                 memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
205         }
206         else
207         {
208                 bzero(pwd->smb_nt_pwd, 16);
209         }
210
211         pwd->null_pwd  = False;
212         pwd->cleartext = False;
213         pwd->crypted   = False;
214
215         pwd_obfuscate(pwd);
216 }
217
218 /****************************************************************************
219  gets lm and nt hashed passwords
220  ****************************************************************************/
221 void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
222 {
223         pwd_deobfuscate(pwd);
224         if (lm_pwd != NULL)
225         {
226                 memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
227         }
228         if (nt_pwd != NULL)
229         {
230                 memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
231         }
232         pwd_obfuscate(pwd);
233 }
234
235 /****************************************************************************
236  makes lm and nt hashed passwords
237  ****************************************************************************/
238 void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
239 {
240         pwd_init(pwd);
241
242         nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
243         pwd->null_pwd  = False;
244         pwd->cleartext = False;
245         pwd->crypted = False;
246
247         pwd_obfuscate(pwd);
248 }
249
250 /****************************************************************************
251  makes lm and nt OWF crypts
252  ****************************************************************************/
253 void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
254                 const char *user, const char *server, const char *domain)
255 {
256         uchar kr[16];
257
258         DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
259                 user, server, domain));
260
261         pwd_deobfuscate(pwd);
262
263         SMBgenclientchals(pwd->lm_cli_chal,
264                           pwd->nt_cli_chal,
265                           &pwd->nt_cli_chal_len,
266                           server, domain);
267         
268         ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);
269
270         /* lm # */
271         SMBOWFencrypt_ntv2(kr,
272                            srv_key, 8,
273                            pwd->lm_cli_chal, 8,
274                            pwd->smb_lm_owf);
275         memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);
276
277         /* nt # */
278         SMBOWFencrypt_ntv2(kr,
279                        srv_key, 8,
280                        pwd->nt_cli_chal, pwd->nt_cli_chal_len,
281                        pwd->smb_nt_owf);
282         memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
283         pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;
284
285         SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, pwd->sess_key);
286
287 #if DEBUG_PASSWORD
288 #endif
289
290 #ifdef DEBUG_PASSWORD
291         DEBUG(100,("server cryptkey: "));
292         dump_data(100, srv_key, 8);
293
294         DEBUG(100,("client lmv2 cryptkey: "));
295         dump_data(100, pwd->lm_cli_chal, 8);
296
297         DEBUG(100,("client ntv2 cryptkey: "));
298         dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len);
299
300         DEBUG(100,("ntv2_owf_passwd: "));
301         dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
302         DEBUG(100,("nt_sess_pwd: "));
303         dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
304
305         DEBUG(100,("lmv2_owf_passwd: "));
306         dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
307         DEBUG(100,("lm_sess_pwd: "));
308         dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
309
310         DEBUG(100,("session key:\n"));
311         dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
312 #endif
313         pwd->crypted = True;
314
315         pwd_obfuscate(pwd);
316 }
317
318 /****************************************************************************
319  makes lm and nt OWF crypts
320  ****************************************************************************/
321 void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
322 {
323         if (pwd->null_pwd)
324         {
325 #ifdef DEBUG_PASSWORD
326                 DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n"));
327 #endif
328                 pwd->nt_owf_len = 0;
329                 return;
330         }
331         pwd_deobfuscate(pwd);
332
333         /* generate 24-byte hashes */
334         SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
335         SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
336         pwd->nt_owf_len = 24;
337
338         SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, pwd->sess_key);
339
340 #ifdef DEBUG_PASSWORD
341         DEBUG(100,("client cryptkey: "));
342         dump_data(100, cryptkey, 8);
343
344         DEBUG(100,("nt_owf_passwd: "));
345         dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
346         DEBUG(100,("nt_sess_pwd: "));
347         dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
348
349         DEBUG(100,("lm_owf_passwd: "));
350         dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
351         DEBUG(100,("lm_sess_pwd: "));
352         dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
353
354         DEBUG(100,("session key:\n"));
355         dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
356 #endif
357
358         pwd->crypted = True;
359
360         pwd_obfuscate(pwd);
361 }
362
363 /****************************************************************************
364  gets lm and nt crypts
365  ****************************************************************************/
366 void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
367                                 uchar *nt_owf, size_t *nt_owf_len,
368                                 uchar *sess_key)
369 {
370         if (pwd->null_pwd)
371         {
372 #ifdef DEBUG_PASSWORD
373                 DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n"));
374 #endif
375                 if (nt_owf_len != NULL)
376                 {
377                         *nt_owf_len = 0;
378                 }
379                 return;
380         }
381                 
382         pwd_deobfuscate(pwd);
383         if (lm_owf != NULL)
384         {
385                 memcpy(lm_owf, pwd->smb_lm_owf, 24);
386         }
387         if (nt_owf != NULL)
388         {
389                 memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
390         }
391         if (sess_key != NULL)
392         {
393                 memcpy(sess_key, pwd->sess_key, 16);
394         }
395         if (nt_owf_len != NULL)
396         {
397                 *nt_owf_len = pwd->nt_owf_len;
398         }
399         pwd_obfuscate(pwd);
400 }
401