ntlm_smb_lm_auth.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/*
10 * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
11 * Distributed freely under the terms of the GNU General Public License,
12 * version 2 or later. See the file COPYING for licensing details
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
22 */
23
24#include "squid.h"
25#include "base64.h"
26#include "compat/debug.h"
28#include "ntlmauth/ntlmauth.h"
30#include "rfcnb/rfcnb.h"
31#include "smblib/smblib.h"
32
33#include <cassert>
34#include <cctype>
35#include <cerrno>
36#include <csignal>
37#include <cstdlib>
38#include <cstring>
39#include <ctime>
40#if HAVE_UNISTD_H
41#include <unistd.h>
42#endif
43#if HAVE_GETOPT_H
44#include <getopt.h>
45#endif
46#if HAVE_UNISTD_H
47#include <unistd.h>
48#endif
49
50/************* CONFIGURATION ***************/
51
52#define DEAD_DC_RETRY_INTERVAL 30
53
54/************* END CONFIGURATION ***************/
55
56/* A couple of harmless helper macros */
57#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
58#ifdef __GNUC__
59#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
60#define SEND3(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
61#else
62/* no gcc, no debugging. varargs macros are a gcc extension */
63#define SEND2 printf
64#define SEND3 printf
65#endif
66
67const char *make_challenge(char *domain, char *controller);
68char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length);
69void dc_disconnect(void);
70int connectedp(void);
71int is_dc_ok(char *domain, char *domain_controller);
72
73typedef struct _dc dc;
74struct _dc {
75 char *domain;
77 time_t dead; /* 0 if it's alive, otherwise time of death */
79};
80
81/* local functions */
82void usage(void);
83void process_options(int argc, char *argv[]);
84const char * obtain_challenge(void);
85void manage_request(void);
86
87#define ENCODED_PASS_LEN 24
88#define MAX_USERNAME_LEN 255
89#define MAX_DOMAIN_LEN 255
90#define MAX_PASSWD_LEN 31
91
92static unsigned char challenge[NTLM_NONCE_LEN];
97static char credentials[MAX_USERNAME_LEN+MAX_DOMAIN_LEN+2]; /* we can afford to waste */
98static char my_domain[100], my_domain_controller[100];
99static char errstr[1001];
100#if DEBUG
101char error_messages_buffer[NTLM_BLOB_BUFFER_SIZE];
102#endif
104dc *controllers = nullptr;
108
109/* Disconnects from the DC. A reconnection will be done upon the next request
110 */
111void
113{
114 if (handle != NULL)
115 SMB_Discon(handle, 0);
116 handle = nullptr;
117}
118
119int
121{
122 return (handle != NULL);
123}
124
125/* Tries to connect to a DC. Returns 0 on failure, 1 on OK */
126int
127is_dc_ok(char *domain, char *domain_controller)
128{
129 SMB_Handle_Type h = SMB_Connect_Server(nullptr, domain_controller, domain);
130 if (h == NULL)
131 return 0;
132 SMB_Discon(h, 0);
133 return 1;
134}
135
136/* returns 0 on success, > 0 on failure */
137static int
138init_challenge(char *domain, char *domain_controller)
139{
140 int smberr;
141
142 if (handle != NULL) {
143 return 0;
144 }
145 debug("Connecting to server %s domain %s\n", domain_controller, domain);
146 handle = SMB_Connect_Server(nullptr, domain_controller, domain);
147 smberr = SMB_Get_Last_Error();
148 SMB_Get_Error_Msg(smberr, errstr, 1000);
149
150 if (handle == NULL) { /* couldn't connect */
151 debug("Couldn't connect to SMB Server. Error:%s\n", errstr);
152 return 1;
153 }
154 if (SMB_Negotiate(handle, SMB_Prots) < 0) { /* An error */
155 debug("Error negotiating protocol with SMB Server\n");
156 SMB_Discon(handle, 0);
157 handle = nullptr;
158 return 2;
159 }
160 if (handle->Security == 0) { /* share-level security, unusable */
161 debug("SMB Server uses share-level security .. we need user security.\n");
162 SMB_Discon(handle, 0);
163 handle = nullptr;
164 return 3;
165 }
167 SMBencrypt((unsigned char *)"",challenge,lmencoded_empty_pass);
168 SMBNTencrypt((unsigned char *)"",challenge,ntencoded_empty_pass);
169 return 0;
170}
171
172const char *
173make_challenge(char *domain, char *domain_controller)
174{
175 /* trying to circumvent some strange problem with pointers in SMBLib */
176 /* Ugly as hell, but the lib is going to be dropped... */
177 strncpy(my_domain, domain, sizeof(my_domain)-1);
178 my_domain[sizeof(my_domain)-1] = '\0';
179 strncpy(my_domain_controller, domain_controller, sizeof(my_domain_controller)-1);
181
183 return nullptr;
184 }
185
186 ntlm_challenge chal;
187 uint32_t flags = NTLM_REQUEST_NON_NT_SESSION_KEY |
194
195 size_t len = sizeof(chal) - sizeof(chal.payload) + le16toh(chal.target.maxlen);
196 // for lack of a good NTLM token size limit, allow up to what the helper input can be
197 // validations later will expect to be limited to that size.
198 static char b64buf[HELPER_INPUT_BUFFER-10]; /* 10 for other line fields, delimiters and terminator */
199 if (base64_encode_len(len) < sizeof(b64buf)-1) {
200 debug("base64 encoding of the token challenge will exceed %zu bytes", sizeof(b64buf));
201 return nullptr;
202 }
203
204 struct base64_encode_ctx ctx;
205 base64_encode_init(&ctx);
206 size_t blen = base64_encode_update(&ctx, b64buf, len, reinterpret_cast<const uint8_t *>(&chal));
207 blen += base64_encode_final(&ctx, b64buf+blen);
208 b64buf[blen] = '\0';
209 return b64buf;
210}
211
212/* returns NULL on failure, or a pointer to
213 * the user's credentials (domain\\username)
214 * upon success. WARNING. It's pointing to static storage.
215 * In case of problem sets as side-effect ntlm_errno to one of the
216 * codes defined in ntlm.h
217 */
218char *
219ntlm_check_auth(ntlm_authenticate * auth, int auth_length)
220{
221 int rv;
222 char pass[MAX_PASSWD_LEN+1];
223 char *domain = credentials;
224 char *user;
225 lstring tmp;
226
227 if (handle == NULL) { /*if null we aren't connected, but it shouldn't happen */
228 debug("Weird, we've been disconnected\n");
230 return nullptr;
231 }
232
233 /* debug("fetching domain\n"); */
234 tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->domain, auth->flags);
235 if (tmp.str == NULL || tmp.l == 0) {
236 debug("No domain supplied. Returning no-auth\n");
238 return nullptr;
239 }
240 if (tmp.l > MAX_DOMAIN_LEN) {
241 debug("Domain string exceeds %d bytes, rejecting\n", MAX_DOMAIN_LEN);
243 return nullptr;
244 }
245 memcpy(domain, tmp.str, tmp.l);
246 user = domain + tmp.l;
247 *user = '\0';
248 ++user;
249
250 /* debug("fetching user name\n"); */
251 tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->user, auth->flags);
252 if (tmp.str == NULL || tmp.l == 0) {
253 debug("No username supplied. Returning no-auth\n");
255 return nullptr;
256 }
257 if (tmp.l > MAX_USERNAME_LEN) {
258 debug("Username string exceeds %d bytes, rejecting\n", MAX_USERNAME_LEN);
260 return nullptr;
261 }
262 memcpy(user, tmp.str, tmp.l);
263 *(user + tmp.l) = '\0';
264
265 // grab the *response blobs. these are fixed length 24 bytes of binary
266 const ntlmhdr *packet = &(auth->hdr);
267 {
268 const strhdr * str = &auth->lmresponse;
269
270 int16_t len = le16toh(str->len);
271 int32_t offset = le32toh(str->offset);
272
273 if (len != ENCODED_PASS_LEN || offset + len > auth_length || offset == 0) {
274 debug("LM response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset);
276 return nullptr;
277 }
278 tmp.str = (char *)packet + offset;
279 tmp.l = len;
280 }
281 if (tmp.l > MAX_PASSWD_LEN) {
282 debug("Password string exceeds %d bytes, rejecting\n", MAX_PASSWD_LEN);
284 return nullptr;
285 }
286
287 /* Authenticating against the NT response doesn't seem to work... in SMB LM helper. */
288 memcpy(pass, tmp.str, tmp.l);
289 pass[min(MAX_PASSWD_LEN,tmp.l)] = '\0';
290
291 debug("Empty LM pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n",
292 user,lmencoded_empty_pass,tmp.str,tmp.l);
293 if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) {
294 fprintf(stderr,"Empty LM password supplied for user %s\\%s. "
295 "No-auth\n",domain,user);
297 return nullptr;
298 }
299
300 /* still fetch the NT response and check validity against empty password */
301 {
302 const strhdr * str = &auth->ntresponse;
303 int16_t len = le16toh(str->len);
304 // NT response field may be absent. that is okay.
305 if (len != 0) {
306 int32_t offset = le32toh(str->offset);
307
308 if (len != ENCODED_PASS_LEN || offset + len > auth_length || offset == 0) {
309 debug("NT response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset);
311 return nullptr;
312 }
313 tmp.str = (char *)packet + offset;
314 tmp.l = len;
315
316 debug("Empty NT pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n",
317 user,ntencoded_empty_pass,tmp.str,tmp.l);
318 if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) {
319 fprintf(stderr,"ERROR: Empty NT password supplied for user %s\\%s. No-auth\n", domain, user);
321 return nullptr;
322 }
323 }
324 }
325
326 debug("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass);
327
328 rv = SMB_Logon_Server(handle, user, pass, domain, 1);
329 debug("Login attempt had result %d\n", rv);
330
331 if (rv != NTLM_ERR_NONE) { /* failed */
332 ntlm_errno = rv;
333 return nullptr;
334 }
335 *(user - 1) = '\\'; /* hack. Performing, but ugly. */
336
337 debug("credentials: %s\n", credentials);
338 return credentials;
339}
340
341extern "C" void timeout_during_auth(int signum);
342
343static char got_timeout = 0;
346void
348{
350}
351
352/*
353 * options:
354 * -b try load-balancing the domain-controllers
355 * -f fail-over to another DC if DC connection fails.
356 * DEPRECATED and VERBOSELY IGNORED. This is on by default now.
357 * -l last-ditch-mode
358 * domain\controller ...
359 */
360char *my_program_name = nullptr;
361
362void
364{
365 fprintf(stderr,
366 "%s usage:\n%s [-b] [-f] [-d] [-l] domain\\controller [domain\\controller ...]\n"
367 "-b enables load-balancing among controllers\n"
368 "-f enables failover among controllers (DEPRECATED and always active)\n"
369 "-d enables debugging statements if DEBUG was defined at build-time.\n\n"
370 "You MUST specify at least one Domain Controller.\n"
371 "You can use either \\ or / as separator between the domain name \n"
372 "and the controller name\n",
374}
375
376/* int debug_enabled=0; defined in libcompat */
377
378void
379process_options(int argc, char *argv[])
380{
381 int opt, j, had_error = 0;
382 dc *new_dc = nullptr, *last_dc = nullptr;
383 while (-1 != (opt = getopt(argc, argv, "bfld"))) {
384 switch (opt) {
385 case 'b':
386 load_balance = 1;
387 break;
388 case 'f':
389 fprintf(stderr,
390 "WARNING. The -f flag is DEPRECATED and always active.\n");
391 break;
392 case 'd':
394 break;
395 default:
396 fprintf(stderr, "unknown option: -%c. Exiting\n", opt);
397 usage();
398 had_error = 1;
399 }
400 }
401 if (had_error)
402 exit(EXIT_FAILURE);
403 /* Okay, now begin filling controllers up */
404 /* we can avoid memcpy-ing, and just reuse argv[] */
405 for (j = optind; j < argc; ++j) {
406 char *d, *c;
407 /* d will not be freed in case of non-error. Since we don't reconfigure,
408 * it's going to live as long as the process anyways */
409 d = static_cast<char*>(xmalloc(strlen(argv[j]) + 1));
410 strcpy(d, argv[j]);
411 debug("Adding domain-controller %s\n", d);
412 if (NULL == (c = strchr(d, '\\')) && NULL == (c = strchr(d, '/'))) {
413 fprintf(stderr, "Couldn't grok domain-controller %s\n", d);
414 free(d);
415 continue;
416 }
417 /* more than one delimiter is not allowed */
418 if (NULL != strchr(c + 1, '\\') || NULL != strchr(c + 1, '/')) {
419 fprintf(stderr, "Broken domain-controller %s\n", d);
420 free(d);
421 continue;
422 }
423 *c= '\0';
424 ++c;
425 new_dc = static_cast<dc *>(xmalloc(sizeof(dc)));
426 if (!new_dc) {
427 fprintf(stderr, "Malloc error while parsing DC options\n");
428 free(d);
429 continue;
430 }
431 /* capitalize */
432 uc(c);
433 uc(d);
435 new_dc->domain = d;
436 new_dc->controller = c;
437 new_dc->dead = 0;
438 if (controllers == NULL) { /* first controller */
439 controllers = new_dc;
440 last_dc = new_dc;
441 } else {
442 last_dc->next = new_dc; /* can't be null */
443 last_dc = new_dc;
444 }
445 }
446 if (numcontrollers == 0) {
447 fprintf(stderr, "You must specify at least one domain-controller!\n");
448 usage();
449 exit(EXIT_FAILURE);
450 }
451 last_dc->next = controllers; /* close the queue, now it's circular */
452}
453
458const char *
460{
461 int j = 0;
462 const char *ch = nullptr;
463 for (j = 0; j < numcontrollers; ++j) {
464 debug("obtain_challenge: selecting %s\\%s (attempt #%d)\n",
466 if (current_dc->dead != 0) {
467 if (time(NULL) - current_dc->dead >= DEAD_DC_RETRY_INTERVAL) {
468 /* mark helper as retry-worthy if it's so. */
469 debug("Reviving DC\n");
470 current_dc->dead = 0;
471 } else { /* skip it */
472 debug("Skipping it\n");
473 continue;
474 }
475 }
476 /* else branch. Here we KNOW that the DC is fine */
477 debug("attempting challenge retrieval\n");
479 debug("make_challenge retuned %p\n", ch);
480 if (ch) {
481 debug("Got it\n");
482 return ch; /* All went OK, returning */
483 }
484 /* Huston, we've got a problem. Take this DC out of the loop */
485 debug("Marking DC as DEAD\n");
486 current_dc->dead = time(NULL);
487 /* Try with the next */
488 debug("moving on to next controller\n");
490 }
491 /* all DCs failed. */
492 return nullptr;
493}
494
495void
497{
498 ntlmhdr *fast_header;
499 char buf[NTLM_BLOB_BUFFER_SIZE];
500 char decoded[NTLM_BLOB_BUFFER_SIZE];
501 char *ch2, *cred = nullptr;
502
503 if (fgets(buf, NTLM_BLOB_BUFFER_SIZE, stdin) == NULL) {
504 fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno,
505 strerror(errno));
506 exit(EXIT_FAILURE); /* BIIG buffer */
507 }
508 debug("managing request\n");
509 ch2 = (char*)memchr(buf, '\n', NTLM_BLOB_BUFFER_SIZE); /* safer against overrun than strchr */
510 if (ch2) {
511 *ch2 = '\0'; /* terminate the string at newline. */
512 }
513 debug("ntlm authenticator. Got '%s' from Squid\n", buf);
514
515 if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */
516 /* figure out what we got */
517 struct base64_decode_ctx ctx;
518 base64_decode_init(&ctx);
519 size_t dstLen = 0;
520 int decodedLen = 0;
521 if (!base64_decode_update(&ctx, &dstLen, reinterpret_cast<uint8_t*>(decoded), strlen(buf)-3, buf+3) ||
522 !base64_decode_final(&ctx)) {
523 SEND("NA Packet format error, couldn't base64-decode");
524 return;
525 }
526 decodedLen = dstLen;
527
528 if ((size_t)decodedLen < sizeof(ntlmhdr)) { /* decoding failure, return error */
529 SEND("NA Packet format error, truncated packet header.");
530 return;
531 }
532 /* fast-track-decode request type. */
533 fast_header = (ntlmhdr *) decoded;
534
535 /* sanity-check: it IS a NTLMSSP packet, isn't it? */
536 if (ntlm_validate_packet(fast_header, NTLM_ANY) < 0) {
537 SEND("NA Broken authentication packet");
538 return;
539 }
540 switch (le32toh(fast_header->type)) {
541 case NTLM_NEGOTIATE:
542 SEND("NA Invalid negotiation request received");
543 return;
544 /* notreached */
545 case NTLM_CHALLENGE:
546 SEND("NA Got a challenge. We refuse to have our authority disputed");
547 return;
548 /* notreached */
550 /* check against the DC */
551 signal(SIGALRM, timeout_during_auth);
552 alarm(30);
553 cred = ntlm_check_auth((ntlm_authenticate *) decoded, decodedLen);
554 alarm(0);
555 signal(SIGALRM, SIG_DFL);
556 if (got_timeout != 0) {
557 fprintf(stderr, "ntlm-auth[%ld]: Timeout during authentication.\n", (long)getpid());
558 SEND("BH Timeout during authentication");
559 got_timeout = 0;
560 return;
561 }
562 if (cred == NULL) {
563 int smblib_err, smb_errorclass, smb_errorcode, nb_error;
564 if (ntlm_errno == NTLM_ERR_LOGON) { /* hackish */
565 SEND("NA Logon Failure");
566 return;
567 }
568 /* there was an error. We have two errno's to look at.
569 * libntlmssp's erno is insufficient, we'll have to look at
570 * the actual SMB library error codes, to actually figure
571 * out what's happening. The thing has braindamaged interfacess..*/
572 smblib_err = SMB_Get_Last_Error();
573 smb_errorclass = SMBlib_Error_Class(SMB_Get_Last_SMB_Err());
574 smb_errorcode = SMBlib_Error_Code(SMB_Get_Last_SMB_Err());
575 nb_error = RFCNB_Get_Last_Error();
576 debug("No creds. SMBlib error %d, SMB error class %d, SMB error code %d, NB error %d\n",
577 smblib_err, smb_errorclass, smb_errorcode, nb_error);
578 /* Should I use smblib_err? Actually it seems I can do as well
579 * without it.. */
580 if (nb_error != 0) { /* netbios-level error */
581 SEND("BH NetBios error!");
582 fprintf(stderr, "NetBios error code %d (%s)\n", nb_error,
583 RFCNB_Error_Strings[abs(nb_error)]);
584 return;
585 }
586 switch (smb_errorclass) {
587 case SMBC_SUCCESS:
588 debug("Huh? Got a SMB success code but could check auth..");
589 SEND("NA Authentication failed");
590 return;
591 case SMBC_ERRDOS:
592 /*this is the most important one for errors */
593 debug("DOS error\n");
594 switch (smb_errorcode) {
595 /* two categories matter to us: those which could be
596 * server errors, and those which are auth errors */
597 case SMBD_noaccess: /* 5 */
598 SEND("NA Access denied");
599 return;
600 case SMBD_badformat:
601 SEND("NA bad format in authentication packet");
602 return;
603 case SMBD_badaccess:
604 SEND("NA Bad access request");
605 return;
606 case SMBD_baddata:
607 SEND("NA Bad Data");
608 return;
609 default:
610 SEND("BH DOS Error");
611 return;
612 }
613 case SMBC_ERRSRV: /* server errors */
614 debug("Server error");
615 switch (smb_errorcode) {
616 /* mostly same as above */
617 case SMBV_badpw:
618 SEND("NA Bad password");
619 return;
620 case SMBV_access:
621 SEND("NA Server access error");
622 return;
623 default:
624 SEND("BH Server Error");
625 return;
626 }
627 case SMBC_ERRHRD: /* hardware errors don't really matter */
628 SEND("BH Domain Controller Hardware error");
629 return;
630 case SMBC_ERRCMD:
631 SEND("BH Domain Controller Command Error");
632 return;
633 }
634 SEND("BH unknown internal error.");
635 return;
636 }
637
638 lc(cred); /* let's lowercase them for our convenience */
639 SEND2("AF %s", cred);
640 return;
641 default:
642 SEND("BH unknown authentication packet type");
643 return;
644 }
645 /* notreached */
646 return;
647 }
648 if (memcmp(buf, "YR", 2) == 0) { /* refresh-request */
650 const char *ch = obtain_challenge();
651 /* Robert says we can afford to wait forever. I'll trust him on this
652 * one */
653 while (ch == NULL) {
654 sleep(30);
655 ch = obtain_challenge();
656 }
657 SEND2("TT %s", ch);
658 return;
659 }
660 SEND("BH Helper detected protocol error");
661 return;
662 /********* END ********/
663
664}
665
666int
667main(int argc, char *argv[])
668{
669 debug("%s " VERSION " " SQUID_BUILD_INFO " starting up...\n", argv[0]);
670
671 my_program_name = argv[0];
672 process_options(argc, argv);
673
674 debug("options processed OK\n");
675
676 /* initialize FDescs */
677 setbuf(stdout, nullptr);
678 setbuf(stderr, nullptr);
679
680 /* select the first domain controller we're going to use */
682 if (load_balance != 0 && numcontrollers > 1) {
683 int n;
684 pid_t pid = getpid();
685 n = pid % numcontrollers;
686 debug("load balancing. Selected controller #%d\n", n);
687 while (n > 0) {
689 --n;
690 }
691 }
692 while (1) {
694 }
695 /* notreached */
696 return EXIT_SUCCESS;
697}
698
static pid_t pid
Definition: IcmpSquid.cc:34
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:232
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
Definition: base64.c:265
void base64_decode_init(struct base64_decode_ctx *ctx)
Definition: base64.c:54
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
Definition: base64.c:308
#define base64_encode_len(length)
Definition: base64.h:169
int base64_decode_update(struct base64_decode_ctx *ctx, size_t *dst_length, uint8_t *dst, size_t src_length, const char *src)
Definition: base64.c:129
int base64_decode_final(struct base64_decode_ctx *ctx)
Definition: base64.c:159
#define HELPER_INPUT_BUFFER
Definition: UserRequest.cc:24
int debug_enabled
Definition: debug.cc:13
void debug(const char *format,...)
Definition: debug.cc:19
A const & min(A const &lhs, A const &rhs)
char * SMB_Prots[]
Definition: find_password.c:29
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:62
int optind
Definition: getopt.c:48
#define VERSION
#define xmalloc
const char * make_challenge(char *domain, char *controller)
int main(int argc, char *argv[])
static char my_domain_controller[100]
#define SEND(X)
#define MAX_DOMAIN_LEN
static char credentials[MAX_USERNAME_LEN+MAX_DOMAIN_LEN+2]
int ntlm_errno
int connectedp(void)
#define MAX_USERNAME_LEN
static char my_domain[100]
static unsigned char challenge[NTLM_NONCE_LEN]
static unsigned char lmencoded_empty_pass[ENCODED_PASS_LEN]
#define MAX_PASSWD_LEN
void timeout_during_auth(int signum)
dc * controllers
#define SEND2
static char errstr[1001]
static int init_challenge(char *domain, char *domain_controller)
static char got_timeout
char * my_program_name
void process_options(int argc, char *argv[])
int numcontrollers
static unsigned char ntencoded_empty_pass[ENCODED_PASS_LEN]
#define ENCODED_PASS_LEN
char protocol_pedantic
char * ntlm_check_auth(ntlm_authenticate *auth, int auth_length)
void manage_request(void)
char load_balance
void dc_disconnect(void)
dc * current_dc
SMB_Handle_Type handle
int is_dc_ok(char *domain, char *domain_controller)
void usage(void)
#define DEAD_DC_RETRY_INTERVAL
const char * obtain_challenge(void)
char smb_error_buffer[1000]
int ntlm_validate_packet(const ntlmhdr *hdr, const int32_t type)
Definition: ntlmauth.cc:67
void ntlm_make_challenge(ntlm_challenge *ch, const char *domain, const char *, const char *challenge_nonce, const int challenge_nonce_len, const uint32_t flags)
Definition: ntlmauth.cc:209
lstring ntlm_fetch_string(const ntlmhdr *packet, const int32_t packet_size, const strhdr *str, const uint32_t flags)
Definition: ntlmauth.cc:98
#define NTLM_REQUEST_NON_NT_SESSION_KEY
Definition: ntlmauth.h:32
#define NTLM_AUTHENTICATE
Definition: ntlmauth.h:75
#define NTLM_ERR_LOGON
Definition: ntlmauth.h:42
#define NTLM_ERR_NOT_CONNECTED
Definition: ntlmauth.h:44
#define NTLM_ERR_NONE
Definition: ntlmauth.h:38
#define NTLM_NEGOTIATE_USE_NTLM
Definition: ntlmauth.h:115
#define NTLM_NEGOTIATE_USE_LM
Definition: ntlmauth.h:113
#define NTLM_NEGOTIATE
Definition: ntlmauth.h:73
#define NTLM_CHALLENGE
Definition: ntlmauth.h:74
#define NTLM_ANY
Definition: ntlmauth.h:72
#define NTLM_NEGOTIATE_ASCII
Definition: ntlmauth.h:108
#define NTLM_NONCE_LEN
Definition: ntlmauth.h:134
#define NTLM_BLOB_BUFFER_SIZE
Definition: ntlmauth.h:25
#define NTLM_CHALLENGE_TARGET_IS_DOMAIN
Definition: ntlmauth.h:137
#define NTLM_NEGOTIATE_ALWAYS_SIGN
Definition: ntlmauth.h:119
const char * RFCNB_Error_Strings[]
Definition: rfcnb-util.c:47
int RFCNB_Get_Last_Error(void)
Definition: session.c:329
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
Definition: smbencrypt.c:140
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
Definition: smbencrypt.c:67
#define SMBC_SUCCESS
Definition: smblib-common.h:52
#define SMBD_baddata
Definition: smblib-common.h:78
#define SMBD_badaccess
Definition: smblib-common.h:77
#define SMBlib_Error_Class(p)
Definition: smblib-common.h:44
#define SMBC_ERRDOS
Definition: smblib-common.h:53
#define SMBV_access
Definition: smblib-common.h:93
#define SMBC_ERRHRD
Definition: smblib-common.h:55
#define SMBD_badformat
Definition: smblib-common.h:76
#define SMBD_noaccess
Definition: smblib-common.h:70
#define SMBC_ERRCMD
Definition: smblib-common.h:56
#define SMBC_ERRSRV
Definition: smblib-common.h:54
#define SMBV_badpw
Definition: smblib-common.h:91
#define SMBlib_Error_Code(p)
Definition: smblib-common.h:48
int SMB_Get_Last_Error()
Definition: smblib-util.c:755
int SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[])
Definition: smblib-util.c:239
int SMB_Get_Last_SMB_Err()
Definition: smblib-util.c:766
void SMB_Get_Error_Msg(int msg, char *msgbuf, int len)
Definition: smblib-util.c:798
int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle)
Definition: smblib.c:577
int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, char *PassWord, const char *NtDomain, int PreCrypted)
Definition: smblib.c:332
SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, const char *server, const char *NTdomain)
Definition: smblib.c:101
char * strerror(int ern)
Definition: strerror.c:22
char Encrypt_Key[80]
time_t dead
char * controller
char * domain
dc * next
char * str
Definition: ntlmauth.h:61
int32_t l
Definition: ntlmauth.h:60
uint32_t flags
Definition: ntlmauth.h:181
strhdr target
Definition: ntlmauth.h:144
char payload[256]
Definition: ntlmauth.h:149
int32_t type
Definition: ntlmauth.h:82
int16_t maxlen
Definition: ntlmauth.h:54
int32_t offset
Definition: ntlmauth.h:55
int16_t len
Definition: ntlmauth.h:53
void uc(char *string)
void lc(char *string)
#define le16toh(x)
#define le32toh(x)
#define NULL
Definition: types.h:145

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors