diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/chgpasswd.c | 12 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 669 | ||||
-rw-r--r-- | source3/smbd/password.c | 103 | ||||
-rw-r--r-- | source3/smbd/pipes.c | 242 | ||||
-rw-r--r-- | source3/smbd/reply.c | 116 | ||||
-rw-r--r-- | source3/smbd/server.c | 4 |
6 files changed, 676 insertions, 470 deletions
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index fb795e973e..c83ff1911c 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -422,6 +422,12 @@ BOOL check_lanman_password(char *user, unsigned char *pass1, return False; } + if(smbpw->acct_ctrl & ACB_DISABLED) + { + DEBUG(0,("check_lanman_password: account %s disabled.\n", user)); + return False; + } + if(smbpw->smb_passwd == NULL) { DEBUG(0,("check_lanman_password: no lanman password !\n")); @@ -462,6 +468,12 @@ BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsi return False; } + if(smbpw->acct_ctrl & ACB_DISABLED) + { + DEBUG(0,("change_lanman_password: account %s disabled.\n", smbpw->smb_name)); + return False; + } + if(smbpw->smb_passwd == NULL) { DEBUG(0,("change_lanman_password: no lanman password !\n")); diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 048dab8b3e..bbeeb21e96 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -27,6 +27,7 @@ */ #include "includes.h" +#include "nterr.h" #ifdef CHECK_TYPES #undef CHECK_TYPES @@ -131,79 +132,128 @@ static BOOL prefix_ok(char *str,char *prefix) return(strncmp(str,prefix,strlen(prefix)) == 0); } +/******************************************************************* + copies parameters and data, as needed, into the smb buffer + + *both* the data and params sections should be aligned. this + is fudged in the rpc pipes by + at present, only the data section is. this may be a possible + cause of some of the ipc problems being experienced. lkcl26dec97 + + ******************************************************************/ +static void copy_trans_params_and_data(char *outbuf, int align, + struct mem_buf *rparam, struct mem_buf *rdata, + int param_offset, int data_offset, + int param_len, int data_len) +{ + char *copy_into = smb_buf(outbuf); + + DEBUG(5,("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n", + param_offset, param_offset + param_len, + data_offset , data_offset + data_len)); + + if (param_len) mem_buf_copy(copy_into, rparam, param_offset, param_len); + copy_into += param_len + align; + if (data_len ) mem_buf_copy(copy_into, rdata , data_offset , data_len); +} /**************************************************************************** send a trans reply ****************************************************************************/ -static void send_trans_reply(char *outbuf,char *data,char *param,uint16 *setup, - int ldata,int lparam,int lsetup) +static void send_trans_reply(char *outbuf, + struct mem_buf *rdata, + struct mem_buf *rparam, + uint16 *setup, int lsetup, int max_data_ret) { - int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; - int align; + int i; + int this_ldata,this_lparam; + int tot_data=0,tot_param=0; + int align; + + int ldata = rdata ? mem_buf_len(rdata ) : 0; + int lparam = rparam ? mem_buf_len(rparam) : 0; - this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */ - this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam)); + BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False; + + if (buffer_too_large) + { + DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret)); + ldata = max_data_ret; + } + + this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */ + this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam)); #ifdef CONFUSE_NETMONITOR_MSRPC_DECODING - /* if you don't want Net Monitor to decode your packets, do this!!! */ - align = ((this_lparam+1)%4); + /* if you don't want Net Monitor to decode your packets, do this!!! */ + align = ((this_lparam+1)%4); #else - align = (this_lparam%4); + align = (this_lparam%4); #endif - set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True); - if (this_lparam) - memcpy(smb_buf(outbuf),param,this_lparam); - if (this_ldata) - memcpy(smb_buf(outbuf)+this_lparam+align,data,this_ldata); - - SSVAL(outbuf,smb_vwv0,lparam); - SSVAL(outbuf,smb_vwv1,ldata); - SSVAL(outbuf,smb_vwv3,this_lparam); - SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf)); - SSVAL(outbuf,smb_vwv5,0); - SSVAL(outbuf,smb_vwv6,this_ldata); - SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf)); - SSVAL(outbuf,smb_vwv8,0); - SSVAL(outbuf,smb_vwv9,lsetup); - for (i=0;i<lsetup;i++) - SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]); - - show_msg(outbuf); - send_smb(Client,outbuf); - - tot_data = this_ldata; - tot_param = this_lparam; - - while (tot_data < ldata || tot_param < lparam) - { - this_lparam = MIN(lparam-tot_param,max_send - 500); /* hack */ - this_ldata = MIN(ldata-tot_data,max_send - (500+this_lparam)); + set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True); - align = (this_lparam%4); + if (buffer_too_large) + { + /* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */ + SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + SIVAL(outbuf, smb_rcls, 0x80000000 | NT_STATUS_ACCESS_VIOLATION); + } - set_message(outbuf,10,this_ldata+this_lparam+align,False); - if (this_lparam) - memcpy(smb_buf(outbuf),param+tot_param,this_lparam); - if (this_ldata) - memcpy(smb_buf(outbuf)+this_lparam+align,data+tot_data,this_ldata); + copy_trans_params_and_data(outbuf, align, + rparam , rdata, + tot_param , tot_data, + this_lparam, this_ldata); + + SSVAL(outbuf,smb_vwv0,lparam); + SSVAL(outbuf,smb_vwv1,ldata); + SSVAL(outbuf,smb_vwv3,this_lparam); + SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf)); + SSVAL(outbuf,smb_vwv5,0); + SSVAL(outbuf,smb_vwv6,this_ldata); + SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf)); + SSVAL(outbuf,smb_vwv8,0); + SSVAL(outbuf,smb_vwv9,lsetup); + + for (i=0;i<lsetup;i++) + { + SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]); + } - SSVAL(outbuf,smb_vwv3,this_lparam); - SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf)); - SSVAL(outbuf,smb_vwv5,tot_param); - SSVAL(outbuf,smb_vwv6,this_ldata); - SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf)); - SSVAL(outbuf,smb_vwv8,tot_data); - SSVAL(outbuf,smb_vwv9,0); + show_msg(outbuf); + send_smb(Client,outbuf); - show_msg(outbuf); - send_smb(Client,outbuf); + tot_data = this_ldata; + tot_param = this_lparam; - tot_data += this_ldata; - tot_param += this_lparam; - } + while (tot_data < ldata || tot_param < lparam) + { + this_lparam = MIN(lparam-tot_param, max_send - 500); /* hack */ + this_ldata = MIN(ldata -tot_data , max_send - (500+this_lparam)); + + align = (this_lparam%4); + + set_message(outbuf,10,this_ldata+this_lparam+align,False); + + copy_trans_params_and_data(outbuf, align, + rparam , rdata, + tot_param , tot_data, + this_lparam, this_ldata); + + SSVAL(outbuf,smb_vwv3,this_lparam); + SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf)); + SSVAL(outbuf,smb_vwv5,tot_param); + SSVAL(outbuf,smb_vwv6,this_ldata); + SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf)); + SSVAL(outbuf,smb_vwv8,tot_data); + SSVAL(outbuf,smb_vwv9,0); + + show_msg(outbuf); + send_smb(Client,outbuf); + + tot_data += this_ldata; + tot_param += this_lparam; + } } struct pack_desc { @@ -1252,6 +1302,39 @@ static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data, return(True); } +/**************************************************************************** + command 0x34 - suspected of being a "Lookup Names" stub api + ****************************************************************************/ +static BOOL api_RNetGroupGetUsers(int cnum, uint16 vuid, char *param, char *data, + int mdrcnt, int mprcnt, char **rdata, + char **rparam, int *rdata_len, int *rparam_len) +{ + char *str1 = param+2; + char *str2 = skip_string(str1,1); + char *p = skip_string(str2,1); + int uLevel = SVAL(p,0); + int buf_len = SVAL(p,2); + int counted=0; + int missed=0; + + DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n", + str1, str2, p, uLevel, buf_len)); + + if (!prefix_ok(str1,"zWrLeh")) return False; + + *rdata_len = 0; + *rdata = NULL; + + *rparam_len = 8; + *rparam = REALLOC(*rparam,*rparam_len); + + SSVAL(*rparam,0,0x08AC); /* informational warning message */ + SSVAL(*rparam,2,0); + SSVAL(*rparam,4,counted); + SSVAL(*rparam,6,counted+missed); + + return(True); +} /**************************************************************************** get info about a share @@ -2185,8 +2268,11 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, char *p2; /* get NIS home of a previously validated user - simeon */ + /* With share level security vuid will always be zero. + Don't depend on vuser being non-null !!. JRA */ user_struct *vuser = get_valid_user_struct(vuid); - DEBUG(3,(" Username of UID %d is %s\n", vuser->uid, vuser->name)); + if(vuser != NULL) + DEBUG(3,(" Username of UID %d is %s\n", vuser->uid, vuser->name)); *rparam_len = 6; *rparam = REALLOC(*rparam,*rparam_len); @@ -2236,7 +2322,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, /* EEK! the cifsrap.txt doesn't have this in!!!! */ SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */ - strcpy(p2,vuser->real_name); /* simeon */ + strcpy(p2,((vuser != NULL) ? vuser->real_name : UserName)); p2 = skip_string(p2,1); } @@ -2292,7 +2378,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, { SIVAL(p,60,0); /* auth_flags */ SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */ - strcpy(p2,vuser->real_name); /* simeon */ + strcpy(p2,((vuser != NULL) ? vuser->real_name : UserName)); p2 = skip_string(p2,1); SIVAL(p,68,0); /* urs_comment */ SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */ @@ -2920,175 +3006,331 @@ static BOOL api_WPrintPortEnum(int cnum,uint16 vuid, char *param,char *data, return(True); } - -struct +struct api_cmd { - char * name; char * pipe_clnt_name; -#ifdef NTDOMAIN char * pipe_srv_name; -#endif - int subcommand; - BOOL (*fn) (); -} api_fd_commands [] = - { -#ifdef NTDOMAIN - { "TransactNmPipe", "lsarpc", "lsass", 0x26, api_ntLsarpcTNP }, - { "TransactNmPipe", "samr", "lsass", 0x26, api_samrTNP }, - { "TransactNmPipe", "srvsvc", "lsass", 0x26, api_srvsvcTNP }, - { "TransactNmPipe", "wkssvc", "ntsvcs", 0x26, api_wkssvcTNP }, - { "TransactNmPipe", "NETLOGON", "NETLOGON", 0x26, api_netlogrpcTNP }, - { NULL, NULL, NULL, -1, (BOOL (*)())api_Unsupported } -#else - { "TransactNmPipe" , "lsarpc", 0x26, api_LsarpcTNP }, - { NULL, NULL, -1, (BOOL (*)())api_Unsupported } -#endif - }; + BOOL (*fn) (pipes_struct *, prs_struct *); +}; -/**************************************************************************** - handle remote api calls delivered to a named pipe already opened. - ****************************************************************************/ -static int api_fd_reply(int cnum,uint16 vuid,char *outbuf, - uint16 *setup,char *data,char *params, - int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt) +static struct api_cmd api_fd_commands[] = { - char *rdata = NULL; - char *rparam = NULL; - int rdata_len = 0; - int rparam_len = 0; + { "lsarpc", "lsass", api_ntlsa_rpc }, + { "samr", "lsass", api_samr_rpc }, + { "srvsvc", "ntsvcs", api_srvsvc_rpc }, + { "wkssvc", "ntsvcs", api_wkssvc_rpc }, + { "NETLOGON", "lsass", api_netlog_rpc }, + { "winreg", "winreg", api_reg_rpc }, + { NULL, NULL, NULL } +}; - BOOL reply = False; - BOOL bind_req = False; - BOOL set_nphs = False; +static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +{ + BOOL ntlmssp_auth = False; + fstring ack_pipe_name; + int i = 0; - int i; - int fd; - int subcommand; - char *pipe_name; - - DEBUG(5,("api_fd_reply\n")); - /* First find out the name of this file. */ - if (suwcnt != 2) - { - DEBUG(0,("Unexpected named pipe transaction.\n")); - return(-1); - } - - /* Get the file handle and hence the file name. */ - fd = setup[1]; - subcommand = setup[0]; - pipe_name = get_rpc_pipe_hnd_name(fd); + DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); - if (pipe_name == NULL) - { - DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", fd)); - } + for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) + { + if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && + api_fd_commands[i].fn != NULL) + { + DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + api_fd_commands[i].pipe_clnt_name, + api_fd_commands[i].pipe_srv_name)); + fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name); + break; + } + } - DEBUG(3,("Got API command %d on pipe %s (fd %x)", - subcommand, pipe_name, fd)); - DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n", - tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid)); - - for (i = 0; api_fd_commands[i].name; i++) - { - if (strequal(api_fd_commands[i].pipe_clnt_name, pipe_name) && - api_fd_commands[i].subcommand == subcommand && - api_fd_commands[i].fn) - { - DEBUG(3,("Doing %s\n", api_fd_commands[i].name)); - break; - } - } - - rdata = (char *)malloc(1024); if (rdata ) bzero(rdata ,1024); - rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024); - -#ifdef NTDOMAIN - /* RPC Pipe command 0x26. */ - if (data != NULL && api_fd_commands[i].subcommand == 0x26) - { - RPC_HDR hdr; + if (api_fd_commands[i].fn == NULL) return False; - /* process the rpc header */ - char *q = smb_io_rpc_hdr(True, &hdr, data, data, 4, 0); - - /* bind request received */ - if ((bind_req = ((q != NULL) && (hdr.pkt_type == RPC_BIND)))) - { - RPC_HDR_RB hdr_rb; + /* decode the bind request */ + smb_io_rpc_hdr_rb("", &p->hdr_rb, pd, 0); - /* decode the bind request */ - char *p = smb_io_rpc_hdr_rb(True, &hdr_rb, q, data, 4, 0); + if (pd->offset == 0) return False; - if ((bind_req = (p != NULL))) - { - RPC_HDR_BA hdr_ba; - fstring ack_pipe_name; + if (p->hdr.auth_len != 0) + { + /* decode the authentication verifier */ + smb_io_rpc_auth_ntlmssp_req("", &p->ntlmssp_req, pd, 0); - /* name has to be \PIPE\xxxxx */ - strcpy(ack_pipe_name, "\\PIPE\\"); - strcat(ack_pipe_name, api_fd_commands[i].pipe_srv_name); + if (pd->offset == 0) return False; - /* make a bind acknowledgement */ - make_rpc_hdr_ba(&hdr_ba, - hdr_rb.bba.max_tsize, hdr_rb.bba.max_rsize, hdr_rb.bba.assoc_gid, - ack_pipe_name, - 0x1, 0x0, 0x0, - &(hdr_rb.transfer)); + /* ignore the version number for now */ + ntlmssp_auth = strequal(p->ntlmssp_req.ntlmssp_str, "NTLMSSP"); + } - p = smb_io_rpc_hdr_ba(False, &hdr_ba, rdata + 0x10, rdata, 4, 0); + /* name has to be \PIPE\xxxxx */ + strcpy(ack_pipe_name, "\\PIPE\\"); + strcat(ack_pipe_name, p->pipe_srv_name); - rdata_len = PTR_DIFF(p, rdata); + DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); - make_rpc_hdr(&hdr, RPC_BINDACK, 0x0, hdr.call_id, rdata_len); + prs_init(&(p->rdata), 1024, 4, 0, False); + prs_init(&(p->rhdr ), 0x10, 4, 0, False); + prs_init(&(p->rauth), 1024, 4, 0, False); - p = smb_io_rpc_hdr(False, &hdr, rdata, rdata, 4, 0); - - reply = (p != NULL); - } - } - } -#endif + /***/ + /*** do the bind ack first ***/ + /***/ - /* Set Named Pipe Handle state */ - if (subcommand == 0x1) - { - set_nphs = True; - reply = api_LsarpcSNPHS(fd, cnum, params); - } + make_rpc_hdr_ba(&p->hdr_ba, + p->hdr_rb.bba.max_tsize, + p->hdr_rb.bba.max_rsize, + p->hdr_rb.bba.assoc_gid, + ack_pipe_name, + 0x1, 0x0, 0x0, + &(p->hdr_rb.transfer)); - if (!bind_req && !set_nphs) - { - DEBUG(10,("calling api_fd_command\n")); + smb_io_rpc_hdr_ba("", &p->hdr_ba, &p->rdata, 0); + mem_realloc_data(p->rdata.data, p->rdata.offset); - reply = api_fd_commands[i].fn(cnum,vuid,params,data,mdrcnt,mprcnt, - &rdata,&rparam,&rdata_len,&rparam_len); - DEBUG(10,("called api_fd_command\n")); - } + /***/ + /*** now the authentication ***/ + /***/ - if (rdata_len > mdrcnt || rparam_len > mprcnt) - { - reply = api_TooSmall(cnum,vuid,params,data,mdrcnt,mprcnt, - &rdata,&rparam,&rdata_len,&rparam_len); - } - - /* if we get False back then it's actually unsupported */ - if (!reply) - { - api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt, - &rdata,&rparam,&rdata_len,&rparam_len); - } - - /* now send the reply */ - send_trans_reply(outbuf,rdata,rparam,NULL,rdata_len,rparam_len,0); - - if (rdata ) free(rdata ); - if (rparam) free(rparam); - - return(-1); + if (ntlmssp_auth) + { + uint8 data[16]; + bzero(data, sizeof(data)); /* first 8 bytes are non-zero */ + + make_rpc_auth_ntlmssp_resp(&p->ntlmssp_resp, + 0x0a, 0x06, 0, + "NTLMSSP", 2, + 0x00000000, 0x0000b2b3, 0x000082b1, + data); + smb_io_rpc_auth_ntlmssp_resp("", &p->ntlmssp_resp, &p->rauth, 0); + mem_realloc_data(p->rauth.data, p->rauth.offset); + } + + /***/ + /*** then do the header, now we know the length ***/ + /***/ + + make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, + p->rdata.offset + p->rauth.offset, + p->rauth.offset); + + smb_io_rpc_hdr("", &p->hdr, &p->rhdr, 0); + mem_realloc_data(p->rhdr.data, p->rdata.offset); + + /***/ + /*** link rpc header, bind acknowledgment and authentication responses ***/ + /***/ + + p->rhdr.data->offset.start = 0; + p->rhdr.data->offset.end = p->rhdr.offset; + p->rhdr.data->next = p->rdata.data; + + if (ntlmssp_auth) + { + p->rdata.data->offset.start = p->rhdr.offset; + p->rdata.data->offset.end = p->rhdr.offset + p->rdata.offset; + p->rdata.data->next = p->rauth.data; + + p->rauth.data->offset.start = p->rhdr.offset + p->rdata.offset; + p->rauth.data->offset.end = p->rhdr.offset + p->rauth.offset + p->rdata.offset; + p->rauth.data->next = NULL; + } + else + { + p->rdata.data->offset.start = p->rhdr.offset; + p->rdata.data->offset.end = p->rhdr.offset + p->rdata.offset; + p->rdata.data->next = NULL; + } + + return True; } +static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd) +{ + int i = 0; + + for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) + { + if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && + api_fd_commands[i].fn != NULL) + { + DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); + return api_fd_commands[i].fn(p, pd); + } + } + return False; +} +static BOOL api_dce_rpc_command(char *outbuf, + pipes_struct *p, + prs_struct *pd) +{ + BOOL reply = False; + if (pd->data == NULL) return False; + + /* process the rpc header */ + smb_io_rpc_hdr("", &p->hdr, pd, 0); + + if (pd->offset == 0) return False; + + switch (p->hdr.pkt_type) + { + case RPC_BIND : + { + reply = api_pipe_bind_req(p, pd); + break; + } + case RPC_REQUEST: + { + reply = api_pipe_request (p, pd); + break; + } + } + + if (reply) + { + /* now send the reply */ + send_trans_reply(outbuf, p->rhdr.data, NULL, NULL, 0, p->max_rdata_len); + + if (mem_buf_len(p->rhdr.data) <= p->max_rdata_len) + { + /* all of data was sent: no need to wait for SMBreadX calls */ + mem_free_data(p->rhdr .data); + mem_free_data(p->rdata.data); + } + } + + return reply; +} + +/**************************************************************************** + SetNamedPipeHandleState +****************************************************************************/ +static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param) +{ + uint16 id; + + if (!param) return False; + + id = param[0] + (param[1] << 8); + DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n", id)); + + if (set_rpc_pipe_hnd_state(p, id)) + { + /* now send the reply */ + send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->max_rdata_len); + + return True; + } + return False; +} + + +/**************************************************************************** + when no reply is generated, indicate unsupported. + ****************************************************************************/ +static BOOL api_no_reply(char *outbuf, int max_rdata_len) +{ + struct mem_buf rparam; + + mem_init(&rparam, 0); + mem_alloc_data(&rparam, 4); + + rparam.offset.start = 0; + rparam.offset.end = 4; + + /* unsupported */ + SSVAL(rparam.data,0,NERR_notsupported); + SSVAL(rparam.data,2,0); /* converter word */ + + DEBUG(3,("Unsupported API fd command\n")); + + /* now send the reply */ + send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len); + + mem_free_data(&rparam); + + return(-1); +} + +/**************************************************************************** + handle remote api calls delivered to a named pipe already opened. + ****************************************************************************/ +static int api_fd_reply(int cnum,uint16 vuid,char *outbuf, + uint16 *setup,char *data,char *params, + int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt) +{ + BOOL reply = False; + + int pnum; + int subcommand; + pipes_struct *p = NULL; + prs_struct pd; + struct mem_buf data_buf; + + DEBUG(5,("api_fd_reply\n")); + + /* fake up a data buffer from the api_fd_reply data parameters */ + mem_create(&data_buf, data, tdscnt, 0, False); + data_buf.offset.start = 0; + data_buf.offset.end = tdscnt; + + /* fake up a parsing structure */ + pd.data = &data_buf; + pd.align = 4; + pd.io = True; + pd.offset = 0; + + /* First find out the name of this file. */ + if (suwcnt != 2) + { + DEBUG(0,("Unexpected named pipe transaction.\n")); + return(-1); + } + + /* Get the file handle and hence the file name. */ + pnum = setup[1]; + subcommand = setup[0]; + get_rpc_pipe(pnum, &p); + + if (p != NULL) + { + DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)", + subcommand, p->name, pnum)); + DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n", + tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid)); + + /* record maximum data length that can be transmitted in an SMBtrans */ + p->max_rdata_len = mdrcnt; + + switch (subcommand) + { + case 0x26: + { + /* dce/rpc command */ + reply = api_dce_rpc_command(outbuf, p, &pd); + break; + } + case 0x01: + { + /* Set Named Pipe Handle state */ + reply = api_SNPHS(outbuf, p, params); + break; + } + } + } + else + { + DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum)); + } + + if (!reply) + { + return api_no_reply(outbuf, mdrcnt); + } + return -1; +} /**************************************************************************** the buffer was too small @@ -3145,6 +3387,7 @@ struct {"RNetShareEnum", 0, (BOOL (*)())api_RNetShareEnum,0}, {"RNetShareGetInfo", 1, (BOOL (*)())api_RNetShareGetInfo,0}, {"RNetServerGetInfo", 13, (BOOL (*)())api_RNetServerGetInfo,0}, + {"RNetGroupGetUsers", 52, (BOOL (*)())api_RNetGroupGetUsers,0}, {"RNetUserGetInfo", 56, (BOOL (*)())api_RNetUserGetInfo,0}, {"NetUserGetGroups", 59, (BOOL (*)())api_NetUserGetGroups,0}, {"NetWkstaGetInfo", 63, (BOOL (*)())api_NetWkstaGetInfo,0}, @@ -3177,6 +3420,8 @@ static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params, int tdscnt,int tpscnt,int mdrcnt,int mprcnt) { int api_command = SVAL(params,0); + struct mem_buf rdata_buf; + struct mem_buf rparam_buf; char *rdata = NULL; char *rparam = NULL; int rdata_len = 0; @@ -3216,14 +3461,20 @@ static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params, &rdata,&rparam,&rdata_len,&rparam_len); + mem_create(&rdata_buf , rdata , rdata_len , 0, False); + mem_create(&rparam_buf, rparam, rparam_len, 0, False); + + rdata_buf.offset.start = 0; + rdata_buf.offset.end = rdata_len; + + rparam_buf.offset.start = 0; + rparam_buf.offset.end = rparam_len; /* now send the reply */ - send_trans_reply(outbuf,rdata,rparam,NULL,rdata_len,rparam_len,0); + send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0); - if (rdata) - free(rdata); - if (rparam) - free(rparam); + if (rdata ) free(rdata); + if (rparam) free(rparam); return(-1); } diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a51e5f639f..b422dda36c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -877,6 +877,68 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha } /**************************************************************************** + Do a specific test for an smb password being correct, given a smb_password and + the lanman and NT responses. +****************************************************************************/ + +BOOL smb_password_ok(struct smb_passwd *smb_pass, + uchar lm_pass[24], uchar nt_pass[24]) +{ + uchar challenge[8]; + + if (!lm_pass || !smb_pass) return(False); + + if(smb_pass->acct_ctrl & ACB_DISABLED) + { + DEBUG(3,("smb_password_ok: account for user %s was disabled.\n", smb_pass->smb_name)); + return(False); + } + + if (!last_challenge(challenge)) + { + DEBUG(1,("smb_password_ok: no challenge done - password failed\n")); + return False; + } + + DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n", smb_pass->smb_name)); + + if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) + { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); + if (smb_password_check(nt_pass, smb_pass->smb_nt_passwd, challenge)) + { + DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); + return(True); + } + DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); + } + + /* Try against the lanman password. smb_pass->smb_passwd == NULL means + no password, allow access. */ + + DEBUG(4,("Checking LM MD4 password\n")); + + if((smb_pass->smb_passwd == NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ)) + { + DEBUG(4,("smb_password_ok: no password required for user %s\n", smb_pass->smb_name)); + return True; + } + + if((smb_pass->smb_passwd != NULL) && smb_password_check(lm_pass, smb_pass->smb_passwd, challenge)) + { + DEBUG(4,("smb_password_ok: LM MD4 password check succeeded\n")); + return(True); + } + + DEBUG(4,("smb_password_ok: LM MD4 password check failed\n")); + + return False; +} + +/**************************************************************************** check if a username/password is OK ****************************************************************************/ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) @@ -940,6 +1002,13 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } + /* Quit if the account was disabled. */ + if(smb_pass->acct_ctrl & ACB_DISABLED) + { + DEBUG(3,("password_ok: account for user %s was disabled.\n", user)); + return(False); + } + /* Ensure the uid's match */ if (smb_pass->smb_userid != pass->pw_uid) { @@ -947,35 +1016,13 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } - if (Protocol >= PROTOCOL_NT1) - { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - if (smb_pass->smb_nt_passwd != NULL) - { - DEBUG(4,("Checking NT MD4 password\n")); - if (smb_password_check(password, - smb_pass->smb_nt_passwd, - (unsigned char *)challenge)) - { - update_protected_database(user,True); - return(True); - } - DEBUG(4,("NT MD4 password check failed\n")); - } - } - - /* Try against the lanman password */ - - if (smb_password_check(password, - smb_pass->smb_passwd, - (unsigned char *)challenge)) { - update_protected_database(user,True); - return(True); - } + if(smb_password_ok( smb_pass, password, password)) + { + update_protected_database(user,True); + return(True); + } - DEBUG(3,("Error smb_password_check failed\n")); + DEBUG(3,("Error smb_password_check failed\n")); } DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen)); diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index b5f9700f33..4d425cc2c0 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -51,17 +51,7 @@ extern fstring myworkgroup; a packet to ensure chaining works correctly */ #define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where)) -char * known_pipes [] = -{ - "lsarpc", -#if NTDOMAIN - "NETLOGON", - "srvsvc", - "wkssvc", - "samr", -#endif - NULL -}; +extern struct pipe_id_info pipe_names[]; /**************************************************************************** reply to an open and X on a named pipe @@ -72,7 +62,8 @@ char * known_pipes [] = int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; - int cnum = SVAL(inbuf,smb_tid); + uint16 cnum = SVAL(inbuf, smb_tid); + uint16 vuid = SVAL(inbuf, smb_uid); int pnum = -1; int smb_ofun = SVAL(inbuf,smb_vwv8); int size=0,fmode=0,mtime=0,rmode=0; @@ -89,23 +80,23 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(4,("Opening pipe %s.\n", fname)); - /* Strip \PIPE\ off the name. */ - pstrcpy(fname,smb_buf(inbuf) + PIPELEN); - /* See if it is one we want to handle. */ - for( i = 0; known_pipes[i] ; i++ ) - if( strcmp(fname,known_pipes[i]) == 0 ) + for( i = 0; pipe_names[i].client_pipe ; i++ ) + if( strcmp(fname,pipe_names[i].client_pipe) == 0 ) break; - if ( known_pipes[i] == NULL ) + if ( pipe_names[i].client_pipe == NULL ) return(ERROR(ERRSRV,ERRaccess)); + /* Strip \PIPE\ off the name. */ + pstrcpy(fname,smb_buf(inbuf) + PIPELEN); + /* Known pipes arrive with DIR attribs. Remove it so a regular file */ /* can be opened and add it in after the open. */ DEBUG(3,("Known pipe %s opening.\n",fname)); smb_ofun |= 0x10; /* Add Create it not exists flag */ - pnum = open_rpc_pipe_hnd(fname, cnum); + pnum = open_rpc_pipe_hnd(fname, cnum, vuid); if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); /* Prepare the reply */ @@ -133,190 +124,65 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** - reply to a close -****************************************************************************/ -int reply_pipe_close(char *inbuf,char *outbuf) -{ - int pnum = get_rpc_pipe_num(inbuf,smb_vwv0); - int cnum = SVAL(inbuf,smb_tid); - int outsize = set_message(outbuf,0,0,True); - - DEBUG(5,("reply_pipe_close: pnum:%x cnum:%x\n", pnum, cnum)); - - if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid)); - - return(outsize); -} - - -/**************************************************************************** - api_LsarpcSNPHS + reply to a read and X - SetNamedPipeHandleState on \PIPE\lsarpc. + This code is basically stolen from reply_read_and_X with some + wrinkles to handle pipes. ****************************************************************************/ -BOOL api_LsarpcSNPHS(int pnum, int cnum, char *param) +int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) { - uint16 id; + int pnum = get_rpc_pipe_num(inbuf,smb_vwv2); + uint32 smb_offs = IVAL(inbuf,smb_vwv3); + int smb_maxcnt = SVAL(inbuf,smb_vwv5); + int smb_mincnt = SVAL(inbuf,smb_vwv6); + int cnum; + int nread = -1; + char *data; + BOOL ok = False; - if (!param) return False; + cnum = SVAL(inbuf,smb_tid); - id = param[0] + (param[1] << 8); - DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id)); - - return set_rpc_pipe_hnd_state(pnum, cnum, id); -} - - -/**************************************************************************** - api_LsarpcTNP - - TransactNamedPipe on \PIPE\lsarpc. -****************************************************************************/ -static void LsarpcTNP1(char *data,char **rdata, int *rdata_len) -{ - uint32 dword1, dword2; - char pname[] = "\\PIPE\\lsass"; +/* + CHECK_FNUM(fnum,cnum); + CHECK_READ(fnum); + CHECK_ERROR(fnum); +*/ - /* All kinds of mysterious numbers here */ - *rdata_len = 68; - *rdata = REALLOC(*rdata,*rdata_len); + set_message(outbuf,12,0,True); + data = smb_buf(outbuf); - dword1 = IVAL(data,0xC); - dword2 = IVAL(data,0x10); + nread = read_pipe(pnum, data, smb_offs, smb_maxcnt); - SIVAL(*rdata,0,0xc0005); - SIVAL(*rdata,4,0x10); - SIVAL(*rdata,8,0x44); - SIVAL(*rdata,0xC,dword1); + ok = True; - SIVAL(*rdata,0x10,dword2); - SIVAL(*rdata,0x14,0x15); - SSVAL(*rdata,0x18,sizeof(pname)); - strcpy(*rdata + 0x1a,pname); - SIVAL(*rdata,0x28,1); - memcpy(*rdata + 0x30, data + 0x34, 0x14); -} - -static void LsarpcTNP2(char *data,char **rdata, int *rdata_len) -{ - uint32 dword1; - - /* All kinds of mysterious numbers here */ - *rdata_len = 48; - *rdata = REALLOC(*rdata,*rdata_len); - - dword1 = IVAL(data,0xC); - - SIVAL(*rdata,0,0x03020005); - SIVAL(*rdata,4,0x10); - SIVAL(*rdata,8,0x30); - SIVAL(*rdata,0xC,dword1); - SIVAL(*rdata,0x10,0x18); - SIVAL(*rdata,0x1c,0x44332211); - SIVAL(*rdata,0x20,0x88776655); - SIVAL(*rdata,0x24,0xCCBBAA99); - SIVAL(*rdata,0x28,0x11FFEEDD); -} - -static void LsarpcTNP3(char *data,char **rdata, int *rdata_len) -{ - uint32 dword1; - uint16 word1; - char * workgroup = myworkgroup; - int wglen = strlen(workgroup); - int i; - - /* All kinds of mysterious numbers here */ - *rdata_len = 90 + 2 * wglen; - *rdata = REALLOC(*rdata,*rdata_len); - - dword1 = IVAL(data,0xC); - word1 = SVAL(data,0x2C); - - SIVAL(*rdata,0,0x03020005); - SIVAL(*rdata,4,0x10); - SIVAL(*rdata,8,0x60); - SIVAL(*rdata,0xC,dword1); - SIVAL(*rdata,0x10,0x48); - SSVAL(*rdata,0x18,0x5988); /* This changes */ - SSVAL(*rdata,0x1A,0x15); - SSVAL(*rdata,0x1C,word1); - SSVAL(*rdata,0x20,6); - SSVAL(*rdata,0x22,8); - SSVAL(*rdata,0x24,0x8E8); /* So does this */ - SSVAL(*rdata,0x26,0x15); - SSVAL(*rdata,0x28,0x4D48); /* And this */ - SSVAL(*rdata,0x2A,0x15); - SIVAL(*rdata,0x2C,4); - SIVAL(*rdata,0x34,wglen); - for ( i = 0 ; i < wglen ; i++ ) - (*rdata)[0x38 + i * 2] = workgroup[i]; - - /* Now fill in the rest */ - i = 0x38 + wglen * 2; - SSVAL(*rdata,i,0x648); - SIVAL(*rdata,i+2,4); - SIVAL(*rdata,i+6,0x401); - SSVAL(*rdata,i+0xC,0x500); - SIVAL(*rdata,i+0xE,0x15); - SIVAL(*rdata,i+0x12,0x2372FE1); - SIVAL(*rdata,i+0x16,0x7E831BEF); - SIVAL(*rdata,i+0x1A,0x4B454B2); -} - -static void LsarpcTNP4(char *data,char **rdata, int *rdata_len) -{ - uint32 dword1; - - /* All kinds of mysterious numbers here */ - *rdata_len = 48; - *rdata = REALLOC(*rdata,*rdata_len); + if (nread < 0) + return(UNIXERROR(ERRDOS,ERRnoaccess)); + + SSVAL(outbuf,smb_vwv5,nread); + SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); + SSVAL(smb_buf(outbuf),-2,nread); + + DEBUG(3,("%s readX pnum=%04x cnum=%d min=%d max=%d nread=%d\n", + timestring(),pnum,cnum, + smb_mincnt,smb_maxcnt,nread)); - dword1 = IVAL(data,0xC); + set_chain_pnum(pnum); - SIVAL(*rdata,0,0x03020005); - SIVAL(*rdata,4,0x10); - SIVAL(*rdata,8,0x30); - SIVAL(*rdata,0xC,dword1); - SIVAL(*rdata,0x10,0x18); + return chain_reply(inbuf,outbuf,length,bufsize); } - - -BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) +/**************************************************************************** + reply to a close +****************************************************************************/ +int reply_pipe_close(char *inbuf,char *outbuf) { - uint32 id,id2; + int pnum = get_rpc_pipe_num(inbuf,smb_vwv0); + int cnum = SVAL(inbuf,smb_tid); + int outsize = set_message(outbuf,0,0,True); - id = IVAL(data,0); + DEBUG(5,("reply_pipe_close: pnum:%x cnum:%x\n", pnum, cnum)); - DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id)); - switch (id) - { - case 0xb0005: - LsarpcTNP1(data,rdata,rdata_len); - break; + if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid)); - case 0x03000005: - id2 = IVAL(data,8); - DEBUG(4,("\t- Suboperation %lx\n",id2)); - switch (id2 & 0xF) - { - case 8: - LsarpcTNP2(data,rdata,rdata_len); - break; - - case 0xC: - LsarpcTNP4(data,rdata,rdata_len); - break; - - case 0xE: - LsarpcTNP3(data,rdata,rdata_len); - break; - } - break; - } - return(True); + return(outsize); } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 38380180f9..74cfd797c3 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -366,6 +366,74 @@ int reply_ioctl(char *inbuf,char *outbuf) #endif } +/**************************************************************************** + always return an error: it's just a matter of which one... + ****************************************************************************/ +static int session_trust_account(char *inbuf, char *outbuf, char *user, + char *smb_passwd, int smb_passlen, + char *smb_nt_passwd, int smb_nt_passlen) +{ + struct smb_passwd *smb_trust_acct = NULL; /* check if trust account exists */ + if (lp_security() == SEC_USER) + { + smb_trust_acct = get_smbpwd_entry(user, 0); + } + else + { + DEBUG(3,("Trust account %s only supported with security = user\n", user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE)); + } + + if (smb_trust_acct == NULL) + { + /* lkclXXXX: workstation entry doesn't exist */ + DEBUG(4,("Trust account %s user doesn't exist\n",user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_NO_SUCH_USER)); + } + else + { + if ((smb_passlen != 24) || (smb_nt_passlen != 24)) + { + DEBUG(4,("Trust account %s - password length wrong.\n", user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE)); + } + + if (!smb_password_ok(smb_trust_acct, smb_passwd, smb_nt_passwd)) + { + DEBUG(4,("Trust Account %s - password failed\n", user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE)); + } + + if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_DOMTRUST)) + { + DEBUG(4,("Domain trust account %s denied by server\n",user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)); + } + + if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_SVRTRUST)) + { + DEBUG(4,("Server trust account %s denied by server\n",user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT)); + } + if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_WSTRUST)) + { + DEBUG(4,("Wksta trust account %s denied by server\n", user)); + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)); + } + } + + /* don't know what to do: indicate logon failure */ + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE)); +} + /**************************************************************************** reply to a session setup command @@ -386,7 +454,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) BOOL valid_nt_password = False; pstring user; BOOL guest=False; - BOOL computer_id=False; static BOOL done_sesssetup = False; BOOL doencrypt = SMBENCRYPT(); char *domain = ""; @@ -496,48 +563,13 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* If name ends in $ then I think it's asking about whether a */ /* computer with that name (minus the $) has access. For now */ /* say yes to everything ending in $. */ - if (user[strlen(user) - 1] == '$') + if ((user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) { -#ifdef NTDOMAIN - struct smb_passwd *smb_pass; /* To check if machine account exists */ -/* - PAXX: Ack. We don't want to do this. The workstation trust account - with a $ on the end should exist in the local password database - or be mapped to something generic, but not modified. For NT - domain support we must reject this used in certain circumstances - with a code to indicate to the client that it is an invalid use - of a workstation trust account. NTWKS needs this error to join - a domain. This may be the source of future bugs if we cannot - be sure whether to reject this or not. -*/ - /* non-null user name indicates search by username not by smb userid */ - smb_pass = get_smbpwd_entry(user, 0); - - 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 */ - } - 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 */ - } - - computer_id = True; -#else /* not NTDOMAIN, leave this in. PAXX: Someone get rid of this */ - user[strlen(user) - 1] = '\0'; -#endif + return session_trust_account(inbuf, outbuf, user, + smb_apasswd, smb_apasslen, + smb_ntpasswd, smb_ntpasslen); } - /* If no username is sent use the guest account */ if (!*user) { @@ -583,7 +615,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) } if (!valid_nt_password && !password_ok(user,smb_apasswd,smb_apasslen,NULL)) { - if (!computer_id && lp_security() >= SEC_USER) { + if (lp_security() >= SEC_USER) { #if (GUEST_SESSSETUP == 0) return(ERROR(ERRSRV,ERRbadpw)); #endif @@ -643,7 +675,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) uid = pw->pw_uid; } - if (guest && !computer_id) + if (guest) SSVAL(outbuf,smb_vwv2,1); /* register the name and uid as being validated, so further connections diff --git a/source3/smbd/server.c b/source3/smbd/server.c index e290027d0a..774e5c10b9 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -3955,7 +3955,7 @@ reply for the nt protocol int reply_nt1(char *outbuf) { /* dual names + lock_and_read + nt SMBs + remote API calls */ - int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ; + int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS; /* other valid capabilities which we may support at some time... CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS; @@ -5190,10 +5190,8 @@ static void init_structs(void ) /* for RPC pipes */ init_rpc_pipe_hnd(); -#ifdef NTDOMAIN /* for LSA handles */ init_lsa_policy_hnd(); -#endif init_dptrs(); } |