2
* (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
3
* Distributed freely under the terms of the GNU General Public License,
4
* version 2. See the file COPYING for licensing details
6
* This program is distributed in the hope that it will be useful,
7
* but WITHOUT ANY WARRANTY; without even the implied warranty of
8
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
* GNU General Public License for more details.
11
* You should have received a copy of the GNU General Public License
12
* along with this program; if not, write to the Free Software
13
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
18
#include "util.h" /* from Squid */
23
#endif /* HAVE_STRING_H */
26
#endif /* HAVE_STDLIB_H */
31
#include "smblib-priv.h" /* for SMB_Handle_Type */
33
/* a few forward-declarations. Hackish, but I don't care right now */
34
SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle,
35
char *server, char *NTdomain);
37
/* this one is reallllly haackiish. We really should be using anything from smblib-priv.h
39
static char *SMB_Prots[] =
40
{"PC NETWORK PROGRAM 1.0",
41
"MICROSOFT NETWORKS 1.03",
42
"MICROSOFT NETWORKS 3.0",
55
int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle);
56
int SMB_Negotiate(void *Con_Handle, char *Prots[]);
57
int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName,
58
char *PassWord, char *Domain, int precrypted);
62
#define debug_dump_ntlmssp_flags dump_ntlmssp_flags
64
#define debug_dump_ntlmssp_flags(X) /* empty */
68
static char challenge[NONCE_LEN];
69
SMB_Handle_Type handle = NULL;
71
/* Disconnects from the DC. A reconnection will be done upon the next request
77
SMB_Discon(handle, 0);
84
return (handle != NULL);
88
/* Tries to connect to a DC. Returns 0 on failure, 1 on OK */
90
is_dc_ok(char *domain,
91
char *domain_controller)
93
SMB_Handle_Type h = SMB_Connect_Server(NULL, domain_controller, domain);
101
/* returns 0 on success, > 0 on failure */
103
init_challenge(char *domain, char *domain_controller)
108
if (handle != NULL) {
111
debug("Connecting to server %s domain %s\n", domain_controller, domain);
112
handle = SMB_Connect_Server(NULL, domain_controller, domain);
113
smberr = SMB_Get_Last_Error();
114
SMB_Get_Error_Msg(smberr, errstr, 100);
117
if (handle == NULL) { /* couldn't connect */
118
debug("Couldn't connect to SMB Server. Error:%s\n", errstr);
121
if (SMB_Negotiate(handle, SMB_Prots) < 0) { /* An error */
122
debug("Error negotiating protocol with SMB Server\n");
123
SMB_Discon(handle, 0);
127
if (handle->Security == 0) { /* share-level security, unuseable */
128
debug("SMB Server uses share-level security .. we need user sercurity.\n");
129
SMB_Discon(handle, 0);
133
memcpy(challenge, handle->Encrypt_Key, NONCE_LEN);
138
make_challenge(char *domain, char *domain_controller)
140
if (init_challenge(domain, domain_controller) > 0)
142
return ntlm_make_challenge(domain, domain_controller, challenge,
146
#define min(A,B) (A<B?A:B)
147
/* returns NULL on failure, or a pointer to
148
* the user's credentials (domain\\username)
149
* upon success. WARNING. It's pointing to static storage.
150
* In case of problem sets as side-effect ntlm_errno to one of the
151
* codes defined in ntlm.h
154
static char credentials[1024]; /* we can afford to waste */
156
ntlm_check_auth(ntlm_authenticate * auth, int auth_length)
160
char *domain = credentials;
164
if (handle == NULL) { /*if null we aren't connected, but it shouldn't happen */
165
debug("Weird, we've been disconnected\n");
166
ntlm_errno = NTLM_NOT_CONNECTED;
169
/* Authenticating against the NT response doesn't seem to work... */
170
tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->lmresponse);
171
if (tmp.str == NULL) {
172
fprintf(stderr, "No auth at all. Returning no-auth\n");
173
ntlm_errno = NTLM_LOGON_ERROR;
176
memcpy(pass, tmp.str, tmp.l);
179
/* debug("fetching domain\n"); */
180
tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->domain);
181
if (tmp.str == NULL) {
182
debug("No domain supplied. Returning no-auth\n");
183
ntlm_errno = NTLM_LOGON_ERROR;
186
memcpy(domain, tmp.str, tmp.l);
187
user = domain + tmp.l;
190
/* debug("fetching user name\n"); */
191
tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->user);
192
if (tmp.str == NULL) {
193
debug("No username supplied. Returning no-auth\n");
194
ntlm_errno = NTLM_LOGON_ERROR;
197
memcpy(user, tmp.str, tmp.l);
198
*(user + tmp.l) = '\0';
200
debug("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass);
202
rv = SMB_Logon_Server(handle, user, pass, domain, 1);
204
while ((rv == NTLM_BAD_PROTOCOL || rv == NTLM_SERVER_ERROR)
205
&& retries < BAD_DC_RETRIES_NUMBER) {
207
usleep((unsigned long) 100000);
208
rv = SMB_Logon_Server(handle, user, pass, domain, 1);
211
debug("\tresult is %d\n", rv);
213
if (rv != NTV_NO_ERROR) { /* failed */
219
debug("credentials: %s\n", credentials);