summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
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();
}