7d1185d9a7d53ebb441da9457762f13907804743
[kai/samba.git] / source3 / libsmb / pwd_cache.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Password cacheing.  obfuscation is planned
4    Copyright (C) Luke Kenneth Casson Leighton 1996-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 /****************************************************************************
24  Initialises a password structure.
25 ****************************************************************************/
26
27 void pwd_init(struct pwd_info *pwd)
28 {
29         memset((char *)pwd->password  , '\0', sizeof(pwd->password  ));
30         memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd));
31         memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd));
32         memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf));
33         memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf));
34
35         pwd->null_pwd  = True; /* safest option... */
36         pwd->cleartext = False;
37         pwd->crypted   = False;
38 }
39
40 /****************************************************************************
41  Returns NULL password flag.
42 ****************************************************************************/
43
44 BOOL pwd_is_nullpwd(const struct pwd_info *pwd)
45 {
46         return pwd->null_pwd;
47 }
48
49 /****************************************************************************
50  Compares two passwords.  hmm, not as trivial as expected.  hmm.
51 ****************************************************************************/
52
53 BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2)
54 {
55         if (pwd1->cleartext && pwd2->cleartext) {
56                 if (strequal(pwd1->password, pwd2->password))
57                         return True;
58         }
59         if (pwd1->null_pwd && pwd2->null_pwd)
60                 return True;
61
62         if (!pwd1->null_pwd  && !pwd2->null_pwd &&
63             !pwd1->cleartext && !pwd2->cleartext) {
64 #ifdef DEBUG_PASSWORD
65                 DEBUG(100,("pwd compare: nt#\n"));
66                 dump_data(100, pwd1->smb_nt_pwd, 16);
67                 dump_data(100, pwd2->smb_nt_pwd, 16);
68 #endif
69                 if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
70                         return True;
71 #ifdef DEBUG_PASSWORD
72                 DEBUG(100,("pwd compare: lm#\n"));
73                 dump_data(100, pwd1->smb_lm_pwd, 16);
74                 dump_data(100, pwd2->smb_lm_pwd, 16);
75 #endif
76                 if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
77                         return True;
78         }
79         return False;
80 }
81
82 /****************************************************************************
83  Reads a password.
84 ****************************************************************************/
85
86 void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt)
87 {
88         /* grab a password */
89         char *user_pass;
90
91         pwd_init(pwd);
92
93         user_pass = (char*)getpass(passwd_report);
94
95         /*
96          * Do not assume that an empty string is a NULL password.
97          * If you do this will break the session key generation for
98          * and account with an emtpy password.  If you wish to use
99          * a NULL password, use the -N option to smbclient and rpcclient
100          * --jerry
101          */
102 #if 0
103         if (user_pass == NULL || user_pass[0] == 0)
104                 pwd_set_nullpwd(pwd);
105         else if (do_encrypt)
106 #endif
107         if (do_encrypt)
108                 pwd_make_lm_nt_16(pwd, user_pass);
109         else
110                 pwd_set_cleartext(pwd, user_pass);
111 }
112
113 /****************************************************************************
114  Stores a cleartext password.
115 ****************************************************************************/
116
117 void pwd_set_nullpwd(struct pwd_info *pwd)
118 {
119         pwd_init(pwd);
120
121         pwd->cleartext = False;
122         pwd->null_pwd  = True;
123         pwd->crypted   = False;
124 }
125
126 /****************************************************************************
127  Stores a cleartext password.
128 ****************************************************************************/
129
130 void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
131 {
132         pwd_init(pwd);
133         push_ascii_fstring(pwd->password, clr);
134         pwd->cleartext = True;
135         pwd->null_pwd  = False;
136         pwd->crypted   = False;
137         pwd_make_lm_nt_16(pwd, clr);
138 }
139
140 /****************************************************************************
141  Gets a cleartext password.
142 ****************************************************************************/
143
144 void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
145 {
146         if (pwd->cleartext)
147                 fstrcpy(clr, pwd->password);
148         else
149                 clr[0] = 0;
150
151 }
152
153 /****************************************************************************
154  Stores lm and nt hashed passwords.
155 ****************************************************************************/
156
157 void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
158 {
159         pwd_init(pwd);
160
161         if (lm_pwd)
162                 memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
163         else
164                 memset((char *)pwd->smb_lm_pwd, '\0', 16);
165
166         if (nt_pwd)
167                 memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
168         else
169                 memset((char *)pwd->smb_nt_pwd, '\0', 16);
170
171         pwd->null_pwd  = False;
172         pwd->cleartext = False;
173         pwd->crypted   = False;
174 }
175
176 /****************************************************************************
177  Gets lm and nt hashed passwords.
178 ****************************************************************************/
179
180 void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
181 {
182         if (lm_pwd != NULL)
183                 memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
184         if (nt_pwd != NULL)
185                 memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
186 }
187
188 /****************************************************************************
189  Makes lm and nt hashed passwords.
190 ****************************************************************************/
191
192 void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
193 {
194         pstring dos_passwd;
195
196         pwd_init(pwd);
197
198         push_ascii_pstring(dos_passwd, clr);
199
200         nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
201         pwd->null_pwd  = False;
202         pwd->cleartext = False;
203         pwd->crypted = False;
204 }
205
206 /****************************************************************************
207  Makes lm and nt OWF crypts.
208 ****************************************************************************/
209
210 void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
211 {
212
213 #ifdef DEBUG_PASSWORD
214         DEBUG(100,("client cryptkey: "));
215         dump_data(100, (char *)cryptkey, 8);
216 #endif
217
218         SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
219
220 #ifdef DEBUG_PASSWORD
221         DEBUG(100,("nt_owf_passwd: "));
222         dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf));
223         DEBUG(100,("nt_sess_pwd: "));
224         dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
225 #endif
226
227         SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
228
229 #ifdef DEBUG_PASSWORD
230         DEBUG(100,("lm_owf_passwd: "));
231         dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
232         DEBUG(100,("lm_sess_pwd: "));
233         dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
234 #endif
235
236         pwd->crypted = True;
237 }
238
239 /****************************************************************************
240  Gets lm and nt crypts.
241 ****************************************************************************/
242
243 void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
244 {
245         if (lm_owf != NULL)
246                 memcpy(lm_owf, pwd->smb_lm_owf, 24);
247         if (nt_owf != NULL)
248                 memcpy(nt_owf, pwd->smb_nt_owf, 24);
249 }