summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-03-11 21:11:04 +0000
committerJeremy Allison <jra@samba.org>1998-03-11 21:11:04 +0000
commitfdeea341ed1bae670382e45eb731db1b5838ad21 (patch)
treebdbc5138a9340bdbd5c12cee243e6acfb2e64daf /source3/smbd
parent4c6230afd2f144322c07c7e4c46147d3e5d2ddde (diff)
downloadsamba-fdeea341ed1bae670382e45eb731db1b5838ad21.tar.gz
samba-fdeea341ed1bae670382e45eb731db1b5838ad21.tar.bz2
samba-fdeea341ed1bae670382e45eb731db1b5838ad21.zip
"For I have laboured mightily on Luke's code, and hath broken
all I saw" - the book of Jeremy, chapter 1 :-). So here is the mega-merge of the NTDOM branch server code. It doesn't include the new client side pieces, we'll look at that later. This should give the same functionality, server wise, as the NTDOM branch does, only merged into the main branch. Any fixes to domain controler functionality should be added to the main branch, not the NTDOM branch. This code compiles without warnings on gcc2.8, but will need further testing before we are sure all the working functionality of the NTDOM server branch has been correctly carried over. I hereby declare the server side of the NTDOM branch dead (and all who sail in her :-). Jeremy. (This used to be commit 118ba4d77a33248e762a2cf843fb7cbc906ee6e7)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/chgpasswd.c12
-rw-r--r--source3/smbd/ipc.c669
-rw-r--r--source3/smbd/password.c103
-rw-r--r--source3/smbd/pipes.c242
-rw-r--r--source3/smbd/reply.c116
-rw-r--r--source3/smbd/server.c4
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();
}