diff options
author | Andrew Tridgell <tridge@samba.org> | 1997-10-21 10:09:30 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1997-10-21 10:09:30 +0000 |
commit | 9caab6bec07230ecc80aada0881f6978f28c58a8 (patch) | |
tree | fb3b02e7240726798cac1eee6b5e436ef20b2eba /source | |
parent | 481b50b6e64e589ca91a43617458115f8f977dae (diff) | |
download | samba-9caab6bec07230ecc80aada0881f6978f28c58a8.tar.gz samba-9caab6bec07230ecc80aada0881f6978f28c58a8.tar.xz samba-9caab6bec07230ecc80aada0881f6978f28c58a8.zip |
add the new password server code to the 1.9.17 tree. This needed to be
fixed as the previous code could provide a security hole if the NT
server was misconfigured
Diffstat (limited to 'source')
-rw-r--r-- | source/client/client.c | 13 | ||||
-rw-r--r-- | source/client/clientutil.c | 65 | ||||
-rw-r--r-- | source/include/local.h | 4 | ||||
-rw-r--r-- | source/include/proto.h | 35 | ||||
-rw-r--r-- | source/include/smb.h | 27 | ||||
-rw-r--r-- | source/smbd/ipc.c | 2 | ||||
-rw-r--r-- | source/smbd/password.c | 279 | ||||
-rw-r--r-- | source/smbd/reply.c | 11 | ||||
-rw-r--r-- | source/smbd/server.c | 170 |
9 files changed, 297 insertions, 309 deletions
diff --git a/source/client/client.c b/source/client/client.c index cd9e8d1c97c..a48d1b4990b 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -3411,6 +3411,13 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu uid = SVAL(inbuf,smb_uid); } + if (SVAL(inbuf, smb_vwv2) & 1) + DEBUG(1,("connected as guest ")); + if (sec_mode & 1) + DEBUG(1,("security=user\n")); + else + DEBUG(1,("security=share\n")); + /* now we've got a connection - send a tcon message */ bzero(outbuf,smb_size); @@ -3520,6 +3527,7 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu free(inbuf); free(outbuf); } + return True; } @@ -3693,6 +3701,7 @@ static BOOL send_trans_request(char *outbuf,int trans, return(True); } + /**************************************************************************** try and browse available connections on a host ****************************************************************************/ @@ -4118,7 +4127,7 @@ static BOOL open_sockets(int port ) strcpy(desthost,host); } - if (*myname == 0) { + if (!(*myname)) { get_myname(myname,NULL); } strupper(myname); @@ -4639,7 +4648,7 @@ static void usage(char *pname) strcpy(workgroup,lp_workgroup()); load_interfaces(); - get_myname(*myname?NULL:myname,NULL); + get_myname((*myname)?NULL:myname,NULL); strupper(myname); if (tar_type) { diff --git a/source/client/clientutil.c b/source/client/clientutil.c index 1b59946ff5b..cb0a731480c 100644 --- a/source/client/clientutil.c +++ b/source/client/clientutil.c @@ -77,7 +77,7 @@ extern int Client; /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ -void cli_setup_pkt(char *outbuf) +static void cli_setup_pkt(char *outbuf) { SSVAL(outbuf,smb_pid,pid); SSVAL(outbuf,smb_uid,uid); @@ -89,11 +89,14 @@ void cli_setup_pkt(char *outbuf) } } + + /**************************************************************************** receive a SMB trans or trans2 response allocating the necessary memory ****************************************************************************/ -BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len, - int *param_len, char **data,char **param) +static BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len, + int *param_len, char **data, + char **param) { int total_data=0; int total_param=0; @@ -164,7 +167,7 @@ BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len, /**************************************************************************** send a session request ****************************************************************************/ -BOOL cli_send_session_request(char *inbuf, char *outbuf) +static BOOL cli_send_session_request(char *inbuf, char *outbuf) { fstring dest; char *p; @@ -661,35 +664,12 @@ void cli_send_logout(void) } - -/**************************************************************************** -call a remote api -****************************************************************************/ -BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt, - int *rdrcnt, char *param,char *data, char **rparam,char **rdata) -{ - static char *inbuf=NULL; - static char *outbuf=NULL; - - if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); - if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); - - cli_send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0, - data,param,NULL, - drcnt,prcnt,0, - mdrcnt,mprcnt,0); - - return (cli_receive_trans_response(inbuf,SMBtrans, - rdrcnt,rprcnt, - rdata,rparam)); -} - /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ -BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags, - char *data,char *param,uint16 *setup, int ldata,int lparam, - int lsetup,int mdata,int mparam,int msetup) +static BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags, + char *data,char *param,uint16 *setup, int ldata,int lparam, + int lsetup,int mdata,int mparam,int msetup) { int i; int this_ldata,this_lparam; @@ -797,6 +777,31 @@ BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int fl } + +/**************************************************************************** +call a remote api +****************************************************************************/ +BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt, + int *rdrcnt, char *param,char *data, + char **rparam, char **rdata) +{ + static char *inbuf=NULL; + static char *outbuf=NULL; + + if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); + if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); + + cli_send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0, + data,param,NULL, + drcnt,prcnt,0, + mdrcnt,mprcnt,0); + + return (cli_receive_trans_response(inbuf,SMBtrans, + rdrcnt,rprcnt, + rdata,rparam)); +} + + /**************************************************************************** open the client sockets ****************************************************************************/ diff --git a/source/include/local.h b/source/include/local.h index f5f2c318180..92d566cf82d 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -147,10 +147,6 @@ /* shall we support browse requests via a FIFO to nmbd? */ #define ENABLE_FIFO 1 -/* keep the password server open, this uses up a aocket, but is needed - by many apps */ -#define KEEP_PASSWORD_SERVER_OPEN 1 - /* how long to wait for a socket connect to happen */ #define LONG_CONNECT_TIMEOUT 30 #define SHORT_CONNECT_TIMEOUT 5 diff --git a/source/include/proto.h b/source/include/proto.h index 7717ce2d4b9..e9776bf2548 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -32,19 +32,31 @@ void cmd_help(void); BOOL reopen_connection(char *inbuf,char *outbuf); char *smb_errstr(char *inbuf); +/*The following definitions come from clientgen.c */ + +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup); +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pword, int passlen); +BOOL cli_tdis(struct cli_state *cli); +BOOL cli_negprot(struct cli_state *cli); +BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, + char *myname); +BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip); +BOOL cli_initialise(struct cli_state *cli); +void cli_shutdown(struct cli_state *cli); + /*The following definitions come from clientutil.c */ -void cli_setup_pkt(char *outbuf); -BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len, - int *param_len, char **data,char **param); -BOOL cli_send_session_request(char *inbuf, char *outbuf); BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setup); void cli_send_logout(void); BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt, - int *rdrcnt, char *param,char *data, char **rparam,char **rdata); -BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags, - char *data,char *param,uint16 *setup, int ldata,int lparam, - int lsetup,int mdata,int mparam,int msetup); + int *rdrcnt, char *param,char *data, + char **rparam, char **rdata); BOOL cli_open_sockets(int port); BOOL cli_reopen_connection(char *inbuf,char *outbuf); char *smb_errstr(char *inbuf); @@ -585,8 +597,11 @@ BOOL user_ok(char *user,int snum); BOOL authorise_login(int snum,char *user,char *password, int pwlen, BOOL *guest,BOOL *force,uint16 vuid); BOOL check_hosts_equiv(char *user); -BOOL server_cryptkey(char *buf); -BOOL server_validate(char *buf); +struct cli_state *server_client(void); +struct cli_state *server_cryptkey(void); +BOOL server_validate(char *user, char *domain, + char *pass, int passlen, + char *ntpass, int ntpasslen); /*The following definitions come from pcap.c */ diff --git a/source/include/smb.h b/source/include/smb.h index b55c180f361..a273d962b69 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -261,6 +261,33 @@ struct smb_passwd { }; +struct cli_state { + int fd; + int cnum; + int pid; + int mid; + int uid; + int protocol; + int sec_mode; + int error; + int privilages; + fstring eff_name; + fstring desthost; + char cryptkey[8]; + uint32 sesskey; + int serverzone; + uint32 servertime; + int readbraw_supported; + int writebraw_supported; + int timeout; + int max_xmit; + char *outbuf; + char *inbuf; + int bufsize; + int initialised; +}; + + struct current_user { int cnum, id; int uid, gid; diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 1d7ee375d3f..c63a54c2ac2 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -2004,6 +2004,8 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, *rparam_len = 6; *rparam = REALLOC(*rparam,*rparam_len); + + DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel)); /* check it's a supported variant */ if (strcmp(str1,"zWrLh") != 0) return False; diff --git a/source/smbd/password.c b/source/smbd/password.c index 68205b4dae9..0d9db08dd98 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -1507,207 +1507,146 @@ BOOL check_hosts_equiv(char *user) return(False); } - -int password_client = -1; -static fstring pserver; -static char *secserver_inbuf = NULL; +static struct cli_state cli; /**************************************************************************** -attempted support for server level security +return the client state structure ****************************************************************************/ -BOOL server_cryptkey(char *buf) +struct cli_state *server_client(void) { - pstring outbuf; - fstring pass_protocol; - extern fstring remote_machine; - char *p; - int len; - fstring desthost; - struct in_addr dest_ip; - int port = SMB_PORT; - BOOL ret; - - if(secserver_inbuf == NULL) { - secserver_inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); - if(secserver_inbuf == NULL) { - DEBUG(0,("server_cryptkey: malloc fail for input buffer.\n")); - return False; - } - } - - if (password_client >= 0) - close(password_client); - password_client = -1; - - if (Protocol < PROTOCOL_NT1) { - strcpy(pass_protocol,"LM1.2X002"); - } else { - strcpy(pass_protocol,"NT LM 0.12"); - } - - bzero(secserver_inbuf,BUFFER_SIZE + SAFETY_MARGIN); - bzero(outbuf,sizeof(outbuf)); - - for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { - strcpy(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; - } - - password_client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT); - if (password_client >= 0) { - DEBUG(3,("connected to password server %s\n",p)); - StrnCpy(pserver,p,sizeof(pserver)-1); - break; - } - } - - if (password_client < 0) { - DEBUG(1,("password server not available\n")); - return(False); - } - - - /* send a session request (RFC 8002) */ - - /* put in the destination name */ - len = 4; - p = outbuf+len; - name_mangle(desthost,p,' '); - len += name_len(p); - p = outbuf+len; - - /* and my name */ - /* Fix from Frank Varnavas <varnavas@ny.ubs.com>. - We cannot use the same name as the client to - the NT password server, as NT will drop client - connections if the same client name connects - twice. Instead, synthesize a name from our pid. - and the remote machine name. - */ - { - char buf[32]; /* create name as PIDname */ - sprintf(buf,"%d", getpid()); - strncpy(&buf[strlen(buf)], remote_machine, 31 - strlen(buf)); - buf[31] = '\0'; - DEBUG(1,("negprot w/password server as %s\n",buf)); - name_mangle(buf,p,' '); - len += name_len(p); - } - - _smb_setlen(outbuf,len); - CVAL(outbuf,0) = 0x81; - - send_smb(password_client,outbuf); - - - if (!receive_smb(password_client,secserver_inbuf,5000) || - CVAL(secserver_inbuf,0) != 0x82) { - DEBUG(1,("%s rejected the session\n",pserver)); - close(password_client); password_client = -1; - return(False); - } + return &cli; +} - DEBUG(3,("got session\n")); +/**************************************************************************** +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; + } - bzero(outbuf,smb_size); + if (ismyip(dest_ip)) { + DEBUG(1,("Password server loop - disabling password server %s\n",p)); + continue; + } - /* setup the protocol string */ - set_message(outbuf,0,strlen(pass_protocol)+2,True); - p = smb_buf(outbuf); - *p++ = 2; - strcpy(p,pass_protocol); + if (cli_connect(&cli, desthost, &dest_ip)) { + DEBUG(3,("connected to password server %s\n",p)); + break; + } + } - CVAL(outbuf,smb_com) = SMBnegprot; - CVAL(outbuf,smb_flg) = 0x8; - SSVAL(outbuf,smb_flg2,0x1); + if (!p) { + DEBUG(1,("password server not available\n")); + cli_shutdown(&cli); + return NULL; + } - send_smb(password_client,outbuf); - ret = receive_smb(password_client,secserver_inbuf,5000); + if (!cli_session_request(&cli, desthost, 0x20, local_machine)) { + DEBUG(1,("%s rejected the session\n",desthost)); + cli_shutdown(&cli); + return NULL; + } - if (!ret || CVAL(secserver_inbuf,smb_rcls) || SVAL(secserver_inbuf,smb_vwv0)) { - DEBUG(1,("%s rejected the protocol\n",pserver)); - close(password_client); password_client= -1; - return(False); - } + DEBUG(3,("got session\n")); - if (!(CVAL(secserver_inbuf,smb_vwv1) & 1)) { - DEBUG(1,("%s isn't in user level security mode\n",pserver)); - close(password_client); password_client= -1; - return(False); - } + if (!cli_negprot(&cli)) { + DEBUG(1,("%s rejected the negprot\n",desthost)); + cli_shutdown(&cli); + return NULL; + } - memcpy(buf,secserver_inbuf,smb_len(secserver_inbuf)+4); + 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")); + DEBUG(3,("password server OK\n")); - return(True); + return &cli; } /**************************************************************************** -attempted support for server level security +validate a password with the password server ****************************************************************************/ -BOOL server_validate(char *buf) +BOOL server_validate(char *user, char *domain, + char *pass, int passlen, + char *ntpass, int ntpasslen) { - pstring outbuf; - BOOL ret; + extern fstring local_machine; + fstring share; - if(secserver_inbuf == NULL) { - secserver_inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); - if(secserver_inbuf == NULL) { - DEBUG(0,("server_validate: malloc fail for input buffer.\n")); - return False; - } - } + if (!cli.initialised) { + DEBUG(1,("password server %s is not connected\n", cli.desthost)); + return(False); + } - if (password_client < 0) { - DEBUG(1,("%s not connected\n",pserver)); - 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; + } - bzero(secserver_inbuf,BUFFER_SIZE + SAFETY_MARGIN); - memcpy(outbuf,buf,sizeof(outbuf)); + /* 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); + } - /* send a session setup command */ - CVAL(outbuf,smb_flg) = 0x8; - SSVAL(outbuf,smb_flg2,0x1); - CVAL(outbuf,smb_vwv0) = 0xFF; - set_message(outbuf,smb_numwords(outbuf),smb_buflen(outbuf),False); + sprintf(share,"\\\\%s\\IPC$", cli.desthost); - SCVAL(secserver_inbuf,smb_rcls,1); + if (!cli_send_tconX(&cli, share, "IPC", "", 1)) { + DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); + return False; + } - send_smb(password_client,outbuf); - ret = receive_smb(password_client,secserver_inbuf,5000); - if (!ret || CVAL(secserver_inbuf,smb_rcls) != 0) { - DEBUG(1,("password server %s rejected the password\n",pserver)); - 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 logged in as guest then reject */ - if ((SVAL(secserver_inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n",pserver)); - return(False); - } + if (cli.privilages == 0) { + DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); + cli_tdis(&cli); + return False; + } - DEBUG(3,("password server %s accepted the password\n",pserver)); + 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; + } -#if !KEEP_PASSWORD_SERVER_OPEN - close(password_client); password_client= -1; -#endif + DEBUG(3,("password server %s accepted the password\n", cli.desthost)); - return(True); + cli_tdis(&cli); + + return(True); } + + + diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 45acde653d9..0cb43a6fb70 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -377,8 +377,10 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) BOOL computer_id=False; static BOOL done_sesssetup = False; BOOL doencrypt = SMBENCRYPT(); + char *domain = ""; *smb_apasswd = 0; + *smb_ntpasswd = 0; smb_bufsize = SVAL(inbuf,smb_vwv2); smb_mpxmax = SVAL(inbuf,smb_vwv3); @@ -467,8 +469,10 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) p += passlen1 + passlen2; fstrcpy(user,p); p = skip_string(p,1); + domain = p; + DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", - p,skip_string(p,1),skip_string(p,2))); + domain,skip_string(p,1),skip_string(p,2))); } @@ -508,7 +512,10 @@ 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(inbuf)) && + if (!guest && !(lp_security() == SEC_SERVER && + server_validate(user, domain, + smb_apasswd, smb_apasslen, + smb_ntpasswd, smb_ntpasslen)) && !check_hosts_equiv(user)) { diff --git a/source/smbd/server.c b/source/smbd/server.c index 0c728d914ba..0eaa708520f 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -2222,22 +2222,21 @@ static int sig_cld() **************************************************************************/ static int sig_pipe() { - extern int password_client; - BlockSignals(True,SIGPIPE); + struct cli_state *cli; + BlockSignals(True,SIGPIPE); - if (password_client != -1) { - DEBUG(3,("lost connection to password server\n")); - close(password_client); - password_client = -1; + if ((cli = server_client()) && cli->initialised) { + DEBUG(3,("lost connection to password server\n")); + cli_shutdown(cli); #ifndef DONT_REINSTALL_SIG - signal(SIGPIPE, SIGNAL_CAST sig_pipe); + signal(SIGPIPE, SIGNAL_CAST sig_pipe); #endif - BlockSignals(False,SIGPIPE); - return 0; - } + BlockSignals(False,SIGPIPE); + return 0; + } - exit_server("Got sigpipe\n"); - return(0); + exit_server("Got sigpipe\n"); + return(0); } /**************************************************************************** @@ -2892,11 +2891,6 @@ int reply_lanman1(char *outbuf) int secword=0; BOOL doencrypt = SMBENCRYPT(); time_t t = time(NULL); - /* We need to save and restore this as it can be destroyed - if we call another server if security=server - Thanks to Paul Nelson @ Thursby for pointing this out. - */ - uint16 mid = SVAL(outbuf, smb_mid); if (lp_security()>=SEC_USER) secword |= 1; if (doencrypt) secword |= 2; @@ -2911,15 +2905,7 @@ int reply_lanman1(char *outbuf) Protocol = PROTOCOL_LANMAN1; - if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) { - DEBUG(3,("using password server validation\n")); -#ifdef SMB_PASSWD - if (doencrypt) set_challenge(smb_buf(outbuf)); -#endif - } - CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */ - SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */ SSVAL(outbuf,smb_vwv2,max_recv); SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */ SSVAL(outbuf,smb_vwv4,1); @@ -2943,36 +2929,45 @@ int reply_lanman2(char *outbuf) int secword=0; BOOL doencrypt = SMBENCRYPT(); time_t t = time(NULL); - /* We need to save and restore this as it can be destroyed - if we call another server if security=server - Thanks to Paul Nelson @ Thursby for pointing this out. - */ - uint16 mid = SVAL(outbuf, smb_mid); + struct cli_state *cli = NULL; + char cryptkey[8]; + char crypt_len = 0; + + if (lp_security() == SEC_SERVER) { + cli = server_cryptkey(); + } + + if (cli) { + DEBUG(3,("using password server validation\n")); + doencrypt = ((cli->sec_mode & 2) != 0); + } if (lp_security()>=SEC_USER) secword |= 1; if (doencrypt) secword |= 2; - set_message(outbuf,13,doencrypt?8:0,True); - SSVAL(outbuf,smb_vwv1,secword); + if (doencrypt) { + crypt_len = 8; + if (!cli) { #ifdef SMB_PASSWD - /* Create a token value and add it to the outgoing packet. */ - if (doencrypt) - generate_next_challenge(smb_buf(outbuf)); + generate_next_challenge(cryptkey); #endif + } else { + memcpy(cryptkey, cli->cryptkey, 8); +#ifdef SMB_PASSWD + set_challenge(cli->cryptkey); +#endif + } + } + set_message(outbuf,13,doencrypt?8:0,True); + SSVAL(outbuf,smb_vwv1,secword); SIVAL(outbuf,smb_vwv6,getpid()); + if (doencrypt) + memcpy(smb_buf(outbuf), cryptkey, 8); Protocol = PROTOCOL_LANMAN2; - if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) { - DEBUG(3,("using password server validation\n")); -#ifdef SMB_PASSWD - if (doencrypt) set_challenge(smb_buf(outbuf)); -#endif - } - CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */ - SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */ SSVAL(outbuf,smb_vwv2,max_recv); SSVAL(outbuf,smb_vwv3,lp_maxmux()); SSVAL(outbuf,smb_vwv4,1); @@ -3002,13 +2997,32 @@ int reply_nt1(char *outbuf) BOOL doencrypt = SMBENCRYPT(); time_t t = time(NULL); int data_len; - int encrypt_len; - char challenge_len = 8; - /* We need to save and restore this as it can be destroyed - if we call another server if security=server - Thanks to Paul Nelson @ Thursby for pointing this out. - */ - uint16 mid = SVAL(outbuf, smb_mid); + struct cli_state *cli = NULL; + char cryptkey[8]; + char crypt_len = 0; + + if (lp_security() == SEC_SERVER) { + cli = server_cryptkey(); + } + + if (cli) { + DEBUG(3,("using password server validation\n")); + doencrypt = ((cli->sec_mode & 2) != 0); + } + + if (doencrypt) { + crypt_len = 8; + if (!cli) { +#ifdef SMB_PASSWD + generate_next_challenge(cryptkey); +#endif + } else { + memcpy(cryptkey, cli->cryptkey, 8); +#ifdef SMB_PASSWD + set_challenge(cli->cryptkey); +#endif + } + } if (lp_readraw() && lp_writeraw()) { @@ -3021,44 +3035,18 @@ int reply_nt1(char *outbuf) /* decide where (if) to put the encryption challenge, and follow it with the OEM'd domain name */ - encrypt_len = doencrypt?challenge_len:0; -#if UNICODE - data_len = encrypt_len + 2*(strlen(myworkgroup)+1); -#else - data_len = encrypt_len + strlen(myworkgroup) + 1; -#endif + data_len = crypt_len + strlen(myworkgroup) + 1; set_message(outbuf,17,data_len,True); - -#if UNICODE - /* put the OEM'd domain name */ - PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup); -#else - strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup); -#endif + strcpy(smb_buf(outbuf)+crypt_len, myworkgroup); CVAL(outbuf,smb_vwv1) = secword; -#ifdef SMB_PASSWD - /* Create a token value and add it to the outgoing packet. */ - if (doencrypt) - { - generate_next_challenge(smb_buf(outbuf)); - - /* Tell the nt machine how long the challenge is. */ - SSVALS(outbuf,smb_vwv16+1,challenge_len); - } -#endif + SSVALS(outbuf,smb_vwv16+1,crypt_len); + if (doencrypt) + memcpy(smb_buf(outbuf), cryptkey, 8); Protocol = PROTOCOL_NT1; - if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) { - DEBUG(3,("using password server validation\n")); -#ifdef SMB_PASSWD - if (doencrypt) set_challenge(smb_buf(outbuf)); -#endif - } - - SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */ SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */ SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */ SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */ @@ -4127,16 +4115,16 @@ static void process(void) } if (keepalive && (counter-last_keepalive)>keepalive) { - extern int password_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 (password_client != -1) - send_keepalive(password_client); - last_keepalive = counter; + 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); + last_keepalive = counter; } /* check for connection timeouts */ |