Project

General

Profile

0007-Add-NTLM-login-on-multiple-and-different-domains.patch

Emmanuel GARETTE, 09/07/2015 10:53 AM

Download (10.4 KB)

View differences:

helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc
22 22
#include "smblib/smblib.h"
23 23
//#include "util.h"
24
#define MAX_DOMAIN_LEN 255
25

  
24 26
#if HAVE_STRING_H
25 27
#include <string.h>
26 28
#endif
......
91 93
void usage(void);
92 94
void process_options(int argc, char *argv[]);
93 95
const char * obtain_challenge(void);
94
void manage_request(void);
96
int manage_request(void);
97
int choose_dc(ntlm_authenticate * auth, int plen, int type);
95 98
#define ENCODED_PASS_LEN 24
96 99
#define MAX_USERNAME_LEN 255
......
109 112
#if DEBUG
110 113
char error_messages_buffer[NTLM_BLOB_BUFFER_SIZE];
111 114
#endif
115

  
116
int any_controller = 0; /* To authenticate on any available controller, default: NO */
112 117
char load_balance = 0, protocol_pedantic = 0;
113 118
dc *controllers = NULL;
114 119
int numcontrollers = 0;
......
337 342
{
338 343
    fprintf(stderr,
339 344
            "%s usage:\n%s [-b] [-f] [-d] [-l] domain\\controller [domain\\controller ...]\n"
345
            "-a any valid authentication on one of the domain controllers is enough to authenticate\n"
340 346
            "-b enables load-balancing among controllers\n"
341 347
            "-f enables failover among controllers (DEPRECATED and always active)\n"
342 348
            "-d enables debugging statements if DEBUG was defined at build-time.\n\n"
......
353 359
{
354 360
    int opt, j, had_error = 0;
355 361
    dc *new_dc = NULL, *last_dc = NULL;
356
    while (-1 != (opt = getopt(argc, argv, "bfld"))) {
362
    while (-1 != (opt = getopt(argc, argv, "abfld"))) {
357 363
        switch (opt) {
364
        case 'a':
365
            any_controller = 1;
366
            break;
358 367
        case 'b':
359 368
            load_balance = 1;
360 369
            break;
......
465 474
    return NULL;
466 475
}
467
void
476
int
477
choose_dc(ntlm_authenticate * auth, int plen, int type)
478
{
479
    /* This function extracts the domain from the decoded message (type 1
480
     * (negotiate) or type 3 (authenticate)) and modifies the global variable
481
     * current_dc accordingly. */
482
    int i;
483
    char domain[MAX_DOMAIN_LEN+2];
484
    lstring tmp;
485

  
486
    /* Extract domain from decoded message: */
487
    switch (type) {
488
	case NTLM_NEGOTIATE:
489
	    tmp = ntlm_fetch_string(&(auth->hdr), plen, &auth->domain, auth->flags);
490
	    break;
491
	case NTLM_AUTHENTICATE:
492
        tmp = ntlm_fetch_string(&(auth->hdr), plen, &auth->domain, auth->flags);
493
	    break;
494
	default:
495
	    fprintf(stderr, "Unknown requested type (%d) in choose_dc.\n",
496
		    type);
497
	    return 101;
498
    }
499
    if (tmp.str == NULL || tmp.l == 0) {
500
	debug("No domain supplied. Returning no-auth\n");
501
	return NTLM_ERR_LOGON;
502
    }
503
    if (tmp.l > MAX_DOMAIN_LEN) {
504
	debug("Domain string exceeds %d bytes, rejecting\n", MAX_DOMAIN_LEN);
505
	return NTLM_ERR_LOGON;
506
    }
507
    if (tmp.l > MAX_DOMAIN_LEN || tmp.l <= 0) return 111;
508
    memcpy(domain, tmp.str, tmp.l);
509
    domain[tmp.l] = '\0';
510

  
511
    /* Select a dc according to the domain fetched above: */
512
    for (i = 0; i < numcontrollers &&
513
		memcmp(domain, current_dc->domain, tmp.l) != 0; i++) {
514
	current_dc = current_dc->next;
515
    }
516

  
517
    /* Check the result: */
518
    if (memcmp(domain, current_dc->domain, tmp.l) != 0) {
519
	fprintf(stderr, "dc for %s not found (current_dc:%s)!\n",
520
		domain, current_dc->domain);
521
	return 121;  /* Failure. */
522
    }
523
    return 0;  /* Success. */
524
}
525

  
526
int
468 527
manage_request()
469 528
{
470 529
    ntlmhdr *fast_header;
......
493 552
        if ((size_t)decodedLen < sizeof(ntlmhdr)) {	/* decoding failure, return error */
494 553
            SEND("NA Packet format error, couldn't base64-decode");
495
            return;
554
            return NTLM_ERR_BAD_PROTOCOL;
496 555
        }
497 556
        /* fast-track-decode request type. */
498 557
        fast_header = (ntlmhdr *) decoded;
......
501 560
        /* sanity-check: it IS a NTLMSSP packet, isn't it? */
502 561
        if (ntlm_validate_packet(fast_header, NTLM_ANY) < 0) {
503 562
            SEND("NA Broken authentication packet");
504
            return;
563
            return NTLM_ERR_BAD_PROTOCOL;
505 564
        }
506 565
        switch (le32toh(fast_header->type)) {
507 566
        case NTLM_NEGOTIATE:
508 567
            SEND("NA Invalid negotiation request received");
509
            return;
568
            return NTLM_ERR_BAD_PROTOCOL;
510 569
            /* notreached */
511 570
        case NTLM_CHALLENGE:
512 571
            SEND("NA Got a challenge. We refuse to have our authority disputed");
513
            return;
572
            return NTLM_ERR_BAD_PROTOCOL;
514 573
            /* notreached */
515 574
        case NTLM_AUTHENTICATE:
516 575
            /* check against the DC */
517 576
            signal(SIGALRM, timeout_during_auth);
518 577
            alarm(30);
578
            if (any_controller) {
579
                choose_dc((ntlm_authenticate *) decoded, decodedLen, NTLM_AUTHENTICATE);
580
            }
519 581
            cred = ntlm_check_auth((ntlm_authenticate *) decoded, decodedLen);
520 582
            alarm(0);
521 583
            signal(SIGALRM, SIG_DFL);
......
523 585
                fprintf(stderr, "ntlm-auth[%ld]: Timeout during authentication.\n", (long)getpid());
524 586
                SEND("BH Timeout during authentication");
525 587
                got_timeout = 0;
526
                return;
588
                return NTLM_ERR_SERVER;
527 589
            }
528 590
            if (cred == NULL) {
529 591
                int smblib_err, smb_errorclass, smb_errorcode, nb_error;
530 592
                if (ntlm_errno == NTLM_ERR_LOGON) {	/* hackish */
531 593
                    SEND("NA Logon Failure");
532
                    return;
594
                    return NTLM_ERR_SERVER;
533 595
                }
534 596
                /* there was an error. We have two errno's to look at.
535 597
                 * libntlmssp's erno is insufficient, we'll have to look at
......
547 609
                    SEND("BH NetBios error!");
548 610
                    fprintf(stderr, "NetBios error code %d (%s)\n", nb_error,
549 611
                            RFCNB_Error_Strings[abs(nb_error)]);
550
                    return;
612
                    return NTLM_ERR_SERVER;
551 613
                }
552 614
                switch (smb_errorclass) {
553 615
                case SMBC_SUCCESS:
554 616
                    debug("Huh? Got a SMB success code but could check auth..");
555 617
                    SEND("NA Authentication failed");
556
                    return;
618
                    return NTLM_ERR_LOGON;
557 619
                case SMBC_ERRDOS:
558 620
                    /*this is the most important one for errors */
559 621
                    debug("DOS error\n");
......
562 624
                         * server errors, and those which are auth errors */
563 625
                    case SMBD_noaccess:	/* 5 */
564 626
                        SEND("NA Access denied");
565
                        return;
627
                        return NTLM_ERR_LOGON;
566 628
                    case SMBD_badformat:
567 629
                        SEND("NA bad format in authentication packet");
568
                        return;
630
                        return NTLM_ERR_LOGON;
569 631
                    case SMBD_badaccess:
570 632
                        SEND("NA Bad access request");
571
                        return;
633
                        return NTLM_ERR_LOGON;
572 634
                    case SMBD_baddata:
573 635
                        SEND("NA Bad Data");
574
                        return;
636
                        return NTLM_ERR_LOGON;
575 637
                    default:
576 638
                        SEND("BH DOS Error");
577
                        return;
639
                        return NTLM_ERR_LOGON;
578 640
                    }
579 641
                case SMBC_ERRSRV:	/* server errors */
580 642
                    debug("Server error");
......
582 644
                        /* mostly same as above */
583 645
                    case SMBV_badpw:
584 646
                        SEND("NA Bad password");
585
                        return;
647
                        return NTLM_ERR_LOGON;
586 648
                    case SMBV_access:
587 649
                        SEND("NA Server access error");
588
                        return;
650
                        return NTLM_ERR_SERVER;
589 651
                    default:
590 652
                        SEND("BH Server Error");
591
                        return;
653
                        return NTLM_ERR_SERVER;
592 654
                    }
593 655
                case SMBC_ERRHRD:	/* hardware errors don't really matter */
594 656
                    SEND("BH Domain Controller Hardware error");
595
                    return;
657
                    return NTLM_ERR_SERVER;
596 658
                case SMBC_ERRCMD:
597 659
                    SEND("BH Domain Controller Command Error");
598
                    return;
660
                    return NTLM_ERR_SERVER;
599 661
                }
600 662
                SEND("BH unknown internal error.");
601
                return;
663
                return NTLM_ERR_SERVER;
602 664
            }
603 665
            lc(cred);		/* let's lowercase them for our convenience */
604 666
            SEND2("AF %s", cred);
605
            return;
667
            return NTLM_ERR_NONE;
606 668
        default:
607 669
            SEND("BH unknown authentication packet type");
608
            return;
670
            return NTLM_ERR_BAD_PROTOCOL;
609 671
        }
610 672
        /* notreached */
611
        return;
673
    	return NTLM_ERR_PROTOCOL; /* The 'authenticate request' did not match any of the above */
612 674
    }
613 675
    if (memcmp(buf, "YR", 2) == 0) {	/* refresh-request */
676
        if (any_controller) {
677
            choose_dc((ntlm_authenticate *) decoded, base64_decode(decoded, sizeof(decoded), buf+3), NTLM_NEGOTIATE);
678
        }
614 679
        dc_disconnect();
615 680
        ch = obtain_challenge();
616 681
        /* Robert says we can afford to wait forever. I'll trust him on this
......
621 686
            ch = obtain_challenge();
622 687
        }
623 688
        SEND2("TT %s", ch);
624
        return;
689
        return NTLM_ERR_NONE;
625 690
    }
626 691
    SEND("BH Helper detected protocol error");
627
    return;
692
    return NTLM_ERR_PROTOCOL;
628 693
    /********* END ********/
629 694
}
......
639 704
    debug("options processed OK\n");
705
    if ( load_balance && any_controller ) {
706
        fprintf(stderr, "Cannot both load balance AND do authentication on any controller, exiting\n");
707
        exit(1);
708
    }
709

  
640 710
    /* initialize FDescs */
641 711
    setbuf(stdout, NULL);
642 712
    setbuf(stderr, NULL);