From e357d9106895b165bfa3f8331b9f186004c9a6cd Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 9 Nov 1997 17:30:10 +0000 Subject: attempting to mark up 32 bit error codes, needed for NT domains. separated out smb server-mode password validation into a separate file. added called and calling netbios names to client gen state: referenced section in rfc1002.txt. created workstation trust account checking code in ntclient.c there might be a bug in reply_session_setup_andX. i indented and added { } around single-line if statements: the lm password checking code now doesn't look right (around the GUEST_SESSSETUP bits). *no code semantics have been changed by the indentation process*. (This used to be commit f27966957fa7f16d337a4a58719239d036deab4c) --- source3/smbd/password.c | 140 +----------------------------------------------- source3/smbd/reply.c | 89 +++++++++++++++++------------- source3/smbd/server.c | 93 +++++++++++++++++++------------- 3 files changed, 110 insertions(+), 212 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 185fc68f5a..7dd2133406 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,7 +21,7 @@ #include "includes.h" -#if (defined(NETGROUP) && defined (AUTOMOUNT)) +#ifdef NETGROUP #include "rpcsvc/ypclnt.h" #endif @@ -1475,141 +1475,3 @@ BOOL check_hosts_equiv(char *user) return(False); } - -static struct cli_state cli; - -/**************************************************************************** -return the client state structure -****************************************************************************/ -struct cli_state *server_client(void) -{ - return &cli; -} - -/**************************************************************************** -support for server level security -****************************************************************************/ -struct cli_state *server_cryptkey(void) -{ - fstring desthost; - struct in_addr dest_ip; - extern fstring local_machine; - char *p; - - if (!cli_initialise(&cli)) - return NULL; - - for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { - fstrcpy(desthost,p); - standard_sub_basic(desthost); - strupper(desthost); - - dest_ip = *interpret_addr2(desthost); - if (zero_ip(dest_ip)) { - DEBUG(1,("Can't resolve address for %s\n",p)); - continue; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("Password server loop - disabling password server %s\n",p)); - continue; - } - - if (cli_connect(&cli, desthost, &dest_ip)) { - DEBUG(3,("connected to password server %s\n",p)); - break; - } - } - - if (!p) { - DEBUG(1,("password server not available\n")); - cli_shutdown(&cli); - return NULL; - } - - if (!cli_session_request(&cli, desthost, 0x20, local_machine)) { - DEBUG(1,("%s rejected the session\n",desthost)); - cli_shutdown(&cli); - return NULL; - } - - DEBUG(3,("got session\n")); - - if (!cli_negprot(&cli)) { - DEBUG(1,("%s rejected the negprot\n",desthost)); - cli_shutdown(&cli); - return NULL; - } - - if (cli.protocol < PROTOCOL_LANMAN2 || - !(cli.sec_mode & 1)) { - DEBUG(1,("%s isn't in user level security mode\n",desthost)); - cli_shutdown(&cli); - return NULL; - } - - DEBUG(3,("password server OK\n")); - - return &cli; -} - -/**************************************************************************** -validate a password with the password server -****************************************************************************/ -BOOL server_validate(char *user, char *domain, - char *pass, int passlen, - char *ntpass, int ntpasslen) -{ - extern fstring local_machine; - - if (!cli.initialised) { - DEBUG(1,("password server %s is not connected\n", cli.desthost)); - return(False); - } - - if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", cli.desthost)); - return False; - } - - /* if logged in as guest then reject */ - if ((SVAL(cli.inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli.desthost)); - return(False); - } - - - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { - DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); - return False; - } - - - if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { - DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); - cli_tdis(&cli); - return False; - } - - if (cli.privilages == 0) { - DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); - cli_tdis(&cli); - return False; - } - - if (!strequal(cli.eff_name, user)) { - DEBUG(1,("password server %s gave different username %s\n", - cli.desthost, - cli.eff_name)); - cli_tdis(&cli); - return False; - } - - DEBUG(3,("password server %s accepted the password\n", cli.desthost)); - - cli_tdis(&cli); - - return(True); -} - - diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 78dad6f02f..532fc583c2 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -395,6 +395,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) static BOOL done_sesssetup = False; BOOL doencrypt = SMBENCRYPT(); char *domain = ""; + struct cli_state *pwd_srv = NULL; *smb_apasswd = 0; *smb_ntpasswd = 0; @@ -518,19 +519,17 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (!smb_pass) { /* lkclXXXX: if workstation entry doesn't exist, indicate logon failure */ - DEBUG(4,("Workstation trust account %s doesn't exist.",user)); - SSVAL(outbuf, smb_flg2, 0xc003); /* PAXX: Someone please unhack this */ - CVAL(outbuf, smb_reh) = 1; /* PAXX: Someone please unhack this */ - return(ERROR(NT_STATUS_LOGON_FAILURE, 0xc000)); /* decimal 109 NT error, 0xc000 */ + DEBUG(4,("Workstation trust account %s doesn't exist\n",user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); /* PAXX: Someone please unhack this */ + return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE)); /* decimal 109; critical NT error */ } else { /* PAXX: This is the NO LOGON workstation trust account stuff */ /* lkclXXXX: if the workstation *does* exist, indicate failure differently! */ - DEBUG(4,("No Workstation trust account %s",user)); - SSVAL(outbuf, smb_flg2, 0xc003); /* PAXX: Someone please unhack this */ - CVAL(outbuf, smb_reh) = 1; /* PAXX: Someone please unhack this */ - return(ERROR(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT, 0xc000)); /* decimal 409 NT error, 0xc000 */ + DEBUG(4,("No Workstation trust account %s\n",user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); /* PAXX: Someone please unhack this */ + return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)); /* decimal 409; critical NT error */ } computer_id = True; @@ -563,43 +562,59 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) */ if(!guest && strequal(user,lp_guestaccount(-1)) && (*smb_apasswd == 0)) + { guest = True; + } - if (!guest && !(lp_security() == SEC_SERVER && - server_validate(user, domain, - smb_apasswd, smb_apasslen, - smb_ntpasswd, smb_ntpasslen)) && - !check_hosts_equiv(user)) - { - - /* now check if it's a valid username/password */ - /* If an NT password was supplied try and validate with that - first. This is superior as the passwords are mixed case - 128 length unicode */ - if(smb_ntpasslen) - { - if(!password_ok(user,smb_ntpasswd,smb_ntpasslen,NULL)) - DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n")); - else - valid_nt_password = True; - } - if (!valid_nt_password && !password_ok(user,smb_apasswd,smb_apasslen,NULL)) + if (!guest && !(lp_security() == SEC_SERVER && + ((pwd_srv = pwd_server_connection()) != NULL) && + server_validate(pwd_srv, user, domain, + smb_apasswd, smb_apasslen, + smb_ntpasswd, smb_ntpasslen)) && + !check_hosts_equiv(user)) { - if (!computer_id && lp_security() >= SEC_USER) { + + /* now check if it's a valid username/password */ + /* If an NT password was supplied try and validate with that + first. This is superior as the passwords are mixed case + 128 length unicode */ + + if (smb_ntpasslen) + { + /* check the NT password, if there is one. */ + if(!password_ok(user,smb_ntpasswd,smb_ntpasslen,NULL)) + { + DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n")); + } + else + { + valid_nt_password = True; + } + } + + /* check the LM password instead */ + if (!valid_nt_password && !password_ok(user,smb_apasswd,smb_apasslen,NULL)) + { + if (!computer_id && lp_security() >= SEC_USER) + { #if (GUEST_SESSSETUP == 0) - return(ERROR(ERRSRV,ERRbadpw)); + return(ERROR(ERRSRV,ERRbadpw)); #endif #if (GUEST_SESSSETUP == 1) - if (Get_Pwnam(user,True)) - return(ERROR(ERRSRV,ERRbadpw)); + if (Get_Pwnam(user,True)) + return(ERROR(ERRSRV,ERRbadpw)); #endif - } - if (*smb_apasswd || !Get_Pwnam(user,True)) - strcpy(user,lp_guestaccount(-1)); - DEBUG(3,("Registered username %s for guest access\n",user)); - guest = True; + } + + /* no lm or nt password specified: username doesn't exist. allow guest access */ + if (*smb_apasswd || !Get_Pwnam(user,True)) + { + strcpy(user, lp_guestaccount(-1)); + DEBUG(3,("Registered username %s for guest access\n",user)); + guest = True; + } + } } - } if (!Get_Pwnam(user,True)) { DEBUG(3,("No such user %s - using guest account\n",user)); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 908cf984b8..a42b4deea2 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -25,6 +25,7 @@ pstring servicesf = CONFIGFILE; extern pstring debugf; extern pstring sesssetup_user; +extern pstring local_machine; extern fstring myworkgroup; char *InBuffer = NULL; @@ -114,6 +115,21 @@ static int find_free_connection(int hash); #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0) #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0) +/* use this to validate user against a password server. "security = server" */ +static struct cli_state pwd_srv; + +/**************************************************************************** + for use in reply.c, to access the password server connection. +****************************************************************************/ +struct cli_state *pwd_server_connection(void) +{ + if (pwd_srv.initialised) + { + return &pwd_srv; + } + return NULL; +} + /**************************************************************************** when exiting, take the whole family ****************************************************************************/ @@ -2257,21 +2273,30 @@ int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int { int outsize = set_message(outbuf,0,0,True); int cmd; - cmd = CVAL(inbuf,smb_com); - - CVAL(outbuf,smb_rcls) = error_class; - SSVAL(outbuf,smb_err,error_code); + int flgs2; + cmd = CVAL(inbuf,smb_com); + flgs2 = SVAL(outbuf,smb_flg2); - DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n", - timestring(), - line, - (int)CVAL(inbuf,smb_com), - smb_fn_name(CVAL(inbuf,smb_com)), - error_class, - error_code)); + if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES) + { + SIVAL(outbuf,smb_rcls,error_code); + + DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n", + timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf))); + } + else + { + CVAL(outbuf,smb_rcls) = error_class; + SSVAL(outbuf,smb_err,error_code); + DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n", + timestring(), line, cmd, smb_fn_name(cmd), error_class, error_code)); + } + if (errno != 0) - DEBUG(3,("error string = %s\n",strerror(errno))); + { + DEBUG(3,("error string = %s\n", strerror(errno))); + } return(outsize); } @@ -2328,12 +2353,13 @@ static int sig_cld() **************************************************************************/ static int sig_pipe() { - struct cli_state *cli; BlockSignals(True,SIGPIPE); - if ((cli = server_client()) && cli->initialised) { + if (pwd_srv.initialised) + { DEBUG(3,("lost connection to password server\n")); - cli_shutdown(cli); + cli_shutdown(&pwd_srv); + #ifndef DONT_REINSTALL_SIG signal(SIGPIPE, SIGNAL_CAST sig_pipe); #endif @@ -3684,29 +3710,27 @@ int reply_lanman2(char *outbuf) int secword=0; BOOL doencrypt = SMBENCRYPT(); time_t t = time(NULL); - struct cli_state *cli = NULL; char cryptkey[8]; char crypt_len = 0; - if (lp_security() == SEC_SERVER) { - cli = server_cryptkey(); - } - - if (cli) { + if (lp_security() == SEC_SERVER && server_cryptkey(&pwd_srv, local_machine)) + { DEBUG(3,("using password server validation\n")); - doencrypt = ((cli->sec_mode & 2) != 0); + doencrypt = ((pwd_srv.sec_mode & 2) != 0); } if (lp_security()>=SEC_USER) secword |= 1; if (doencrypt) secword |= 2; - if (doencrypt) { + if (doencrypt) + { crypt_len = 8; - if (!cli) { + if (pwd_srv.initialised) + { generate_next_challenge(cryptkey); } else { - memcpy(cryptkey, cli->cryptkey, 8); - set_challenge(cli->cryptkey); + memcpy(cryptkey, pwd_srv.cryptkey, 8); + set_challenge(pwd_srv.cryptkey); } } @@ -3751,16 +3775,14 @@ int reply_nt1(char *outbuf) char cryptkey[8]; char crypt_len = 0; - if (lp_security() == SEC_SERVER) { - cli = server_cryptkey(); - } - - if (cli) { + if (lp_security() == SEC_SERVER && server_cryptkey(&pwd_srv, local_machine)) + { DEBUG(3,("using password server validation\n")); - doencrypt = ((cli->sec_mode & 2) != 0); + doencrypt = ((pwd_srv.sec_mode & 2) != 0); } - if (doencrypt) { + if (doencrypt) + { crypt_len = 8; if (!cli) { generate_next_challenge(cryptkey); @@ -4862,15 +4884,14 @@ static void process(void) if (keepalive && (counter-last_keepalive)>keepalive) { - struct cli_state *cli = server_client(); if (!send_keepalive(Client)) { DEBUG(2,("%s Keepalive failed - exiting\n",timestring())); return; } /* also send a keepalive to the password server if its still connected */ - if (cli && cli->initialised) - send_keepalive(cli->fd); + if (pwd_srv.initialised) + send_keepalive(pwd_srv.fd); last_keepalive = counter; } -- cgit