summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1997-11-09 17:30:10 +0000
committerLuke Leighton <lkcl@samba.org>1997-11-09 17:30:10 +0000
commite357d9106895b165bfa3f8331b9f186004c9a6cd (patch)
tree52e18b1e8f0770f89d157c6766745ed201df11a6 /source3/smbd
parenta81dd62af0321e0c78f81ea79605dade3e563f7a (diff)
downloadsamba-e357d9106895b165bfa3f8331b9f186004c9a6cd.tar.gz
samba-e357d9106895b165bfa3f8331b9f186004c9a6cd.tar.bz2
samba-e357d9106895b165bfa3f8331b9f186004c9a6cd.zip
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)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/password.c140
-rw-r--r--source3/smbd/reply.c89
-rw-r--r--source3/smbd/server.c93
3 files changed, 110 insertions, 212 deletions
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;
}