From 47673b32ed4a907b380b70d5f4f366ba8be301d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 Aug 1996 15:11:34 +0000 Subject: - added FAST_SHARE_MODES code - added some named pipe code from Jim (This used to be commit c94866e9e44ea1eb72da06bc65ef1c032ae8e0c9) --- source3/smbd/pipes.c | 363 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 source3/smbd/pipes.c (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c new file mode 100644 index 0000000000..724f58e1e2 --- /dev/null +++ b/source3/smbd/pipes.c @@ -0,0 +1,363 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Pipe SMB reply routines + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + This file handles reply_ calls on named pipes that the server + makes to handle specific protocols +*/ + + +#include "includes.h" +#include "trans2.h" + +#define PIPE "\\PIPE\\" +#define PIPELEN strlen(PIPE) + +#define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024)) + +/* look in server.c for some explanation of these variables */ +extern int Protocol; +extern int DEBUGLEVEL; +extern int chain_size; +extern int maxxmit; +extern int chain_fnum; +extern char magic_char; +extern connection_struct Connections[]; +extern files_struct Files[]; +extern BOOL case_sensitive; +extern pstring sesssetup_user; +extern int Client; + +/* this macro should always be used to extract an fnum (smb_fid) from +a packet to ensure chaining works correctly */ +#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where)) + +char * known_pipes [] = +{ + "lsarpc", + NULL +}; + +/**************************************************************************** + reply to an open and X on a named pipe + + In fact what we do is to open a regular file with the same name in + /tmp. This can then be closed as normal. Reading and writing won't + make much sense, but will do *something*. The real reason for this + support is to be able to do transactions on them (well, on lsarpc + for domain login purposes...). + + This code is basically stolen from reply_open_and_X with some + wrinkles to handle pipes. +****************************************************************************/ +int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) +{ + pstring fname; + int cnum = SVAL(inbuf,smb_tid); + int fnum = -1; + int outsize = 0; + int smb_com2 = CVAL(inbuf,smb_vwv0); + int smb_off2 = SVAL(inbuf,smb_vwv1); + int smb_mode = SVAL(inbuf,smb_vwv3); + int smb_attr = SVAL(inbuf,smb_vwv5); +#if 0 + int open_flags = SVAL(inbuf,smb_vwv2); + int smb_sattr = SVAL(inbuf,smb_vwv4); + uint32 smb_time = make_unix_date3(inbuf+smb_vwv6); +#endif + int smb_ofun = SVAL(inbuf,smb_vwv8); + int unixmode; + int size=0,fmode=0,mtime=0,rmode=0; + struct stat sbuf; + int smb_action = 0; + int i; + + /* XXXX we need to handle passed times, sattr and flags */ + strcpy(fname,smb_buf(inbuf)); + + /* If the name doesn't start \PIPE\ then this is directed */ + /* at a mailslot or something we really, really don't understand, */ + /* not just something we really don't understand. */ + if ( strncmp(fname,PIPE,PIPELEN) != 0 ) + return(ERROR(ERRSRV,ERRaccess)); + + DEBUG(4,("Opening pipe %s.\n", fname)); + + /* Strip \PIPE\ off the name. */ + strcpy(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 ) + break; + + if ( known_pipes[i] == NULL ) + return(ERROR(ERRSRV,ERRaccess)); + + /* 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_attr &= ~aDIR; + Connections[cnum].read_only = 0; + smb_ofun |= 0x10; /* Add Create it not exists flag */ + + unix_convert(fname,cnum); + + fnum = find_free_file(); + if (fnum < 0) + return(ERROR(ERRSRV,ERRnofids)); + + if (!check_name(fname,cnum)) + return(UNIXERROR(ERRDOS,ERRnoaccess)); + + unixmode = unix_mode(cnum,smb_attr); + + open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode, + &rmode,&smb_action); + + if (!Files[fnum].open) + return(UNIXERROR(ERRDOS,ERRnoaccess)); + + if (fstat(Files[fnum].fd,&sbuf) != 0) { + close_file(fnum); + return(ERROR(ERRDOS,ERRnoaccess)); + } + + size = sbuf.st_size; + fmode = dos_mode(cnum,fname,&sbuf); + mtime = sbuf.st_mtime; + if (fmode & aDIR) { + close_file(fnum); + return(ERROR(ERRDOS,ERRnoaccess)); + } + + /* Prepare the reply */ + outsize = set_message(outbuf,15,0,True); + CVAL(outbuf,smb_vwv0) = smb_com2; + + /* Put things back the way they were. */ + Connections[cnum].read_only = 1; + + /* Mark the opened file as an existing named pipe in message mode. */ + SSVAL(outbuf,smb_vwv9,2); + SSVAL(outbuf,smb_vwv10,0xc700); + if (rmode == 2) + { + DEBUG(4,("Resetting open result to open from create.\n")); + rmode = 1; + } + + SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4); + SSVAL(outbuf,smb_vwv2,fnum); + SSVAL(outbuf,smb_vwv3,fmode); + put_dos_date3(outbuf,smb_vwv4,mtime); + SIVAL(outbuf,smb_vwv6,size); + SSVAL(outbuf,smb_vwv8,rmode); + SSVAL(outbuf,smb_vwv11,smb_action); + + chain_fnum = fnum; + + if (smb_com2 != 0xFF) + outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4, + outbuf,outbuf+outsize, + length,bufsize); + + chain_fnum = -1; + + DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n", + fname, fnum, Files[fnum].name)); + + return(outsize); +} + + +/**************************************************************************** + api_LsarpcSNPHS + + SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here, + so just blithely return True. This is really only for NT domain stuff, + we we're only handling that - don't assume Samba now does complete + named pipe handling. +****************************************************************************/ +BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 id; + + id = param[0] + (param[1] << 8); + DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id)); + return(True); +} + + +/**************************************************************************** + api_LsarpcTNP + + TransactNamedPipe on \PIPE\lsarpc. +****************************************************************************/ +static void LsarpcTNP1(char *data,char **rdata, int *rdata_len) +{ + uint32 dword1, dword2; + char pname[] = "\\PIPE\\lsass"; + + /* All kinds of mysterious numbers here */ + *rdata_len = 68; + *rdata = REALLOC(*rdata,*rdata_len); + + dword1 = IVAL(data,0xC); + dword2 = IVAL(data,0x10); + + SIVAL(*rdata,0,0xc0005); + SIVAL(*rdata,4,0x10); + SIVAL(*rdata,8,0x44); + SIVAL(*rdata,0xC,dword1); + + 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 = lp_workgroup(); + 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); + + dword1 = IVAL(data,0xC); + + SIVAL(*rdata,0,0x03020005); + SIVAL(*rdata,4,0x10); + SIVAL(*rdata,8,0x30); + SIVAL(*rdata,0xC,dword1); + SIVAL(*rdata,0x10,0x18); +} + + +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) +{ + uint32 id,id2; + + id = IVAL(data,0); + + DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id)); + switch (id) + { + case 0xb0005: + LsarpcTNP1(data,rdata,rdata_len); + break; + + 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); +} -- cgit From 0c33046a0aa0461a5e932dd7b0b6e38ab9708867 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 1996 11:17:29 +0000 Subject: - added "netbios name" option in smb.conf to make controlling the name that samba uses possible - added "socket address" option to allow virtual SMB servers (on systems with IP aliasing line Linux) - disabled FAST_SHARE_MODES by default in Linux as older Linux boxes can't do shared writeable mappings. We really need autoconf ... - added new option types in loadparm so a string type can be specified ot be uppercase only, this is used for the workgroup and netbios name options - auto-create the lock directory if it doesn't exist in shared mem startup - get rid of announce_backup() - change a few comments in nmbd code - rewrote the chaining code completely. Hopefully it will handle any depth chains now. - added LPRng support (This used to be commit e9eac6cd49c352349580ddb13d720cb201aecc48) --- source3/smbd/pipes.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 724f58e1e2..ffa46083c3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -35,7 +35,6 @@ /* look in server.c for some explanation of these variables */ extern int Protocol; extern int DEBUGLEVEL; -extern int chain_size; extern int maxxmit; extern int chain_fnum; extern char magic_char; @@ -72,9 +71,6 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) pstring fname; int cnum = SVAL(inbuf,smb_tid); int fnum = -1; - int outsize = 0; - int smb_com2 = CVAL(inbuf,smb_vwv0); - int smb_off2 = SVAL(inbuf,smb_vwv1); int smb_mode = SVAL(inbuf,smb_vwv3); int smb_attr = SVAL(inbuf,smb_vwv5); #if 0 @@ -149,8 +145,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) } /* Prepare the reply */ - outsize = set_message(outbuf,15,0,True); - CVAL(outbuf,smb_vwv0) = smb_com2; + set_message(outbuf,15,0,True); /* Put things back the way they were. */ Connections[cnum].read_only = 1; @@ -164,7 +159,6 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) rmode = 1; } - SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4); SSVAL(outbuf,smb_vwv2,fnum); SSVAL(outbuf,smb_vwv3,fmode); put_dos_date3(outbuf,smb_vwv4,mtime); @@ -174,17 +168,10 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) chain_fnum = fnum; - if (smb_com2 != 0xFF) - outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4, - outbuf,outbuf+outsize, - length,bufsize); - - chain_fnum = -1; - DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n", fname, fnum, Files[fnum].name)); - return(outsize); + return chain_reply(inbuf,outbuf,length,bufsize); } -- cgit From 5a2f52b79e28530c454cb488a44588147640f061 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Oct 1996 14:09:22 +0000 Subject: - a huge pile of changes from Luke which implement the browse.conf stuff and also fix a pile of nmbd bugs. Unfortunately I found it very hard to disentangle the new features from the bug fixes so I am putting in the new code. I hope this is the last big pile of changes to the 1.9.16 series! (This used to be commit 20b6203dac4bbb43e4e7bea0b214496d76d679d9) --- source3/smbd/pipes.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index ffa46083c3..35f8d684eb 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -44,6 +44,8 @@ extern BOOL case_sensitive; extern pstring sesssetup_user; extern int Client; +extern pstring local_machine; + /* this macro should always be used to extract an fnum (smb_fid) from a packet to ensure chaining works correctly */ #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where)) @@ -251,9 +253,18 @@ static void LsarpcTNP3(char *data,char **rdata, int *rdata_len) { uint32 dword1; uint16 word1; - char * workgroup = lp_workgroup(); - int wglen = strlen(workgroup); + int wglen; int i; + char domain[17]; + + char *work_alias = conf_alias_to_workgroup(local_machine); /* look-up */ + + if (work_alias) + StrnCpy(domain, work_alias, 16); + else + StrnCpy(domain, lp_workgroup(), 16); + + wglen = strlen(domain); /* All kinds of mysterious numbers here */ *rdata_len = 90 + 2 * wglen; @@ -279,7 +290,7 @@ static void LsarpcTNP3(char *data,char **rdata, int *rdata_len) SIVAL(*rdata,0x2C,4); SIVAL(*rdata,0x34,wglen); for ( i = 0 ; i < wglen ; i++ ) - (*rdata)[0x38 + i * 2] = workgroup[i]; + (*rdata)[0x38 + i * 2] = domain[i]; /* Now fill in the rest */ i = 0x38 + wglen * 2; -- cgit From afd08462ad5ff6b3c4bf621e39c55853a608175e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Oct 1996 15:41:30 +0000 Subject: backout all the changes to nmbd. The 1.9.16 tree is now back to 1.9.16p2 as far as nmbd is concerned apart from a small change that fixes the announce type in two places. (This used to be commit 45e66a69d320024877c8b13f12b21bf895e04410) --- source3/smbd/pipes.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 35f8d684eb..ffa46083c3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -44,8 +44,6 @@ extern BOOL case_sensitive; extern pstring sesssetup_user; extern int Client; -extern pstring local_machine; - /* this macro should always be used to extract an fnum (smb_fid) from a packet to ensure chaining works correctly */ #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where)) @@ -253,18 +251,9 @@ static void LsarpcTNP3(char *data,char **rdata, int *rdata_len) { uint32 dword1; uint16 word1; - int wglen; + char * workgroup = lp_workgroup(); + int wglen = strlen(workgroup); int i; - char domain[17]; - - char *work_alias = conf_alias_to_workgroup(local_machine); /* look-up */ - - if (work_alias) - StrnCpy(domain, work_alias, 16); - else - StrnCpy(domain, lp_workgroup(), 16); - - wglen = strlen(domain); /* All kinds of mysterious numbers here */ *rdata_len = 90 + 2 * wglen; @@ -290,7 +279,7 @@ static void LsarpcTNP3(char *data,char **rdata, int *rdata_len) SIVAL(*rdata,0x2C,4); SIVAL(*rdata,0x34,wglen); for ( i = 0 ; i < wglen ; i++ ) - (*rdata)[0x38 + i * 2] = domain[i]; + (*rdata)[0x38 + i * 2] = workgroup[i]; /* Now fill in the rest */ i = 0x38 + wglen * 2; -- cgit From 8bc7d6bebd4fcf8c95cb6d58da14404a5e46de91 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 9 Jan 1997 18:02:17 +0000 Subject: Makefile: Changes to split Solaris into Solaris2.3 and previous, and 2.4 and after from Paul Eggert. Makefile: Added AMIGA changes from Rask Ingemann Lambertsen . charset.c: Patch for Western European Languages from Josef Hinteregger charset.h: Patch for Western European Languages from Josef Hinteregger clitar.c: Patch to re-sync after read fail from (lost contributor name, sorry). includes.h: Patch for AMIGA from Rask Ingemann Lambertsen includes.h: Patch for SunOS atexit by Jeremy (jra@cygnus.com) interface.c: Patch for AMIGA from Rask Ingemann Lambertsen kanji.h: Patch for Western European Languages from Josef Hinteregger locking.c: Patch to fix file locking from Jeremy (jra@cygnus.com) locking.c: Patch to add granularity of lock files to usec by Jeremy (jra@cygnus.com) pipes.c: Patch to fix file locking from Jeremy (jra@cygnus.com) proto.h: Patch to fix file locking from Jeremy (jra@cygnus.com) reply.c: Patch to fix file locking from Jeremy (jra@cygnus.com) server.c: Patch to fix file locking from Jeremy (jra@cygnus.com) server.c: Patch for FAST_SHARE_MODE fix from (lost contributor name, sorry). smb.h: Patch to fix file locking from Jeremy (jra@cygnus.com) smb.h: Patch to add granularity of lock files to usec by Jeremy (jra@cygnus.com) status.c: Patch to fix file locking from Jeremy (jra@cygnus.com) statuc.c: Patch to add granularity of lock files to usec by Jeremy (jra@cygnus.com) system.c: Patch for Western European Languages from Josef Hinteregger trans2.c: Patch to fix file locking from Jeremy (jra@cygnus.com) trans2.c: Patch to fix volume name reported to Win95 from Jeremy (jra@cygnus.com) util.c: Patch for Western European Languages from Josef Hinteregger util.c: Patch to fix client_name from continuously returning UNKNOWN (from various contributors). version.h: Update to 1.9.16p10. (This used to be commit 03d28fa32eb094affa33133ebe2602fdb70f6361) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index ffa46083c3..cb498a6195 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -131,7 +131,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (!Files[fnum].open) return(UNIXERROR(ERRDOS,ERRnoaccess)); - if (fstat(Files[fnum].fd,&sbuf) != 0) { + if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { close_file(fnum); return(ERROR(ERRDOS,ERRnoaccess)); } -- cgit From 586c6276ec78c9ee276e3d01ba017db14c30e0ce Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Mon, 13 Jan 1997 19:41:08 +0000 Subject: Added an extra parameter for unix_convert. If present this is the last component of the modified pathname before modification. This is needed due to an exceptional condition in reply_mv when the filesystem is case preserving, but not case sensitive and the user wants to change the case of a filename. Code for this is also added to reply.c Jeremy (jra@cygnus.com). (This used to be commit cdafa35f9dba6eb0073700e3a214348c432a3e84) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index cb498a6195..efa6a68b9d 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -114,7 +114,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) Connections[cnum].read_only = 0; smb_ofun |= 0x10; /* Add Create it not exists flag */ - unix_convert(fname,cnum); + unix_convert(fname,cnum,0); fnum = find_free_file(); if (fnum < 0) -- cgit From da0a56a278232bad50ea0dd05de3b06299d66234 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 28 Feb 1997 20:39:36 +0000 Subject: Split maxxmit parameter into two : max_send (auto configured by the connecting client, as per CIFS4) and max_recv, which can be configured as the old maxxmit was. Fixes problems with NT directory listings when maxxmit is set very small. jra@cygnus.com (This used to be commit c2d5d1040a933987a0c39545bb5bf8e2fc400a87) --- source3/smbd/pipes.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index efa6a68b9d..06f3aeb0fb 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -35,7 +35,6 @@ /* look in server.c for some explanation of these variables */ extern int Protocol; extern int DEBUGLEVEL; -extern int maxxmit; extern int chain_fnum; extern char magic_char; extern connection_struct Connections[]; -- cgit From 0f1f0ceb9519368188f695e18e2341ccfd1b2d15 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 8 May 1997 01:14:17 +0000 Subject: 'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 06f3aeb0fb..634d7af7f4 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Pipe SMB reply routines - Copyright (C) Andrew Tridgell 1992-1995 + Copyright (C) Andrew Tridgell 1992-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From aa864415c5183c948fe9ae221023d40265c38013 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 20 May 1997 00:32:51 +0000 Subject: dir.c: Fixed double slash issue. includes.h: Changed to ifdef FAST_SHARE_MODES. ipc.c: Changed lp_workgroup() to myworkgroup. loadparm.c: Added new shared mem parameters. Added Luke's fix. locking.c: Rewrite to do share modes better (both fast and slow modes). nameannounce.c: Changed lp_workgroup() to myworkgroup. Added Luke's fix. nameconf.c: Changed lp_workgroup() to myworkgroup. namedbname.c: Improved debug. namedbserver.c: Changed lp_workgroup() to myworkgroup. namedbsubnet.c: Added Luke's fix - rewritten somewhat. namedbwork.c: Changed lp_workgroup() to myworkgroup. nameelect.c: Added Luke's fix - rewritten somewhat. nameresp.c: Stoped shadowing global. nameserv.c: Added Luke's fix - Improved debug. nameservreply.c: Improved debug. namework.c: Changed lp_workgroup() to myworkgroup. nmbd.c: Added Luke's fix - Changed lp_workgroup() to myworkgroup. pipes.c: Changed lp_workgroup() to myworkgroup. proto.h: Added Luke's fix, added smb_shm_ proto's. reply.c: Changed lp_workgroup() to myworkgroup. server.c: Rewrite to do share modes better (both fast and slow modes). shmem.c: Rewrite to do share modes better (both fast and slow modes). smb.h: Rewrite to do share modes better (both fast and slow modes). status.c: Rewrite to do share modes better (both fast and slow modes). trans2.c: Fixed double slash issue. util.c: Tidied up, created myworkgroup. Jeremy Allison (jallison@whistle.com). (This used to be commit 2a1711eaaf08bb6776770cd3c96b3010f431a677) --- source3/smbd/pipes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 634d7af7f4..a294ee4f49 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -42,6 +42,7 @@ extern files_struct Files[]; extern BOOL case_sensitive; extern pstring sesssetup_user; extern int Client; +extern fstring myworkgroup; /* this macro should always be used to extract an fnum (smb_fid) from a packet to ensure chaining works correctly */ @@ -250,7 +251,7 @@ static void LsarpcTNP3(char *data,char **rdata, int *rdata_len) { uint32 dword1; uint16 word1; - char * workgroup = lp_workgroup(); + char * workgroup = myworkgroup; int wglen = strlen(workgroup); int i; -- cgit From 46dbd8c06009ad9e64251ae844fb16f2a30f5ab7 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 20 Aug 1997 20:32:23 +0000 Subject: Changes to allow Samba to return the same error code as Windows NT. Takes care of the cases where a Windows program is parsing a pathname component by component and expects 2 different errors. ERRbadpath - if a component in the path doesn't exist. ERRbaddirectory - if a component in the path exists but is not a directory. Extra error code added to smb.h to support this. Code based on suggestions from "Christian Groessler" . Jeremy (jallison@whistle.com) (This used to be commit 28b3c6db8a81b41b448a4f3cd98e9cd2c4b5fb2e) --- source3/smbd/pipes.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index a294ee4f49..afab7e1d91 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -84,6 +84,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) struct stat sbuf; int smb_action = 0; int i; + BOOL bad_path = False; /* XXXX we need to handle passed times, sattr and flags */ strcpy(fname,smb_buf(inbuf)); @@ -114,7 +115,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) Connections[cnum].read_only = 0; smb_ofun |= 0x10; /* Add Create it not exists flag */ - unix_convert(fname,cnum,0); + unix_convert(fname,cnum,0,&bad_path); fnum = find_free_file(); if (fnum < 0) @@ -129,7 +130,15 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) &rmode,&smb_action); if (!Files[fnum].open) + { + /* Change the error code if bad_path was set. */ + if((errno == ENOENT) && bad_path) + { + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRbadpath; + } return(UNIXERROR(ERRDOS,ERRnoaccess)); + } if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { close_file(fnum); -- cgit From cef59090bb2fd3f8a9efd1a453cb90264b891d58 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 18:55:29 +0000 Subject: Adding Andrews buffer overflow fixes into the main branch. Jeremy (jallison@whistle.com) (This used to be commit e7eb1f044d3101679dc7a118820ea5efe0cd837c) --- source3/smbd/pipes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index afab7e1d91..feb8d91a5b 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -87,7 +87,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) BOOL bad_path = False; /* XXXX we need to handle passed times, sattr and flags */ - strcpy(fname,smb_buf(inbuf)); + pstrcpy(fname,smb_buf(inbuf)); /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ @@ -98,7 +98,7 @@ 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. */ - strcpy(fname,smb_buf(inbuf) + PIPELEN); + pstrcpy(fname,smb_buf(inbuf) + PIPELEN); /* See if it is one we want to handle. */ for( i = 0; known_pipes[i] ; i++ ) -- cgit From dff16872ca39c007d32d114af82d3ccd97f9d47a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 19:26:56 +0000 Subject: Syncing up current oplock work in progress. #ifdef'ed out so should have no effect on other work. Jeremy (jallison@whistle.com) (This used to be commit 7e3d4c8b21f63a06d32605d230129e36883ad08c) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index feb8d91a5b..a465e91145 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -127,7 +127,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) unixmode = unix_mode(cnum,smb_attr); open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode, - &rmode,&smb_action); + 0, &rmode,&smb_action); if (!Files[fnum].open) { -- cgit From a3b7bdd7b997fd6d41b8b96676eb58471112d931 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 7 Oct 1997 14:58:07 +0000 Subject: pipes.c: some routines to create LSA RPC packets. none of them are used. lsaparse.c: smbparse.c: smb.h: more tidy-up. (This used to be commit b37e21273e81b875876e8e8ddf6804714044ffd8) --- source3/smbd/pipes.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 237 insertions(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index a465e91145..0fb8a89c9e 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -2,7 +2,9 @@ Unix SMB/Netbios implementation. Version 1.9. Pipe SMB reply routines - Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Andrew Tridgell 1992-1997, + Paul Ashton 1997, + Luke Kenneth Casson Leighton 1996-1997. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,6 +53,9 @@ a packet to ensure chaining works correctly */ char * known_pipes [] = { "lsarpc", +#if 0 + "NETLOGON", +#endif NULL }; @@ -357,3 +362,234 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, } return(True); } + +/* + PAXX: Someone fix above. + The above API is indexing RPC calls based on RPC flags and + fragment length. I've decided to do it based on operation number :-) +*/ + +/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ +/* identauth >= 2^32 can be detected because it will be specified in hex */ +static void init_dom_sid(DOM_SID *sid, char *domsid) +{ + int identauth; + char *p; + + DEBUG(4,("netlogon domain SID: %s\n", domsid)); + + /* assume, but should check, that domsid starts "S-" */ + p = strtok(domsid+2,"-"); + sid->sid_no = atoi(p); + + /* identauth in decimal should be < 2^32 */ + /* identauth in hex should be >= 2^32 */ + identauth = atoi(strtok(0,"-")); + + DEBUG(4,("netlogon rev %d\n", sid->sid_no)); + DEBUG(4,("netlogon %s ia %d\n", p, identauth)); + + sid->id_auth[0] = 0; + sid->id_auth[1] = 0; + sid->id_auth[2] = (identauth & 0xff000000) >> 24; + sid->id_auth[3] = (identauth & 0x00ff0000) >> 16; + sid->id_auth[4] = (identauth & 0x0000ff00) >> 8; + sid->id_auth[5] = (identauth & 0x000000ff); + + sid->num_auths = 0; + + while ((p = strtok(0, "-")) != NULL) + { + sid->sub_auths[sid->num_auths++] = atoi(p); + } +} + +static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) +{ + if (hdr == NULL) return; + + hdr->major = 5; /* RPC version 5 */ + hdr->minor = 0; /* minor version 0 */ + hdr->pkt_type = 2; /* RPC response packet */ + hdr->frag = 3; /* first frag + last frag */ + hdr->pack_type = 1; /* packed data representation */ + hdr->frag_len = data_len; /* fragment length, fill in later */ + hdr->auth_len = 0; /* authentication length */ + hdr->call_id = call_id; /* call identifier - match incoming RPC */ + hdr->alloc_hint = data_len - 0x18; /* allocation hint (no idea) */ + hdr->context_id = 0; /* presentation context identifier */ + hdr->cancel_count = 0; /* cancel count */ + hdr->reserved = 0; /* reserved */ +} + +static void init_rpc_reply(char *inbuf, char *q, char *base, int data_len) +{ + uint32 callid = RIVAL(inbuf, 12); + RPC_HDR hdr; + + create_rpc_reply(&hdr, callid, data_len); + smb_io_rpc_hdr(False, &hdr, q, base, 4); +} + +static int lsa_reply_open_policy(char *q, char *base) +{ + char *start = q; + LSA_R_OPEN_POL r_o; + + /* set up the LSA QUERY INFO response */ + bzero(&(r_o.pol.data), POL_HND_SIZE); + r_o.status = 0x0; + + /* store the response in the SMB stream */ + q = lsa_io_r_open_pol(False, &r_o, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + +static void init_unistr2(UNISTR2 *str, char *buf, int len, char terminate) +{ + /* set up string lengths. add one if string is not null-terminated */ + str->uni_max_len = len + (terminate != 0 ? 1 : 0); + str->undoc = 0; + str->uni_str_len = len; + + /* store the string (null-terminated copy) */ + PutUniCode((char *)str->buffer, buf); + + /* overwrite the last character: some strings are terminated with 4 not 0 */ + str->buffer[len] = (uint16)terminate; +} + +static void init_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) +{ + int domlen = strlen(dom_name); + + d_q->uni_dom_max_len = domlen * 2; + d_q->padding = 0; + d_q->uni_dom_str_len = domlen * 2; + + d_q->buffer_dom_name = 0; /* domain buffer pointer */ + d_q->buffer_dom_sid = 0; /* domain sid pointer */ + + /* NOT null-terminated: 4-terminated instead! */ + init_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4); + + init_dom_sid(&(d_q->dom_sid), dom_sid); +} + +static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, + char *dom_name, char *dom_sid) +{ + char *start = q; + LSA_R_QUERY_INFO r_q; + + /* set up the LSA QUERY INFO response */ + + r_q.undoc_buffer = 1; /* not null */ + r_q.info_class = q_q->info_class; + + init_dom_query(&r_q.dom.id5, dom_name, dom_sid); + + r_q.status = 0x0; + + /* store the response in the SMB stream */ + q = lsa_io_r_query(False, &r_q, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + +static void init_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, char chal[8], int status) +{ + memcpy(r_c->srv_chal.data, chal, sizeof(r_c->srv_chal.data)); + r_c->status = status; +} + +#if 0 + char chal[8]; + /* PAXX: set these to random values */ + for (int i = 0; i < 8; i+++) + { + chal[i] = 0xA5; + } +#endif + +static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, + char chal[8]) +{ + char *start = q; + LSA_R_REQ_CHAL r_c; + + /* set up the LSA REQUEST CHALLENGE response */ + + init_lsa_r_req_chal(&r_c, chal, 0); + + /* store the response in the SMB stream */ + q = lsa_io_r_req_chal(False, &r_c, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + +static void init_lsa_chal(DOM_CHAL *cred, char resp_cred[8]) +{ + memcpy(cred->data, resp_cred, sizeof(cred->data)); +} + +static void init_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, + char resp_cred[8], NEG_FLAGS *flgs, int status) +{ + init_lsa_chal(&(r_a->srv_chal), resp_cred); + memcpy(&(r_a->srv_flgs), flgs, sizeof(r_a->srv_flgs)); + r_a->status = status; +} + +static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, + char resp_cred[8], int status) +{ + char *start = q; + LSA_R_AUTH_2 r_a; + + /* set up the LSA AUTH 2 response */ + + init_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status); + + /* store the response in the SMB stream */ + q = lsa_io_r_auth_2(False, &r_a, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + +static void init_lsa_dom_chal(DOM_CRED *cred, char srv_chal[8], UTIME srv_time) +{ + init_lsa_chal(&(cred->challenge), srv_chal); + cred->timestamp = srv_time; +} + + +static void init_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, + char srv_chal[8], UTIME srv_time, int status) +{ + init_lsa_dom_chal(&(r_a->srv_cred), srv_chal, srv_time); + r_a->status = status; +} + +static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, + char srv_cred[8], UTIME srv_time, + int status) +{ + char *start = q; + LSA_R_SRV_PWSET r_s; + + /* set up the LSA Server Password Set response */ + init_lsa_r_srv_pwset(&r_s, srv_cred, srv_time, status); + + /* store the response in the SMB stream */ + q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + -- cgit From 577ae65ca562ec05849a2e9e79689d00e0a0bcf2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 7 Oct 1997 18:18:10 +0000 Subject: pipes.c: more static unused functions in pipes.c for the LSA RPC stream. smb.h: corrections and altercations over the documentation lsaparse.c: reflecting alterations in LSA structures... (This used to be commit bef12478d212a950578843d6d4dece1f153bfd25) --- source3/smbd/pipes.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 182 insertions(+), 18 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 0fb8a89c9e..95b69ef4d9 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -28,6 +28,7 @@ #include "includes.h" #include "trans2.h" +#include "nterr.h" #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) @@ -371,7 +372,7 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ /* identauth >= 2^32 can be detected because it will be specified in hex */ -static void init_dom_sid(DOM_SID *sid, char *domsid) +static void make_dom_sid(DOM_SID *sid, char *domsid) { int identauth; char *p; @@ -422,7 +423,7 @@ static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) hdr->reserved = 0; /* reserved */ } -static void init_rpc_reply(char *inbuf, char *q, char *base, int data_len) +static void make_rpc_reply(char *inbuf, char *q, char *base, int data_len) { uint32 callid = RIVAL(inbuf, 12); RPC_HDR hdr; @@ -447,7 +448,14 @@ static int lsa_reply_open_policy(char *q, char *base) return q - start; } -static void init_unistr2(UNISTR2 *str, char *buf, int len, char terminate) +static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate) +{ + hdr->uni_max_len = max_len; + hdr->uni_str_len = len; + hdr->undoc = terminate; +} + +static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate) { /* set up string lengths. add one if string is not null-terminated */ str->uni_max_len = len + (terminate != 0 ? 1 : 0); @@ -461,7 +469,7 @@ static void init_unistr2(UNISTR2 *str, char *buf, int len, char terminate) str->buffer[len] = (uint16)terminate; } -static void init_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) +static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) { int domlen = strlen(dom_name); @@ -473,9 +481,9 @@ static void init_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) d_q->buffer_dom_sid = 0; /* domain sid pointer */ /* NOT null-terminated: 4-terminated instead! */ - init_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4); + make_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4); - init_dom_sid(&(d_q->dom_sid), dom_sid); + make_dom_sid(&(d_q->dom_sid), dom_sid); } static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, @@ -489,7 +497,7 @@ static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, r_q.undoc_buffer = 1; /* not null */ r_q.info_class = q_q->info_class; - init_dom_query(&r_q.dom.id5, dom_name, dom_sid); + make_dom_query(&r_q.dom.id5, dom_name, dom_sid); r_q.status = 0x0; @@ -500,7 +508,7 @@ static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, return q - start; } -static void init_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, char chal[8], int status) +static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, char chal[8], int status) { memcpy(r_c->srv_chal.data, chal, sizeof(r_c->srv_chal.data)); r_c->status = status; @@ -523,7 +531,7 @@ static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, /* set up the LSA REQUEST CHALLENGE response */ - init_lsa_r_req_chal(&r_c, chal, 0); + make_lsa_r_req_chal(&r_c, chal, 0); /* store the response in the SMB stream */ q = lsa_io_r_req_chal(False, &r_c, q, base, 4); @@ -532,15 +540,15 @@ static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, return q - start; } -static void init_lsa_chal(DOM_CHAL *cred, char resp_cred[8]) +static void make_lsa_chal(DOM_CHAL *cred, char resp_cred[8]) { memcpy(cred->data, resp_cred, sizeof(cred->data)); } -static void init_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, +static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, char resp_cred[8], NEG_FLAGS *flgs, int status) { - init_lsa_chal(&(r_a->srv_chal), resp_cred); + make_lsa_chal(&(r_a->srv_chal), resp_cred); memcpy(&(r_a->srv_flgs), flgs, sizeof(r_a->srv_flgs)); r_a->status = status; } @@ -553,7 +561,7 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, /* set up the LSA AUTH 2 response */ - init_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status); + make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status); /* store the response in the SMB stream */ q = lsa_io_r_auth_2(False, &r_a, q, base, 4); @@ -562,17 +570,17 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, return q - start; } -static void init_lsa_dom_chal(DOM_CRED *cred, char srv_chal[8], UTIME srv_time) +static void make_lsa_dom_chal(DOM_CRED *cred, char srv_chal[8], UTIME srv_time) { - init_lsa_chal(&(cred->challenge), srv_chal); + make_lsa_chal(&(cred->challenge), srv_chal); cred->timestamp = srv_time; } -static void init_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, +static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, char srv_chal[8], UTIME srv_time, int status) { - init_lsa_dom_chal(&(r_a->srv_cred), srv_chal, srv_time); + make_lsa_dom_chal(&(r_a->srv_cred), srv_chal, srv_time); r_a->status = status; } @@ -584,7 +592,7 @@ static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, LSA_R_SRV_PWSET r_s; /* set up the LSA Server Password Set response */ - init_lsa_r_srv_pwset(&r_s, srv_cred, srv_time, status); + make_lsa_r_srv_pwset(&r_s, srv_cred, srv_time, status); /* store the response in the SMB stream */ q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4); @@ -593,3 +601,159 @@ static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, return q - start; } +static void make_lsa_user_info(LSA_USER_INFO *usr, + + NTTIME *logon_time, + NTTIME *logoff_time, + NTTIME *kickoff_time, + NTTIME *pass_last_set_time, + NTTIME *pass_can_change_time, + NTTIME *pass_must_change_time, + + char *user_name, + char *full_name, + char *logon_script, + char *profile_path, + char *home_dir, + char *dir_drive, + + uint16 logon_count, + uint16 bad_pw_count, + + uint32 user_id, + uint32 group_id, + uint32 num_groups, + DOM_GID *gids, + uint32 user_flgs, + + char sess_key[16], + + char *logon_srv, + char *logon_dom, + + char *dom_sid, + char *other_sids) /* space-delimited set of SIDs */ +{ + /* only cope with one "other" sid, right now. */ + /* need to count the number of space-delimited sids */ + int i; + int num_other_sids = other_sids != NULL ? 1 : 0; + + int len_user_name = strlen(user_name ); + int len_full_name = strlen(full_name ); + int len_logon_script = strlen(logon_script); + int len_profile_path = strlen(profile_path); + int len_home_dir = strlen(home_dir ); + int len_dir_drive = strlen(dir_drive ); + + int len_logon_srv = strlen(logon_srv); + int len_logon_dom = strlen(logon_dom); + + usr->undoc_buffer = 1; /* yes, we're bothering to put USER_INFO data here */ + + usr->logon_time = *logon_time; + usr->logoff_time = *logoff_time; + usr->kickoff_time = *kickoff_time; + usr->pass_last_set_time = *pass_last_set_time; + usr->pass_can_change_time = *pass_can_change_time; + usr->pass_must_change_time = *pass_must_change_time; + + make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 4); + make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4); + make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4); + make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4); + make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4); + make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4); + + usr->logon_count = logon_count; + usr->bad_pw_count = bad_pw_count; + + usr->user_id = user_id; + usr->group_id = group_id; + usr->num_groups = num_groups; + usr->buffer_groups = num_groups ? 1 : 0; /* yes, we're bothering to put group info in */ + usr->user_flgs = user_flgs; + + if (sess_key != NULL) + { + memcpy(usr->sess_key, sess_key, sizeof(usr->sess_key)); + } + else + { + bzero(usr->sess_key, sizeof(usr->sess_key)); + } + + make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4); + make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4); + + usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */ + + bzero(usr->padding, sizeof(usr->padding)); + + usr->num_other_sids = num_other_sids; + usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0; + + make_unistr2(&(usr->uni_user_name ), user_name , len_user_name , 0); + make_unistr2(&(usr->uni_full_name ), full_name , len_full_name , 0); + make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script, 0); + make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path, 0); + make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir , 0); + make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive , 0); + + usr->num_groups2 = num_groups; + for (i = 0; i < num_groups; i++) + { + usr->gids[i] = gids[i]; + } + + make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv, 0); + make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom, 0); + + make_dom_sid(&(usr->dom_sid), dom_sid); + make_dom_sid(&(usr->other_sids[0]), other_sids); +} + + +static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, + char srv_cred[8], UTIME srv_time, + LSA_USER_INFO *user_info) +{ + char *start = q; + LSA_R_SAM_LOGON r_s; + + /* XXXX maybe we want to say 'no', reject the client's credentials */ + r_s.buffer_creds = 1; /* yes, we have valid server credentials */ + make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time); + + /* store the user information, if there is any. */ + r_s.user = user_info; + r_s.buffer_user = user_info != NULL ? 1 : 0; + r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER); + + /* store the response in the SMB stream */ + q = lsa_io_r_sam_logon(False, &r_s, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + + +static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, + char srv_cred[8], UTIME srv_time, + uint32 status) +{ + char *start = q; + LSA_R_SAM_LOGOFF r_s; + + /* XXXX maybe we want to say 'no', reject the client's credentials */ + r_s.buffer_creds = 1; /* yes, we have valid server credentials */ + make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time); + + r_s.status = status; + + /* store the response in the SMB stream */ + q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} -- cgit From fb27bc139f8d321e50471c595b65b277ee114801 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Oct 1997 18:46:19 +0000 Subject: locking.c: Added fix for race condition in slow share mode code. lsaparse.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. pipes.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. server.c: Fixed last known oplock race condition. smb.h: Re-removed USE_OPLOCK defines - someone checked in an old version. smbparse.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. Jeremy (jallison@whistle.com) (This used to be commit 1e1366ddc5542283a37debdf830ca139bbade1b0) --- source3/smbd/pipes.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 95b69ef4d9..ffa64a4e80 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -364,6 +364,8 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, return(True); } +#if 0 /* HAVING TO DO THIS TO GET THINGS TO COMPILE - LUKE PLEASE CHECK THIS !!! */ + /* PAXX: Someone fix above. The above API is indexing RPC calls based on RPC flags and @@ -757,3 +759,5 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, /* return length of SMB data stored */ return q - start; } + +#endif /* LUKE PLEASE CHECK THIS !! */ -- cgit From 827aa6bc6ad8e73a9100c2ae4cad3f0da8a29a58 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 8 Oct 1997 11:47:46 +0000 Subject: updating lsaparse.c and smbparse.c in line with changes to pipes.c and smb.h from yesterday. (This used to be commit 0b7049fae25957851a7f33d2bd500d8ecefc1ad5) --- source3/smbd/pipes.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index ffa64a4e80..95b69ef4d9 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -364,8 +364,6 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, return(True); } -#if 0 /* HAVING TO DO THIS TO GET THINGS TO COMPILE - LUKE PLEASE CHECK THIS !!! */ - /* PAXX: Someone fix above. The above API is indexing RPC calls based on RPC flags and @@ -759,5 +757,3 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, /* return length of SMB data stored */ return q - start; } - -#endif /* LUKE PLEASE CHECK THIS !! */ -- cgit From 8871297885050911aaa802c4e90e282c44e49b84 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 8 Oct 1997 17:12:07 +0000 Subject: loadparm.c proto.h: added lp_domainsid() lsaparse.c smb.h: debugging structures and parsing functions pipes.c: finally got to the functions that will go into the RPC switch statement. (This used to be commit d15aed8a9c58a7cc90befaee2d5a2752708f9327) --- source3/smbd/pipes.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 95b69ef4d9..06b785bd87 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -423,13 +423,13 @@ static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) hdr->reserved = 0; /* reserved */ } -static void make_rpc_reply(char *inbuf, char *q, char *base, int data_len) +static void make_rpc_reply(char *inbuf, char *q, int data_len) { uint32 callid = RIVAL(inbuf, 12); RPC_HDR hdr; create_rpc_reply(&hdr, callid, data_len); - smb_io_rpc_hdr(False, &hdr, q, base, 4); + smb_io_rpc_hdr(False, &hdr, q, q, 4); } static int lsa_reply_open_policy(char *q, char *base) @@ -455,6 +455,18 @@ static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate) hdr->undoc = terminate; } +static void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate) +{ + make_uni_hdr(&(hdr->unihdr), max_len, len, terminate); + hdr->undoc_buffer = len > 0 ? 1 : 0; +} + +static void make_unistr(UNISTR *str, char *buf) +{ + /* store the string (null-terminated copy) */ + PutUniCode((char *)(str->buffer), buf); +} + static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate) { /* set up string lengths. add one if string is not null-terminated */ @@ -469,6 +481,16 @@ static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate) str->buffer[len] = (uint16)terminate; } +static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str) +{ + int len_sid_str = strlen(sid_str); + + sid2->type = 0x5; + sid2->undoc = 0; + make_uni_hdr2(&(sid2->hdr), len_sid_str, len_sid_str, 0); + make_unistr (&(sid2->str), sid_str); +} + static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) { int domlen = strlen(dom_name); @@ -508,6 +530,79 @@ static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, return q - start; } +/* pretty much hard-coded choice of "other" sids, unfortunately... */ +static void make_dom_ref(DOM_R_REF *ref, + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + int len_dom_name = strlen(dom_name); + int len_other_sid1 = strlen(other_sid1); + int len_other_sid2 = strlen(other_sid2); + int len_other_sid3 = strlen(other_sid3); + + ref->undoc_buffer = 1; + ref->num_ref_doms_1 = 4; + ref->buffer_dom_name = 1; + ref->max_entries = 32; + ref->num_ref_doms_2 = 4; + + make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0); + make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0); + make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0); + make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0); + + if (dom_name != NULL) + { + make_unistr(&(ref->uni_dom_name), dom_name); + } + + make_dom_sid(&(ref->ref_dom[0]), dom_sid ); + make_dom_sid(&(ref->ref_dom[1]), other_sid1); + make_dom_sid(&(ref->ref_dom[2]), other_sid2); + make_dom_sid(&(ref->ref_dom[3]), other_sid3); +} + +static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, + int num_entries, char *dom_sids[MAX_LOOKUP_SIDS], + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + int i; + + make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid, + other_sid1, other_sid2, other_sid3); + + r_l->num_entries = num_entries; + r_l->undoc_buffer = 1; + r_l->num_entries2 = num_entries; + + for (i = 0; i < num_entries; i++) + { + make_dom_sid2(&(r_l->dom_sid[i]), dom_sids[i]); + } + + r_l->num_entries3 = num_entries; +} + +static int lsa_reply_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, char *q, char *base, + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + char *start = q; + LSA_R_LOOKUP_SIDS r_l; + + /* set up the LSA Lookup SIDs response */ + make_reply_lookup_sids(&r_l, 0, NULL, /* q_l->num_entries, q_l->dom_sids, */ + dom_name, dom_sid, other_sid1, other_sid2, other_sid3); + r_l.status = 0x0; + + /* store the response in the SMB stream */ + q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, char chal[8], int status) { memcpy(r_c->srv_chal.data, chal, sizeof(r_c->srv_chal.data)); @@ -757,3 +852,44 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, /* return length of SMB data stored */ return q - start; } + + +static void api_lsa_open_policy( char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + /* we might actually want to decode the query, but it's not necessary */ + /* lsa_io_q_open_policy(...); */ + + /* return a 20 byte policy handle */ + reply_len = lsa_reply_open_policy(*rdata + 0x18, *rdata + 0x18); + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; +} + +static void api_lsa_query_info( char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + LSA_Q_QUERY_INFO q_i; + pstring dom_name; + pstring dom_sid; + + /* grab the info class and policy handle */ + lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4); + + pstrcpy(dom_name, lp_workgroup()); + pstrcpy(dom_sid , lp_domainsid()); + + /* construct reply. return status is always 0x0 */ + reply_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata + 0x18, + dom_name, dom_sid); + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; +} -- cgit From b2707324245d7143f4ac0056526044aed3881f3e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 8 Oct 1997 18:36:34 +0000 Subject: added api_lsa_lookup_sids() function (This used to be commit 35dd48740d8f733e7725813322b094b4679b31c5) --- source3/smbd/pipes.c | 1074 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1071 insertions(+), 3 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 06b785bd87..88cf0b2d71 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -370,6 +370,29 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, fragment length. I've decided to do it based on operation number :-) */ +/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ +char *dom_sid_to_string(DOM_SID *sid) +{ + static pstring sidstr; + char subauth[16]; + int i; + uint32 ia = (sid->id_auth[0]) + + (sid->id_auth[1] << 8 ) + + (sid->id_auth[2] << 16) + + (sid->id_auth[3] << 24); + + sprintf(sidstr, "S-%d-%d", sid->sid_no, ia); + + for (i = 0; i < sid->num_auths; i++) + { + sprintf(subauth, "-%d", sid->sub_auths[i]); + strcat(sidstr, subauth); + } + + DEBUG(5,("dom_sid_to_string returning %s\n", sidstr)); + return sidstr; +} + /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ /* identauth >= 2^32 can be detected because it will be specified in hex */ static void make_dom_sid(DOM_SID *sid, char *domsid) @@ -563,7 +586,7 @@ static void make_dom_ref(DOM_R_REF *ref, } static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, - int num_entries, char *dom_sids[MAX_LOOKUP_SIDS], + int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS], char *dom_name, char *dom_sid, char *other_sid1, char *other_sid2, char *other_sid3) { @@ -584,7 +607,8 @@ static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, r_l->num_entries3 = num_entries; } -static int lsa_reply_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, char *q, char *base, +static int lsa_reply_lookup_sids(char *q, char *base, + int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS], char *dom_name, char *dom_sid, char *other_sid1, char *other_sid2, char *other_sid3) { @@ -592,7 +616,7 @@ static int lsa_reply_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, char *q, char *base, LSA_R_LOOKUP_SIDS r_l; /* set up the LSA Lookup SIDs response */ - make_reply_lookup_sids(&r_l, 0, NULL, /* q_l->num_entries, q_l->dom_sids, */ + make_reply_lookup_sids(&r_l, num_entries, dom_sids, dom_name, dom_sid, other_sid1, other_sid2, other_sid3); r_l.status = 0x0; @@ -893,3 +917,1047 @@ static void api_lsa_query_info( char *param, char *data, make_rpc_reply(data, *rdata, reply_len); *rdata_len = reply_len + 0x18; } + +static void api_lsa_lookup_sids( char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + int i; + LSA_Q_LOOKUP_SIDS q_l; + pstring dom_name; + pstring dom_sid; + fstring dom_sids[MAX_LOOKUP_SIDS]; + + /* grab the info class and policy handle */ + lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4); + + pstrcpy(dom_name, lp_workgroup()); + pstrcpy(dom_sid , lp_domainsid()); + + /* convert received SIDs to strings, so we can do them. */ + for (i = 0; i < q_l.num_entries; i++) + { + fstrcpy(dom_sids[i], dom_sid_to_string(&(q_l.dom_sids[i]))); + } + + /* construct reply. return status is always 0x0 */ + reply_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata + 0x18, + q_l.num_entries, dom_sids, /* text-converted SIDs */ + dom_name, dom_sid, /* domain name, domain SID */ + "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; +} + + +#ifdef UNDEFINED_NTDOMAIN +/* + PAXX: Someone fix above. + The above API is indexing RPC calls based on RPC flags and + fragment length. I've decided to do it based on operation number :-) +*/ + +BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum; + char *q; + char *domainname; + int domlen; + pstring domsid; + char *p; + int numsubauths; + int subauths[MAXSUBAUTHS]; + struct smb_passwd *smb_pass; /* To check if machine account exists */ + pstring machacct; + pstring foo; + uint16 infoclass; + uint16 revision; /* Domain sid revision */ + int identauth; + int i; + char *logonsrv; + char *unicomp; + char *accountname; + uint16 secchanneltype; + uint32 negflags; + char netcred[8]; + uint32 rcvcred[8]; + char rtncred[8]; + uint32 clnttime; + uint32 rtntime; + char *newpass; + uint16 logonlevel; + uint16 switchval; + uint16 dommaxlen; + uint16 paramcontrol; + uint32 logonid[2]; + uint16 usernamelen; + uint16 usernamemaxlen; + uint16 wslen; + uint16 wsmaxlen; + uchar *rc4lmowfpass; + uchar *rc4ntowfpass; + char *domain; + char *username; + char *ws; + struct uinfo *userinfo; + int pkttype; + ArcfourContext c; + uchar rc4key[16]; + uchar ntowfpass[16]; + uint32 nentries; + char *policyhandle; + #define MAXSIDS 64 + uchar *sids[MAXSIDS]; /* for lookup SID */ + int nsids; + int nnames; + #define MAXNAMES 64 + uchar *names[MAXNAMES]; + + opnum = SVAL(data,22); + + pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ + { + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; + } + + DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum)); + initrpcreply(data, *rdata); + DEBUG(4,("netlogon LINE %d\n",__LINE__)); + switch (opnum) + { + case LSAOPENPOLICY: + DEBUG(1,("LSAOPENPOLICY\n")); + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + DEBUG(4,("netlogon data %lx\n", data)); + q = *rdata + 0x18; + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + /* return a 20 byte policy handle */ + /* here's a pretty handle:- */ + qSIVAL(time(NULL)); + qSIVAL(0x810a792f); + qSIVAL(0x11d107d5); + qSIVAL(time(NULL)); + qSIVAL(0x6cbcf800); + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); /* size of data plus return code */ + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + break; + + case LSAQUERYINFOPOLICY: + DEBUG(1,("LSAQUERYINFOPOLICY\n")); + dump_data(1,data,128); + infoclass = SVAL(data, 44); /* also a policy handle but who cares? */ + q = *rdata + 0x18; + qRSIVAL(0x00000022); /* undocumented. Usually a buffer pointer whose + value is ignored */ + qSSVAL(infoclass); + domainname = lp_workgroup(); + domlen = strlen(domainname); + strcpy(domsid,lp_domainsid()); + DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); + /* assume, but should check, that domsid starts "S-" */ + p = strtok(domsid+2,"-"); + revision = atoi(p); + DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); + identauth = atoi(strtok(0,"-")); + DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + + switch (infoclass) + { + case 5: + case 3: + default: + qSSVAL(0); /* 2 undocumented bytes */ + qSSVAL(domlen*2); + qSSVAL(domlen*2); /* unicode domain len and maxlen */ + qSIVAL(4); /* domain buffer pointer */ + qSIVAL(2); /* domain sid pointer */ + qunistr(domainname); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + } + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSAENUMTRUSTDOM: + DEBUG(1,("LSAENUMTRUSTDOM\n")); + q = *rdata + 0x18; + qSIVAL(0); /* enumeration context */ + qSIVAL(0); /* entries read */ + qSIVAL(0); /* trust information */ + endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len); + break; + + case LSACLOSE: + DEBUG(1,("LSACLOSE\n")); + q = *rdata + 0x18; + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSAOPENSECRET: + DEBUG(1,("LSAOPENSECRET\n")); + q = *rdata + 0x18; + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len); + break; + + case LSALOOKUPSIDS: + DEBUG(1,("LSAOPENSECRET\n")); + q = data + 0x18; + policyhandle = q; q += 20; + nentries = qIVAL; + DEBUG(4,("lookupsid entries %d\n",nentries)); + q += (2+nentries) * 4; /* skip bufptrs */ + /* now we have nentries sids of the form: + uint32 Subauthority count (SAC) + char Revision + char Subaurity count again + char[6] Identifier authority + [uint32 subauthority] * SAC + */ + for (nsids = 0; nsids < nentries; nsids++) + { + DEBUG(4,("lookupsid q in %lx\n",q)); + sids[nsids] = q; + DEBUG(4,("lookupsid numsubs %d\n",IVAL(q,0))); + q += 4+1+1+6+IVAL(q,0)*4; + DEBUG(4,("lookupsid q %lx\n",q)); + } + /* There's 16 bytes of something after all of that, don't know + what it is though - incorrectly documented */ + + DEBUG(4,("lookupsid line %d\n",__LINE__)); + /* formulate reply */ + q = *rdata + 0x18; + qSIVAL(2); /* bufptr */ + qSIVAL(4); /* number of referenced domains + - need one per each identifier authority in call */ + qSIVAL(2); /* dom bufptr */ + qSIVAL(32); /* max entries */ + qSIVAL(4); /* number of reference domains? */ + + qunihdr(lp_workgroup()); /* reference domain */ + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-1"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-5"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-3"); + qSIVAL(2); /* sid bufptr */ + + qunistr(lp_workgroup()); + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + strcpy(domsid,lp_domainsid()); + p = strtok(domsid+2,"-"); + revision = atoi(p); + identauth = atoi(strtok(0,"-")); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-1"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-5"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + + qunistr("S-1-3"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + + qSIVAL(nentries); + qSIVAL(2); /* bufptr */ + qSIVAL(nentries); + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qSSVAL(5); /* SID name use ?! */ + qSSVAL(0); /* undocumented */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + qunihdr(sidtostring(sids[i])); + DEBUG(4,("lookupsid sidname %s\n",sidtostring(sids[i]))); + qSIVAL(0); /* domain index out of above reference domains */ + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qunistr(sidtostring(sids[i])); + } + qSIVAL(nentries); /* mapped count */ + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSALOOKUPNAMES: + DEBUG(1,("LSALOOKUPNAMES\n")); + q = data + 0x18; + policyhandle = q; q += 20; + nentries = qIVAL; + DEBUG(4,("lookupnames entries %d\n",nentries)); + q += 4; /* skip second count */ + q += 8 * nentries; /* skip pointers */ + for (nnames = 0; nnames < nentries; nnames++) + { + names[nnames] = q; /* set name string to unicode header */ + q += IVAL(q,0)*2; /* guessing here */ + } + /* There's a translated sids structure next but it looks fals */ + + DEBUG(4,("lookupnames line %d\n",__LINE__)); + /* formulate reply */ + q = *rdata + 0x18; + qSIVAL(2); /* bufptr */ + qSIVAL(4); /* number of referenced domains + - need one per each identifier authority in call */ + qSIVAL(2); /* dom bufptr */ + qSIVAL(32); /* max entries */ + qSIVAL(4); /* number of reference domains? */ + + qunihdr(lp_workgroup()); /* reference domain */ + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-1"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-5"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-3"); + qSIVAL(2); /* sid bufptr */ + + qunistr(lp_workgroup()); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + + strcpy(domsid,lp_domainsid()); + p = strtok(domsid+2,"-"); + revision = atoi(p); + identauth = atoi(strtok(0,"-")); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-1"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-5"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + + qunistr("S-1-3"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + + qSIVAL(nentries); + qSIVAL(2); /* bufptr */ + qSIVAL(nentries); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ + qSSVAL(5); /* undocumented */ + DEBUG(4,("lookupnames line %d\n",__LINE__)); + qSIVAL(nametorid(names[i])); + DEBUG(4,("lookupnames nametorid %d\n",nametorid(names[i]))); + qSIVAL(0); /* domain index out of above reference domains */ + } + qSIVAL(nentries); /* mapped count */ + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + default: + DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum)); + } + return(True); +} + +BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum; + char *q; + char *domainname; + int domlen; + pstring domsid; + char *p; + int numsubauths; + int subauths[MAXSUBAUTHS]; + struct smb_passwd *smb_pass; /* To check if machine account exists */ + pstring machacct; + pstring foo; + uint16 infoclass; + uint16 revision; /* Domain sid revision */ + int identauth; + int i; + char *logonsrv; + char *unicomp; + char *accountname; + uint16 secchanneltype; + uint32 negflags; + char netcred[8]; + uint32 rcvcred[8]; + char rtncred[8]; + uint32 clnttime; + uint32 rtntime; + char *newpass; + uint16 logonlevel; + uint16 switchval; + uint16 dommaxlen; + uint16 paramcontrol; + uint32 logonid[2]; + uint16 usernamelen; + uint16 usernamemaxlen; + uint16 wslen; + uint16 wsmaxlen; + uchar *rc4lmowfpass; + uchar *rc4ntowfpass; + char *domain; + char *username; + char *ws; + struct uinfo *userinfo; + int pkttype; + ArcfourContext c; + uchar rc4key[16]; + uchar ntowfpass[16]; + + opnum = SVAL(data,22); + + pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ + { + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; + } + + DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); + initrpcreply(data, *rdata); + DEBUG(4,("netlogon LINE %d\n",__LINE__)); + switch (opnum) + { + case LSAREQCHAL: + DEBUG(1,("LSAREQCHAL\n")); + q = data + 0x18; + dump_data(1,q,128); + logonsrv = q + 16; /* first 16 bytes, buffer ptr, + unicode lenghts */ + q = skip_unicode_string(logonsrv,1) + 12; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1); + + + DEBUG(1,("logonsrv=%s unicomp=%s\n", + unistr(logonsrv), + unistr(unicomp))); + + dcauth[cnum].chal[0] = IVAL(q, 0); + dcauth[cnum].chal[1] = IVAL(q, 4); + dcauth[cnum].cred[0] = IVAL(q, 0); /* this looks weird (tridge) */ + dcauth[cnum].cred[1] = IVAL(q, 4); + +DEBUG(1,("NL: client challenge %08x %08x\n", dcauth[cnum].chal[0],dcauth[cnum].chal[1])); + + /* PAXX: set these to random values */ + dcauth[cnum].svrchal[0] = 0x11111111; + dcauth[cnum].svrchal[1] = 0x22222222; + dcauth[cnum].svrcred[0] = 0x11111111; + dcauth[cnum].svrcred[1] = 0x22222222; + strcpy(machacct,unistr(unicomp)); + strcat(machacct, "$"); + smb_pass = get_smbpwnam(machacct); + if(smb_pass) + memcpy(dcauth[cnum].md4pw, smb_pass->smb_nt_passwd, 16); + else + { + /* No such machine account. Should error out here, but we'll + print and carry on */ + DEBUG(1,("No account in domain at REQCHAL for %s\n", machacct)); + } + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",dcauth[cnum].md4pw[i]); + DEBUG(1,("pass %s %s\n", machacct, foo)); + setsesskey(cnum); + q = *rdata + 0x18; + qSIVAL(dcauth[cnum].svrchal[0]); + qSIVAL(dcauth[cnum].svrchal[1]); + +DEBUG(1,("NL: server challenge %08x %08x\n", + dcauth[cnum].svrchal[0],dcauth[cnum].svrchal[1])); + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSAAUTH2: + DEBUG(1,("LSAAUTH2\n")); + dump_data(1,q,128); + q = data + 0x18; + logonsrv = q + 16; + q = skip_unicode_string(logonsrv,1)+12; + q = align4(q, data); + accountname = q; + + q = skip_unicode_string(accountname,1); + secchanneltype = qSVAL; + q += 12; + q = align4(q, data); + unicomp = q; + dump_data(1,unicomp,32); + q = skip_unicode_string(unicomp,1); + rcvcred[0] = qIVAL; + rcvcred[1] = qIVAL; + q = align4(q, data); + negflags = qIVAL; + DEBUG(3,("AUTH2 logonsrv=%s accountname=%s unicomp=%s %lx %lx %lx\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp), + rcvcred[0], rcvcred[1], negflags)); + +DEBUG(1,("NL: recvcred %08x %08x negflags=%08x\n", + rcvcred[0], rcvcred[1], negflags)); + + checkcred(cnum, rcvcred[0], rcvcred[1], 0); + q = *rdata + 0x18; + makecred(cnum, 0, q); + q += 8; + + qSIVAL(negflags); + /* update stored client credentials */ + dcauth[cnum].cred[0] = dcauth[cnum].svrcred[0] = rcvcred[0]; + dcauth[cnum].cred[1] = dcauth[cnum].svrcred[1] = rcvcred[1]; + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSASVRPWSET: + DEBUG(1,("LSASVRPWSET\n")); + q = data + 0x18; + dump_data(1,q,128); + logonsrv = q + 16; + q = skip_unicode_string(logonsrv,1)+12; + q = align4(q, data); + accountname = q; + q = skip_unicode_string(accountname,1); + secchanneltype = qSVAL; + q += 12; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1); + rcvcred[0] = qIVAL; + rcvcred[1] = qIVAL; + clnttime = qIVAL; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp))); + + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); + newpass = q; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); + + /* PAXX: For the moment we'll reject these */ + /* TODO Need to set newpass in smbpasswd file for accountname */ + q = *rdata + 0x18; + makecred(cnum, clnttime+1, q); + q += 8; + qSIVAL(0); /* timestamp. Seems to be ignored */ + + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + + endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); + break; + + case LSASAMLOGON: + DEBUG(1,("LSASAMLOGON\n")); + dump_data(1,data,128); + q = data + 0x18; + logonsrv = q + 16; + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = skip_unicode_string(logonsrv,1)+16; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1)+4; + DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n", + __LINE__, unistr(logonsrv), unistr(unicomp))); + q = align4(q, data); + rcvcred[0] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[1] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + clnttime = qIVAL; + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + q += 2; + rtncred[0] = qIVAL; /* all these are ignored */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + rtncred[1] = qIVAL; + rtntime = qIVAL; + logonlevel = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + switchval = qSVAL; + switch (switchval) + { + case 1: + + q += 6; + domlen = qSVAL; + dommaxlen = qSVAL; q += 4; + paramcontrol = qIVAL; + logonid[0] = qIVAL; /* low part */ + logonid[1] = qIVAL; /* high part */ + + usernamelen = qSVAL; + + DEBUG(1,("SMLOG %d\n", __LINE__)); + usernamemaxlen = qSVAL; q += 4; + + DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n", + usernamelen, usernamemaxlen, dommaxlen)); + + dump_data(1,q,128); + + wslen = qSVAL; + wsmaxlen = qSVAL; q += 4; + rc4lmowfpass = q; q += 16; + rc4ntowfpass = q; q += 16; + + q += 12; domain = q; q += dommaxlen + 12; + q = align4(q, data); + username = q; q += usernamemaxlen + 12; + q = align4(q, data); + ws = q; + DEBUG(1,("domain=%s username=%s ws=%s\n", + unistr(domain), unistr(username), + unistr(ws))); + break; + default: + DEBUG(0,("unknown switch in SAMLOGON %d\n", + switchval)); + } + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]); + DEBUG(1,("userNAME %s [%s]\n", foo, username)); + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = *rdata + 0x18; + qSIVAL(0x16a4b4); /* magic buffer pointer ? */ + makecred(cnum, clnttime+1, q); + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + q += 8; + qSIVAL(0); /* timestamp. client doesn't care */ + qSSVAL(3); /* switch value 3. May be others? */ + qSSVAL(0); /* undocumented */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + + memset(rc4key, 0, sizeof rc4key); + SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]); + SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]); + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]); + DEBUG(1,("rc4ntowf %s\n", foo)); + arcfour_init(&c, rc4key, sizeof rc4key); + arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass); + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]); + DEBUG(1,("ntowf %s\n", foo)); + + if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) { + qSIVAL(0); /* no buffer */ + qSCVAL(1); /* Authoratitive. Change if passthrough? */ + qSCVAL(0); /* pad for above boolean */ + qSSVAL(0); /* pad for above boolean */ + + endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len); + break; + } + + qSIVAL(2); /* another magic bufptr? */ + DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo)); + qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]); + qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]); + DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1])); + qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]); + qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]); + qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]); + qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]); + DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename)); + qunihdr(userinfo->effectivename); + qunihdr(userinfo->fullname); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunihdr(userinfo->logonscript); + qunihdr(userinfo->profilepath); + qunihdr(userinfo->homedirectory); + qunihdr(userinfo->homedirectorydrive); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSSVAL(userinfo->logoncount); + qSSVAL(userinfo->badpwcount); + qSIVAL(userinfo->uid); + qSIVAL(userinfo->gid); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->ngroups); + qSIVAL(8); /* ptr to groups */ + qSIVAL(userinfo->userflags); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */ + qunihdr(userinfo->logonserver); + qunihdr(userinfo->logondomain); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(2); /* logon domain id ptr */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + memset(q,0,40); q += 40; /* expansion room */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->nsids); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(0); /* ptr to sids and values */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->effectivename); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->fullname); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->logonscript); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->profilepath); + qunistr(userinfo->homedirectory); + qunistr(userinfo->homedirectorydrive); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->ngroups); + for (i = 0; i < userinfo->ngroups; i++) + { + qSIVAL(userinfo->groups[i].gid); + qSIVAL(userinfo->groups[i].attr); + } + qunistr(userinfo->logonserver); + qunistr(userinfo->logondomain); + for (i = 0; i < userinfo->nsids; i++) + { + /* put the extra sids: PAXX: TODO */ + } + /* Assumption. This is the only domain, sending our SID */ + /* PAXX: may want to do passthrough later */ + strcpy(domsid,lp_domainsid()); + DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); + /* assume, but should check, that domsid starts "S-" */ + p = strtok(domsid+2,"-"); + revision = atoi(p); + DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); + identauth = atoi(strtok(0,"-")); + DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + qSCVAL(1); /* Authoratitive. Change if passthrough? */ + qSCVAL(0); /* pad for above boolean */ + qSSVAL(0); /* pad for above boolean */ + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSASAMLOGOFF: + DEBUG(1,("LSASAMLOGOFF\n")); + q = data + 0x18; + logonsrv = q + 16; + DEBUG(1,("SAMLOGOFF %d\n", __LINE__)); + unicomp = skip_unicode_string(logonsrv,1)+16; + if (strlen(unistr(logonsrv)) % 2 == 0) + q += 2; + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = skip_unicode_string(unicomp,1)+4; + if (strlen(unistr(unicomp)) % 2 == 0) + q += 2; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[0] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[1] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + clnttime = qIVAL; + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + q += 4; + rtncred[0] = qIVAL; /* all these are ignored */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + rtncred[1] = qIVAL; + rtntime = qIVAL; + logonlevel = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + switchval = qSVAL; + switch (switchval) + { + case 1: + q += 4; + domlen = qSVAL; + dommaxlen = qSVAL; q += 4; + paramcontrol = qIVAL; + logonid[0] = qIVAL; /* low part */ + logonid[1] = qIVAL; /* high part */ + usernamelen = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + usernamemaxlen = qSVAL; q += 4; + wslen = qSVAL; + wsmaxlen = qSVAL; q += 4; + rc4lmowfpass = q; q += 16; + rc4ntowfpass = q; q += 16; + q += 12; domain = q; q += dommaxlen + 12; + if ((domlen/2) % 2 != 0) q += 2; + username = q; q += usernamemaxlen + 12; /* PAXX: HACK */ + if ((usernamelen/2) % 2 != 0) q += 2; + ws = q; + break; + default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval)); + } + DEBUG(1,("SAMLOGOFF %s\n", unistr(username))); + default: + DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); + } + return(True); +} + +void initrpcreply(char *inbuf, char *q) +{ + uint32 callid; + + qSCVAL(5); /* RPC version 5 */ + qSCVAL(0); /* minor version 0 */ + qSCVAL(2); /* RPC response packet */ + qSCVAL(3); /* first frag + last frag */ + qRSIVAL(0x10000000); /* packed data representation */ + qRSSVAL(0); /* fragment length, fill in later */ + qSSVAL(0); /* authentication length */ + callid = RIVAL(inbuf,12); + qRSIVAL(callid); /* call identifier - match incoming RPC */ + qSIVAL(0x18); /* allocation hint (no idea) */ + qSSVAL(0); /* presentation context identifier */ + qSCVAL(0); /* cancel count */ + qSCVAL(0); /* reserved */ +} + +endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen) +{ + SSVAL(q, 8, datalen + 4); + SIVAL(q,0x10,datalen+4-0x18); /* allocation hint */ + SIVAL(q, datalen, rtnval); + *rlen = datalen + 4; + {int fd; fd = open("/tmp/rpc", O_RDWR);write(fd,q,datalen+4);} +} + +void setsesskey(int cnum) +{ + uint32 sum[2]; + char netsum[8]; + char netsesskey[8]; + char icv[8]; + + sum[0] = dcauth[cnum].chal[0] + dcauth[cnum].svrchal[0]; + sum[1] = dcauth[cnum].chal[1] + dcauth[cnum].svrchal[1]; + SIVAL(netsum,0,sum[0]); + SIVAL(netsum,4,sum[1]); + E1(dcauth[cnum].md4pw,netsum,icv); + E1(dcauth[cnum].md4pw+9,icv,netsesskey); + dcauth[cnum].sesskey[0] = IVAL(netsesskey,0); + dcauth[cnum].sesskey[1] = IVAL(netsesskey,4); + +DEBUG(1,("NL: session key %08x %08x\n", + dcauth[cnum].sesskey[0], + dcauth[cnum].sesskey[1])); +} + +void checkcred(int cnum, uint32 cred0, uint32 cred1, uint32 time) +{ + uint32 sum[2]; + char netdata[8]; + char netsesskey[8]; + char calccred[8]; + char icv[8]; + char key2[7]; + + SIVAL(netdata, 0, dcauth[cnum].cred[0]+time); + SIVAL(netdata, 4, dcauth[cnum].cred[1]); + SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); + SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); + E1(netsesskey,netdata,icv); + memset(key2, 0, sizeof key2); + key2[0] = netsesskey[7]; + E1(key2, icv, calccred); + if (IVAL(calccred,0) != cred0 || + IVAL(calccred,4) != cred1) + { + DEBUG(1,("Incorrect client credential received cred %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", + cred0, cred1, time, + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].cred[0], dcauth[cnum].cred[1], + IVAL(calccred,0), IVAL(calccred,4))); + /* PAXX: do something about it! */ + } else + DEBUG(4,("Correct client credential received chal %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", + cred0, cred1, time, + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].cred[0], dcauth[cnum].cred[1], + IVAL(calccred,0), IVAL(calccred,4))); +} + +void makecred(int cnum, uint32 time, char *calccred) +{ + uint32 sum[2]; + char netdata[8]; + char netsesskey[8]; + char icv[8]; + char key2[7]; + + SIVAL(netdata, 0, dcauth[cnum].svrcred[0]+time); + SIVAL(netdata, 4, dcauth[cnum].svrcred[1]); + SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); + SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); + E1(netsesskey,netdata,icv); + memset(key2, 0, sizeof key2); + key2[0] = netsesskey[7]; + E1(key2, icv, calccred); + DEBUG(4,("Server credential: chal %lx %lx sk %lx %lx cred %lx %lx calc %lx %lx\n", + dcauth[cnum].svrchal[0], dcauth[cnum].svrchal[1], + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].svrcred[0], dcauth[cnum].svrcred[1], + IVAL(calccred, 0), IVAL(calccred, 4))); +} + + +struct uinfo *getuserinfo(char *user, int len, char *ntowfpass) +{ + static struct uinfo u; + static pstring fullnm; + static pstring ascuser; + extern pstring myname; + static pstring stme; + static pstring stdom; + struct smb_passwd *smb_pass; + + strcpy(ascuser,unistr(user)); + ascuser[len/2] = 0; /* PAXX: FIXMEFIXMEFIXME */ + DEBUG(1,("GETUSER username :%s: len=%d\n",ascuser, len)); + + smb_pass = get_smbpwnam(ascuser); + if(!smb_pass) + return 0; + DEBUG(1,("GETU %d\n", __LINE__)); + if (memcmp(ntowfpass, smb_pass->smb_nt_passwd, 16)) { + DEBUG(1,("pass mismatch:\n")); + dump_data(1,ntowfpass,16); + dump_data(1,smb_pass->smb_nt_passwd,16); + return 0; + } + + DEBUG(1,("GETU %d\n", __LINE__)); + u.logontime[0] = 0xffffffff; u.logontime[1] = 0x7fffffff; + u.logofftime[0] = 0xffffffff; u.logofftime[1] = 0x7fffffff; + u.kickofftime[0] = 0xffffffff; u.kickofftime[1] = 0x7fffffff; + DEBUG(1,("GETU %d\n", __LINE__)); + u.passlastsettime[0] = 0xffffffff; u.passlastsettime[1] = 0x7fffffff; + u.passcanchgtime[0] = 0xffffffff; u.passcanchgtime[1] = 0x7fffffff; + u.passmustchgtime[0] = 0xffffffff; u.passmustchgtime[1] = 0x7fffffff; + DEBUG(1,("GETU %d\n", __LINE__)); + u.effectivename = ascuser; + strcpy(fullnm, "Full name of "); + strcat(fullnm, ascuser); + DEBUG(1,("GETU %d\n", __LINE__)); + u.fullname = fullnm; + u.logonscript = "foologin.cmd"; + u.profilepath = "prof"; + u.homedirectory = "foohomes"; + DEBUG(1,("GETU %d\n", __LINE__)); + u.homedirectorydrive = "a:"; + u.logoncount = 7; + u.badpwcount = 8; + u.uid = 778; + DEBUG(1,("GETU %d\n", __LINE__)); + u.gid = 998; + u.ngroups = 2; + u.groups = (struct groupinfo *)(malloc(sizeof (struct groupinfo) * 2)); + u.groups[0].gid = 776; + DEBUG(1,("GETU %d\n", __LINE__)); + u.groups[0].attr = 0x7; + u.groups[1].gid = 776; + u.groups[1].attr = 0x7; + u.userflags = 0x20; + u.logonserver = stme; + get_myname(myname,NULL); + strcpy(stme, myname); + strupper(stme); + DEBUG(1,("LS %s\n", u.logonserver)); + u.logondomain = stdom; + strcpy(stdom, lp_workgroup()); + strupper(stdom); + DEBUG(1,("DOM %s\n", u.logondomain)); + u.nsids = 0; + u.sids = 0; + DEBUG(1,("GETU %d\n", __LINE__)); + return &u; +}; + +int +nametorid(char *uniuser) +{ + if (!strncmp(unistr(uniuser+12),"ashtonp",7)) + return 2000; + if (!strncmp(unistr(uniuser+12),"user1",5)) + return 1; + if (!strncmp(unistr(uniuser+12),"user2",5)) + return 10; + if (!strncmp(unistr(uniuser+12),"user3",5)) + return 100; + return 3000; +} + +#endif /* NTDOMAIN */ -- cgit From 74113cd60ecceaf73fce83e84dbcd58b498f2cb1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 8 Oct 1997 20:34:13 +0000 Subject: Makefile: Split definitions for SGI4,5,6. includes.h: Split definitions for SGI4,5,6. pipes.c: Moved Luke's #ifdef to remove warnings. quotas.c: Two changes for FreeBSD and SGI. server.c: Quota changes for large filesystems. Jeremy (jallison@whistle.com) (This used to be commit b8ff5543b9fa45095caa9f24aeb22a1dcc1cd308) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 88cf0b2d71..870dc16fdd 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -364,6 +364,7 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, return(True); } +#ifdef UNDEFINED_NTDOMAIN /* PAXX: Someone fix above. The above API is indexing RPC calls based on RPC flags and @@ -953,7 +954,6 @@ static void api_lsa_lookup_sids( char *param, char *data, } -#ifdef UNDEFINED_NTDOMAIN /* PAXX: Someone fix above. The above API is indexing RPC calls based on RPC flags and -- cgit From f40427291e176028f45482209d863019428abc8b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 8 Oct 1997 21:36:42 +0000 Subject: added a dummy function (space in front so make proto doesn't pick it up) to call the unused static functions in pipes.c. avoids need to move #if UNDEFINED_NTDOMAIN about, to stop compiler warnings while code is being developed, but might be released as-is. (This used to be commit d7f41e3815babce58fa9901f076c2918666abaf9) --- source3/smbd/pipes.c | 1028 +------------------------------------------------- 1 file changed, 20 insertions(+), 1008 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 870dc16fdd..bedf847cc4 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -364,7 +364,6 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, return(True); } -#ifdef UNDEFINED_NTDOMAIN /* PAXX: Someone fix above. The above API is indexing RPC calls based on RPC flags and @@ -953,1011 +952,24 @@ static void api_lsa_lookup_sids( char *param, char *data, *rdata_len = reply_len + 0x18; } - -/* - PAXX: Someone fix above. - The above API is indexing RPC calls based on RPC flags and - fragment length. I've decided to do it based on operation number :-) -*/ - -BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - uint16 opnum; - char *q; - char *domainname; - int domlen; - pstring domsid; - char *p; - int numsubauths; - int subauths[MAXSUBAUTHS]; - struct smb_passwd *smb_pass; /* To check if machine account exists */ - pstring machacct; - pstring foo; - uint16 infoclass; - uint16 revision; /* Domain sid revision */ - int identauth; - int i; - char *logonsrv; - char *unicomp; - char *accountname; - uint16 secchanneltype; - uint32 negflags; - char netcred[8]; - uint32 rcvcred[8]; - char rtncred[8]; - uint32 clnttime; - uint32 rtntime; - char *newpass; - uint16 logonlevel; - uint16 switchval; - uint16 dommaxlen; - uint16 paramcontrol; - uint32 logonid[2]; - uint16 usernamelen; - uint16 usernamemaxlen; - uint16 wslen; - uint16 wsmaxlen; - uchar *rc4lmowfpass; - uchar *rc4ntowfpass; - char *domain; - char *username; - char *ws; - struct uinfo *userinfo; - int pkttype; - ArcfourContext c; - uchar rc4key[16]; - uchar ntowfpass[16]; - uint32 nentries; - char *policyhandle; - #define MAXSIDS 64 - uchar *sids[MAXSIDS]; /* for lookup SID */ - int nsids; - int nnames; - #define MAXNAMES 64 - uchar *names[MAXNAMES]; - - opnum = SVAL(data,22); - - pkttype = CVAL(data, 2); - if (pkttype == 0x0b) /* RPC BIND */ - { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } - - DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum)); - initrpcreply(data, *rdata); - DEBUG(4,("netlogon LINE %d\n",__LINE__)); - switch (opnum) - { - case LSAOPENPOLICY: - DEBUG(1,("LSAOPENPOLICY\n")); - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - DEBUG(4,("netlogon data %lx\n", data)); - q = *rdata + 0x18; - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - /* return a 20 byte policy handle */ - /* here's a pretty handle:- */ - qSIVAL(time(NULL)); - qSIVAL(0x810a792f); - qSIVAL(0x11d107d5); - qSIVAL(time(NULL)); - qSIVAL(0x6cbcf800); - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); /* size of data plus return code */ - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - break; - - case LSAQUERYINFOPOLICY: - DEBUG(1,("LSAQUERYINFOPOLICY\n")); - dump_data(1,data,128); - infoclass = SVAL(data, 44); /* also a policy handle but who cares? */ - q = *rdata + 0x18; - qRSIVAL(0x00000022); /* undocumented. Usually a buffer pointer whose - value is ignored */ - qSSVAL(infoclass); - domainname = lp_workgroup(); - domlen = strlen(domainname); - strcpy(domsid,lp_domainsid()); - DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); - /* assume, but should check, that domsid starts "S-" */ - p = strtok(domsid+2,"-"); - revision = atoi(p); - DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); - identauth = atoi(strtok(0,"-")); - DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - - switch (infoclass) - { - case 5: - case 3: - default: - qSSVAL(0); /* 2 undocumented bytes */ - qSSVAL(domlen*2); - qSSVAL(domlen*2); /* unicode domain len and maxlen */ - qSIVAL(4); /* domain buffer pointer */ - qSIVAL(2); /* domain sid pointer */ - qunistr(domainname); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - } - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSAENUMTRUSTDOM: - DEBUG(1,("LSAENUMTRUSTDOM\n")); - q = *rdata + 0x18; - qSIVAL(0); /* enumeration context */ - qSIVAL(0); /* entries read */ - qSIVAL(0); /* trust information */ - endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len); - break; - - case LSACLOSE: - DEBUG(1,("LSACLOSE\n")); - q = *rdata + 0x18; - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSAOPENSECRET: - DEBUG(1,("LSAOPENSECRET\n")); - q = *rdata + 0x18; - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len); - break; - - case LSALOOKUPSIDS: - DEBUG(1,("LSAOPENSECRET\n")); - q = data + 0x18; - policyhandle = q; q += 20; - nentries = qIVAL; - DEBUG(4,("lookupsid entries %d\n",nentries)); - q += (2+nentries) * 4; /* skip bufptrs */ - /* now we have nentries sids of the form: - uint32 Subauthority count (SAC) - char Revision - char Subaurity count again - char[6] Identifier authority - [uint32 subauthority] * SAC - */ - for (nsids = 0; nsids < nentries; nsids++) - { - DEBUG(4,("lookupsid q in %lx\n",q)); - sids[nsids] = q; - DEBUG(4,("lookupsid numsubs %d\n",IVAL(q,0))); - q += 4+1+1+6+IVAL(q,0)*4; - DEBUG(4,("lookupsid q %lx\n",q)); - } - /* There's 16 bytes of something after all of that, don't know - what it is though - incorrectly documented */ - - DEBUG(4,("lookupsid line %d\n",__LINE__)); - /* formulate reply */ - q = *rdata + 0x18; - qSIVAL(2); /* bufptr */ - qSIVAL(4); /* number of referenced domains - - need one per each identifier authority in call */ - qSIVAL(2); /* dom bufptr */ - qSIVAL(32); /* max entries */ - qSIVAL(4); /* number of reference domains? */ - - qunihdr(lp_workgroup()); /* reference domain */ - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-1"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-5"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-3"); - qSIVAL(2); /* sid bufptr */ - - qunistr(lp_workgroup()); - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - strcpy(domsid,lp_domainsid()); - p = strtok(domsid+2,"-"); - revision = atoi(p); - identauth = atoi(strtok(0,"-")); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - qunistr("S-1-1"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - qunistr("S-1-5"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ - - qunistr("S-1-3"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ - - qSIVAL(nentries); - qSIVAL(2); /* bufptr */ - qSIVAL(nentries); - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qSSVAL(5); /* SID name use ?! */ - qSSVAL(0); /* undocumented */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - qunihdr(sidtostring(sids[i])); - DEBUG(4,("lookupsid sidname %s\n",sidtostring(sids[i]))); - qSIVAL(0); /* domain index out of above reference domains */ - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qunistr(sidtostring(sids[i])); - } - qSIVAL(nentries); /* mapped count */ - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSALOOKUPNAMES: - DEBUG(1,("LSALOOKUPNAMES\n")); - q = data + 0x18; - policyhandle = q; q += 20; - nentries = qIVAL; - DEBUG(4,("lookupnames entries %d\n",nentries)); - q += 4; /* skip second count */ - q += 8 * nentries; /* skip pointers */ - for (nnames = 0; nnames < nentries; nnames++) - { - names[nnames] = q; /* set name string to unicode header */ - q += IVAL(q,0)*2; /* guessing here */ - } - /* There's a translated sids structure next but it looks fals */ - - DEBUG(4,("lookupnames line %d\n",__LINE__)); - /* formulate reply */ - q = *rdata + 0x18; - qSIVAL(2); /* bufptr */ - qSIVAL(4); /* number of referenced domains - - need one per each identifier authority in call */ - qSIVAL(2); /* dom bufptr */ - qSIVAL(32); /* max entries */ - qSIVAL(4); /* number of reference domains? */ - - qunihdr(lp_workgroup()); /* reference domain */ - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-1"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-5"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-3"); - qSIVAL(2); /* sid bufptr */ - - qunistr(lp_workgroup()); - DEBUG(4,("lookupnames line %d\n",__LINE__)); - - strcpy(domsid,lp_domainsid()); - p = strtok(domsid+2,"-"); - revision = atoi(p); - identauth = atoi(strtok(0,"-")); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - qunistr("S-1-1"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - qunistr("S-1-5"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ - - qunistr("S-1-3"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ - - qSIVAL(nentries); - qSIVAL(2); /* bufptr */ - qSIVAL(nentries); - DEBUG(4,("lookupnames line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ - qSSVAL(5); /* undocumented */ - DEBUG(4,("lookupnames line %d\n",__LINE__)); - qSIVAL(nametorid(names[i])); - DEBUG(4,("lookupnames nametorid %d\n",nametorid(names[i]))); - qSIVAL(0); /* domain index out of above reference domains */ - } - qSIVAL(nentries); /* mapped count */ - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - default: - DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum)); - } - return(True); -} - -BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - uint16 opnum; - char *q; - char *domainname; - int domlen; - pstring domsid; - char *p; - int numsubauths; - int subauths[MAXSUBAUTHS]; - struct smb_passwd *smb_pass; /* To check if machine account exists */ - pstring machacct; - pstring foo; - uint16 infoclass; - uint16 revision; /* Domain sid revision */ - int identauth; - int i; - char *logonsrv; - char *unicomp; - char *accountname; - uint16 secchanneltype; - uint32 negflags; - char netcred[8]; - uint32 rcvcred[8]; - char rtncred[8]; - uint32 clnttime; - uint32 rtntime; - char *newpass; - uint16 logonlevel; - uint16 switchval; - uint16 dommaxlen; - uint16 paramcontrol; - uint32 logonid[2]; - uint16 usernamelen; - uint16 usernamemaxlen; - uint16 wslen; - uint16 wsmaxlen; - uchar *rc4lmowfpass; - uchar *rc4ntowfpass; - char *domain; - char *username; - char *ws; - struct uinfo *userinfo; - int pkttype; - ArcfourContext c; - uchar rc4key[16]; - uchar ntowfpass[16]; - - opnum = SVAL(data,22); - - pkttype = CVAL(data, 2); - if (pkttype == 0x0b) /* RPC BIND */ - { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } - - DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); - initrpcreply(data, *rdata); - DEBUG(4,("netlogon LINE %d\n",__LINE__)); - switch (opnum) - { - case LSAREQCHAL: - DEBUG(1,("LSAREQCHAL\n")); - q = data + 0x18; - dump_data(1,q,128); - logonsrv = q + 16; /* first 16 bytes, buffer ptr, + unicode lenghts */ - q = skip_unicode_string(logonsrv,1) + 12; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1); - - - DEBUG(1,("logonsrv=%s unicomp=%s\n", - unistr(logonsrv), - unistr(unicomp))); - - dcauth[cnum].chal[0] = IVAL(q, 0); - dcauth[cnum].chal[1] = IVAL(q, 4); - dcauth[cnum].cred[0] = IVAL(q, 0); /* this looks weird (tridge) */ - dcauth[cnum].cred[1] = IVAL(q, 4); - -DEBUG(1,("NL: client challenge %08x %08x\n", dcauth[cnum].chal[0],dcauth[cnum].chal[1])); - - /* PAXX: set these to random values */ - dcauth[cnum].svrchal[0] = 0x11111111; - dcauth[cnum].svrchal[1] = 0x22222222; - dcauth[cnum].svrcred[0] = 0x11111111; - dcauth[cnum].svrcred[1] = 0x22222222; - strcpy(machacct,unistr(unicomp)); - strcat(machacct, "$"); - smb_pass = get_smbpwnam(machacct); - if(smb_pass) - memcpy(dcauth[cnum].md4pw, smb_pass->smb_nt_passwd, 16); - else - { - /* No such machine account. Should error out here, but we'll - print and carry on */ - DEBUG(1,("No account in domain at REQCHAL for %s\n", machacct)); - } - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",dcauth[cnum].md4pw[i]); - DEBUG(1,("pass %s %s\n", machacct, foo)); - setsesskey(cnum); - q = *rdata + 0x18; - qSIVAL(dcauth[cnum].svrchal[0]); - qSIVAL(dcauth[cnum].svrchal[1]); - -DEBUG(1,("NL: server challenge %08x %08x\n", - dcauth[cnum].svrchal[0],dcauth[cnum].svrchal[1])); - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSAAUTH2: - DEBUG(1,("LSAAUTH2\n")); - dump_data(1,q,128); - q = data + 0x18; - logonsrv = q + 16; - q = skip_unicode_string(logonsrv,1)+12; - q = align4(q, data); - accountname = q; - - q = skip_unicode_string(accountname,1); - secchanneltype = qSVAL; - q += 12; - q = align4(q, data); - unicomp = q; - dump_data(1,unicomp,32); - q = skip_unicode_string(unicomp,1); - rcvcred[0] = qIVAL; - rcvcred[1] = qIVAL; - q = align4(q, data); - negflags = qIVAL; - DEBUG(3,("AUTH2 logonsrv=%s accountname=%s unicomp=%s %lx %lx %lx\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp), - rcvcred[0], rcvcred[1], negflags)); - -DEBUG(1,("NL: recvcred %08x %08x negflags=%08x\n", - rcvcred[0], rcvcred[1], negflags)); - - checkcred(cnum, rcvcred[0], rcvcred[1], 0); - q = *rdata + 0x18; - makecred(cnum, 0, q); - q += 8; - - qSIVAL(negflags); - /* update stored client credentials */ - dcauth[cnum].cred[0] = dcauth[cnum].svrcred[0] = rcvcred[0]; - dcauth[cnum].cred[1] = dcauth[cnum].svrcred[1] = rcvcred[1]; - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSASVRPWSET: - DEBUG(1,("LSASVRPWSET\n")); - q = data + 0x18; - dump_data(1,q,128); - logonsrv = q + 16; - q = skip_unicode_string(logonsrv,1)+12; - q = align4(q, data); - accountname = q; - q = skip_unicode_string(accountname,1); - secchanneltype = qSVAL; - q += 12; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1); - rcvcred[0] = qIVAL; - rcvcred[1] = qIVAL; - clnttime = qIVAL; - - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp))); - - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); - newpass = q; - - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); - - /* PAXX: For the moment we'll reject these */ - /* TODO Need to set newpass in smbpasswd file for accountname */ - q = *rdata + 0x18; - makecred(cnum, clnttime+1, q); - q += 8; - qSIVAL(0); /* timestamp. Seems to be ignored */ - - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; - - endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); - break; - - case LSASAMLOGON: - DEBUG(1,("LSASAMLOGON\n")); - dump_data(1,data,128); - q = data + 0x18; - logonsrv = q + 16; - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = skip_unicode_string(logonsrv,1)+16; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1)+4; - DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n", - __LINE__, unistr(logonsrv), unistr(unicomp))); - q = align4(q, data); - rcvcred[0] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[1] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - clnttime = qIVAL; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - q += 2; - rtncred[0] = qIVAL; /* all these are ignored */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - rtncred[1] = qIVAL; - rtntime = qIVAL; - logonlevel = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - switchval = qSVAL; - switch (switchval) - { - case 1: - - q += 6; - domlen = qSVAL; - dommaxlen = qSVAL; q += 4; - paramcontrol = qIVAL; - logonid[0] = qIVAL; /* low part */ - logonid[1] = qIVAL; /* high part */ - - usernamelen = qSVAL; - - DEBUG(1,("SMLOG %d\n", __LINE__)); - usernamemaxlen = qSVAL; q += 4; - - DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n", - usernamelen, usernamemaxlen, dommaxlen)); - - dump_data(1,q,128); - - wslen = qSVAL; - wsmaxlen = qSVAL; q += 4; - rc4lmowfpass = q; q += 16; - rc4ntowfpass = q; q += 16; - - q += 12; domain = q; q += dommaxlen + 12; - q = align4(q, data); - username = q; q += usernamemaxlen + 12; - q = align4(q, data); - ws = q; - DEBUG(1,("domain=%s username=%s ws=%s\n", - unistr(domain), unistr(username), - unistr(ws))); - break; - default: - DEBUG(0,("unknown switch in SAMLOGON %d\n", - switchval)); - } - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]); - DEBUG(1,("userNAME %s [%s]\n", foo, username)); - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = *rdata + 0x18; - qSIVAL(0x16a4b4); /* magic buffer pointer ? */ - makecred(cnum, clnttime+1, q); - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; - q += 8; - qSIVAL(0); /* timestamp. client doesn't care */ - qSSVAL(3); /* switch value 3. May be others? */ - qSSVAL(0); /* undocumented */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - - memset(rc4key, 0, sizeof rc4key); - SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]); - SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]); - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]); - DEBUG(1,("rc4ntowf %s\n", foo)); - arcfour_init(&c, rc4key, sizeof rc4key); - arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass); - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]); - DEBUG(1,("ntowf %s\n", foo)); - - if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) { - qSIVAL(0); /* no buffer */ - qSCVAL(1); /* Authoratitive. Change if passthrough? */ - qSCVAL(0); /* pad for above boolean */ - qSSVAL(0); /* pad for above boolean */ - - endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len); - break; - } - - qSIVAL(2); /* another magic bufptr? */ - DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo)); - qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]); - qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]); - DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1])); - qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]); - qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]); - qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]); - qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]); - DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename)); - qunihdr(userinfo->effectivename); - qunihdr(userinfo->fullname); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunihdr(userinfo->logonscript); - qunihdr(userinfo->profilepath); - qunihdr(userinfo->homedirectory); - qunihdr(userinfo->homedirectorydrive); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSSVAL(userinfo->logoncount); - qSSVAL(userinfo->badpwcount); - qSIVAL(userinfo->uid); - qSIVAL(userinfo->gid); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->ngroups); - qSIVAL(8); /* ptr to groups */ - qSIVAL(userinfo->userflags); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */ - qunihdr(userinfo->logonserver); - qunihdr(userinfo->logondomain); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(2); /* logon domain id ptr */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - memset(q,0,40); q += 40; /* expansion room */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->nsids); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(0); /* ptr to sids and values */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->effectivename); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->fullname); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->logonscript); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->profilepath); - qunistr(userinfo->homedirectory); - qunistr(userinfo->homedirectorydrive); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->ngroups); - for (i = 0; i < userinfo->ngroups; i++) - { - qSIVAL(userinfo->groups[i].gid); - qSIVAL(userinfo->groups[i].attr); - } - qunistr(userinfo->logonserver); - qunistr(userinfo->logondomain); - for (i = 0; i < userinfo->nsids; i++) - { - /* put the extra sids: PAXX: TODO */ - } - /* Assumption. This is the only domain, sending our SID */ - /* PAXX: may want to do passthrough later */ - strcpy(domsid,lp_domainsid()); - DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); - /* assume, but should check, that domsid starts "S-" */ - p = strtok(domsid+2,"-"); - revision = atoi(p); - DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); - identauth = atoi(strtok(0,"-")); - DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - qSCVAL(1); /* Authoratitive. Change if passthrough? */ - qSCVAL(0); /* pad for above boolean */ - qSSVAL(0); /* pad for above boolean */ - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSASAMLOGOFF: - DEBUG(1,("LSASAMLOGOFF\n")); - q = data + 0x18; - logonsrv = q + 16; - DEBUG(1,("SAMLOGOFF %d\n", __LINE__)); - unicomp = skip_unicode_string(logonsrv,1)+16; - if (strlen(unistr(logonsrv)) % 2 == 0) - q += 2; - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = skip_unicode_string(unicomp,1)+4; - if (strlen(unistr(unicomp)) % 2 == 0) - q += 2; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[0] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[1] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - clnttime = qIVAL; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - q += 4; - rtncred[0] = qIVAL; /* all these are ignored */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - rtncred[1] = qIVAL; - rtntime = qIVAL; - logonlevel = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - switchval = qSVAL; - switch (switchval) - { - case 1: - q += 4; - domlen = qSVAL; - dommaxlen = qSVAL; q += 4; - paramcontrol = qIVAL; - logonid[0] = qIVAL; /* low part */ - logonid[1] = qIVAL; /* high part */ - usernamelen = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - usernamemaxlen = qSVAL; q += 4; - wslen = qSVAL; - wsmaxlen = qSVAL; q += 4; - rc4lmowfpass = q; q += 16; - rc4ntowfpass = q; q += 16; - q += 12; domain = q; q += dommaxlen + 12; - if ((domlen/2) % 2 != 0) q += 2; - username = q; q += usernamemaxlen + 12; /* PAXX: HACK */ - if ((usernamelen/2) % 2 != 0) q += 2; - ws = q; - break; - default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval)); - } - DEBUG(1,("SAMLOGOFF %s\n", unistr(username))); - default: - DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); - } - return(True); +/* space in front of this function so that make proto doesn't pick it up */ + void _dummy_function(void) +{ + UTIME t; + lsa_reply_req_chal(NULL, NULL, NULL, NULL); + lsa_reply_auth_2(NULL, NULL, NULL, NULL, 0); + lsa_reply_srv_pwset(NULL, NULL, NULL, NULL, t, 0); + make_lsa_user_info(NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + 0, 0, + 0, 0, 0, NULL, 0, + NULL, + NULL, NULL, + NULL, NULL); + lsa_reply_sam_logon(NULL,NULL,NULL,NULL,t, NULL); + lsa_reply_sam_logoff(NULL,NULL,NULL,NULL,t,0); + api_lsa_open_policy(NULL,NULL,NULL,NULL); + api_lsa_query_info(NULL,NULL,NULL,NULL); + api_lsa_lookup_sids(NULL,NULL,NULL,NULL); } - -void initrpcreply(char *inbuf, char *q) -{ - uint32 callid; - - qSCVAL(5); /* RPC version 5 */ - qSCVAL(0); /* minor version 0 */ - qSCVAL(2); /* RPC response packet */ - qSCVAL(3); /* first frag + last frag */ - qRSIVAL(0x10000000); /* packed data representation */ - qRSSVAL(0); /* fragment length, fill in later */ - qSSVAL(0); /* authentication length */ - callid = RIVAL(inbuf,12); - qRSIVAL(callid); /* call identifier - match incoming RPC */ - qSIVAL(0x18); /* allocation hint (no idea) */ - qSSVAL(0); /* presentation context identifier */ - qSCVAL(0); /* cancel count */ - qSCVAL(0); /* reserved */ -} - -endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen) -{ - SSVAL(q, 8, datalen + 4); - SIVAL(q,0x10,datalen+4-0x18); /* allocation hint */ - SIVAL(q, datalen, rtnval); - *rlen = datalen + 4; - {int fd; fd = open("/tmp/rpc", O_RDWR);write(fd,q,datalen+4);} -} - -void setsesskey(int cnum) -{ - uint32 sum[2]; - char netsum[8]; - char netsesskey[8]; - char icv[8]; - - sum[0] = dcauth[cnum].chal[0] + dcauth[cnum].svrchal[0]; - sum[1] = dcauth[cnum].chal[1] + dcauth[cnum].svrchal[1]; - SIVAL(netsum,0,sum[0]); - SIVAL(netsum,4,sum[1]); - E1(dcauth[cnum].md4pw,netsum,icv); - E1(dcauth[cnum].md4pw+9,icv,netsesskey); - dcauth[cnum].sesskey[0] = IVAL(netsesskey,0); - dcauth[cnum].sesskey[1] = IVAL(netsesskey,4); - -DEBUG(1,("NL: session key %08x %08x\n", - dcauth[cnum].sesskey[0], - dcauth[cnum].sesskey[1])); -} - -void checkcred(int cnum, uint32 cred0, uint32 cred1, uint32 time) -{ - uint32 sum[2]; - char netdata[8]; - char netsesskey[8]; - char calccred[8]; - char icv[8]; - char key2[7]; - - SIVAL(netdata, 0, dcauth[cnum].cred[0]+time); - SIVAL(netdata, 4, dcauth[cnum].cred[1]); - SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); - SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); - E1(netsesskey,netdata,icv); - memset(key2, 0, sizeof key2); - key2[0] = netsesskey[7]; - E1(key2, icv, calccred); - if (IVAL(calccred,0) != cred0 || - IVAL(calccred,4) != cred1) - { - DEBUG(1,("Incorrect client credential received cred %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", - cred0, cred1, time, - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].cred[0], dcauth[cnum].cred[1], - IVAL(calccred,0), IVAL(calccred,4))); - /* PAXX: do something about it! */ - } else - DEBUG(4,("Correct client credential received chal %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", - cred0, cred1, time, - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].cred[0], dcauth[cnum].cred[1], - IVAL(calccred,0), IVAL(calccred,4))); -} - -void makecred(int cnum, uint32 time, char *calccred) -{ - uint32 sum[2]; - char netdata[8]; - char netsesskey[8]; - char icv[8]; - char key2[7]; - - SIVAL(netdata, 0, dcauth[cnum].svrcred[0]+time); - SIVAL(netdata, 4, dcauth[cnum].svrcred[1]); - SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); - SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); - E1(netsesskey,netdata,icv); - memset(key2, 0, sizeof key2); - key2[0] = netsesskey[7]; - E1(key2, icv, calccred); - DEBUG(4,("Server credential: chal %lx %lx sk %lx %lx cred %lx %lx calc %lx %lx\n", - dcauth[cnum].svrchal[0], dcauth[cnum].svrchal[1], - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].svrcred[0], dcauth[cnum].svrcred[1], - IVAL(calccred, 0), IVAL(calccred, 4))); -} - - -struct uinfo *getuserinfo(char *user, int len, char *ntowfpass) -{ - static struct uinfo u; - static pstring fullnm; - static pstring ascuser; - extern pstring myname; - static pstring stme; - static pstring stdom; - struct smb_passwd *smb_pass; - - strcpy(ascuser,unistr(user)); - ascuser[len/2] = 0; /* PAXX: FIXMEFIXMEFIXME */ - DEBUG(1,("GETUSER username :%s: len=%d\n",ascuser, len)); - - smb_pass = get_smbpwnam(ascuser); - if(!smb_pass) - return 0; - DEBUG(1,("GETU %d\n", __LINE__)); - if (memcmp(ntowfpass, smb_pass->smb_nt_passwd, 16)) { - DEBUG(1,("pass mismatch:\n")); - dump_data(1,ntowfpass,16); - dump_data(1,smb_pass->smb_nt_passwd,16); - return 0; - } - - DEBUG(1,("GETU %d\n", __LINE__)); - u.logontime[0] = 0xffffffff; u.logontime[1] = 0x7fffffff; - u.logofftime[0] = 0xffffffff; u.logofftime[1] = 0x7fffffff; - u.kickofftime[0] = 0xffffffff; u.kickofftime[1] = 0x7fffffff; - DEBUG(1,("GETU %d\n", __LINE__)); - u.passlastsettime[0] = 0xffffffff; u.passlastsettime[1] = 0x7fffffff; - u.passcanchgtime[0] = 0xffffffff; u.passcanchgtime[1] = 0x7fffffff; - u.passmustchgtime[0] = 0xffffffff; u.passmustchgtime[1] = 0x7fffffff; - DEBUG(1,("GETU %d\n", __LINE__)); - u.effectivename = ascuser; - strcpy(fullnm, "Full name of "); - strcat(fullnm, ascuser); - DEBUG(1,("GETU %d\n", __LINE__)); - u.fullname = fullnm; - u.logonscript = "foologin.cmd"; - u.profilepath = "prof"; - u.homedirectory = "foohomes"; - DEBUG(1,("GETU %d\n", __LINE__)); - u.homedirectorydrive = "a:"; - u.logoncount = 7; - u.badpwcount = 8; - u.uid = 778; - DEBUG(1,("GETU %d\n", __LINE__)); - u.gid = 998; - u.ngroups = 2; - u.groups = (struct groupinfo *)(malloc(sizeof (struct groupinfo) * 2)); - u.groups[0].gid = 776; - DEBUG(1,("GETU %d\n", __LINE__)); - u.groups[0].attr = 0x7; - u.groups[1].gid = 776; - u.groups[1].attr = 0x7; - u.userflags = 0x20; - u.logonserver = stme; - get_myname(myname,NULL); - strcpy(stme, myname); - strupper(stme); - DEBUG(1,("LS %s\n", u.logonserver)); - u.logondomain = stdom; - strcpy(stdom, lp_workgroup()); - strupper(stdom); - DEBUG(1,("DOM %s\n", u.logondomain)); - u.nsids = 0; - u.sids = 0; - DEBUG(1,("GETU %d\n", __LINE__)); - return &u; -}; - -int -nametorid(char *uniuser) -{ - if (!strncmp(unistr(uniuser+12),"ashtonp",7)) - return 2000; - if (!strncmp(unistr(uniuser+12),"user1",5)) - return 1; - if (!strncmp(unistr(uniuser+12),"user2",5)) - return 10; - if (!strncmp(unistr(uniuser+12),"user3",5)) - return 100; - return 3000; -} - -#endif /* NTDOMAIN */ -- cgit From ad54a5671405374b6308929154c6922bc6a7d0d7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 9 Oct 1997 14:40:46 +0000 Subject: credentials.c: use UTIME structure (defined and commented in smb.h to be time, secs, since 01jan1970) pipes.c: another sub-function. util.c: added char *unistr2(uint16 *buff) function. same as unistr except it takes uint16* instead of char*. smbparse.c smb.h: more structure sorting. proto.h: the usual. (This used to be commit 72a86f514f0c92b69499718e63f5dd73ebece56e) --- source3/smbd/pipes.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 189 insertions(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index bedf847cc4..13cdff262d 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -370,6 +370,20 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, fragment length. I've decided to do it based on operation number :-) */ +/* RID username mapping function. just for fun, it maps to the unix uid */ +static uint32 name_to_rid(char *user_name) +{ + struct passwd *pw = Get_Pwnam(user_name, False); + if (!pw) + { + DEBUG(1,("Username %s is invalid on this system\n", user_name)); + return (uint32)(-1); + } + + return (uint32)(pw->pw_uid); +} + + /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ char *dom_sid_to_string(DOM_SID *sid) { @@ -504,6 +518,14 @@ static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate) str->buffer[len] = (uint16)terminate; } +static void make_dom_rid2(DOM_RID2 *rid2, uint32 rid) +{ + rid2->type = 0x5; + rid2->undoc = 0x5; + rid2->rid = rid; + rid2->rid_idx = 0; +} + static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str) { int len_sid_str = strlen(sid_str); @@ -585,6 +607,28 @@ static void make_dom_ref(DOM_R_REF *ref, make_dom_sid(&(ref->ref_dom[3]), other_sid3); } +static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l, + int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS], + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + int i; + + make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid, + other_sid1, other_sid2, other_sid3); + + r_l->num_entries = num_entries; + r_l->undoc_buffer = 1; + r_l->num_entries2 = num_entries; + + for (i = 0; i < num_entries; i++) + { + make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]); + } + + r_l->num_entries3 = num_entries; +} + static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS], char *dom_name, char *dom_sid, @@ -627,6 +671,26 @@ static int lsa_reply_lookup_sids(char *q, char *base, return q - start; } +static int lsa_reply_lookup_rids(char *q, char *base, + int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS], + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + char *start = q; + LSA_R_LOOKUP_RIDS r_l; + + /* set up the LSA Lookup RIDs response */ + make_reply_lookup_rids(&r_l, num_entries, dom_rids, + dom_name, dom_sid, other_sid1, other_sid2, other_sid3); + r_l.status = 0x0; + + /* store the response in the SMB stream */ + q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, char chal[8], int status) { memcpy(r_c->srv_chal.data, chal, sizeof(r_c->srv_chal.data)); @@ -952,6 +1016,129 @@ static void api_lsa_lookup_sids( char *param, char *data, *rdata_len = reply_len + 0x18; } +static void api_lsa_lookup_names( char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + int i; + LSA_Q_LOOKUP_RIDS q_l; + pstring dom_name; + pstring dom_sid; + uint32 dom_rids[MAX_LOOKUP_SIDS]; + + /* grab the info class and policy handle */ + lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4); + + pstrcpy(dom_name, lp_workgroup()); + pstrcpy(dom_sid , lp_domainsid()); + + /* convert received RIDs to strings, so we can do them. */ + for (i = 0; i < q_l.num_entries; i++) + { + char *user_name = unistr2(q_l.lookup_name[i].str.buffer); + dom_rids[i] = name_to_rid(user_name); + } + + /* construct reply. return status is always 0x0 */ + reply_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata + 0x18, + q_l.num_entries, dom_rids, /* text-converted SIDs */ + dom_name, dom_sid, /* domain name, domain SID */ + "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; +} + +#if 0 + q = data + 0x18; + policyhandle = q; q += 20; + nentries = qIVAL; + DEBUG(4,("lookupnames entries %d\n",nentries)); + q += 4; /* skip second count */ + q += 8 * nentries; /* skip pointers */ + for (nnames = 0; nnames < nentries; nnames++) + { + names[nnames] = q; /* set name string to unicode header */ + q += IVAL(q,0)*2; /* guessing here */ + } + /* There's a translated sids structure next but it looks fals */ + + DEBUG(4,("lookupnames line %d\n",__LINE__)); + /* formulate reply */ + q = *rdata + 0x18; + qSIVAL(2); /* bufptr */ + qSIVAL(4); /* number of referenced domains + - need one per each identifier authority in call */ + qSIVAL(2); /* dom bufptr */ + qSIVAL(32); /* max entries */ + qSIVAL(4); /* number of reference domains? */ + + qunihdr(lp_workgroup()); /* reference domain */ + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-1"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-5"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-3"); + qSIVAL(2); /* sid bufptr */ + + qunistr(lp_workgroup()); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + + strcpy(domsid,lp_domainsid()); + p = strtok(domsid+2,"-"); + revision = atoi(p); + identauth = atoi(strtok(0,"-")); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < numsubauths; i++) + { +qSIVAL(subauths[i]); + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-1"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-5"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + + qunistr("S-1-3"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + + qSIVAL(nentries); + qSIVAL(2); /* bufptr */ + qSIVAL(nentries); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { +qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ +qSSVAL(5); /* undocumented */ + DEBUG(4,("lookupnames line %d\n",__LINE__)); +qSIVAL(name_to_rid(names[i])); + DEBUG(4,("lookupnames name_to_rid %d\n",name_to_rid(names[i]))); +qSIVAL(0); /* domain index out of above reference domains */ + } + qSIVAL(nentries); /* mapped count */ + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + +#endif + + /* space in front of this function so that make proto doesn't pick it up */ void _dummy_function(void) { @@ -971,5 +1158,6 @@ static void api_lsa_lookup_sids( char *param, char *data, lsa_reply_sam_logoff(NULL,NULL,NULL,NULL,t,0); api_lsa_open_policy(NULL,NULL,NULL,NULL); api_lsa_query_info(NULL,NULL,NULL,NULL); - api_lsa_lookup_sids(NULL,NULL,NULL,NULL); + api_lsa_lookup_sids (NULL,NULL,NULL,NULL); + api_lsa_lookup_names(NULL,NULL,NULL,NULL); } -- cgit From 5a3ea52d4a567a341c8f2243783afdb392991ea2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 9 Oct 1997 15:48:40 +0000 Subject: pipes.c: added api_ntlsarpcTNP() function. hooray! smb.h: added LSA #defines needed by above function. (This used to be commit 5437f666987918516032cf8a5dada107e5d14d25) --- source3/smbd/pipes.c | 1175 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 1093 insertions(+), 82 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 13cdff262d..4dd7aa3e30 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -3,8 +3,8 @@ Version 1.9. Pipe SMB reply routines Copyright (C) Andrew Tridgell 1992-1997, - Paul Ashton 1997, - Luke Kenneth Casson Leighton 1996-1997. + Copyright (C) Luke Kenneth Casson Leighton 1996-1997. + Copyright (C) Paul Ashton 1997. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -370,6 +370,36 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, fragment length. I've decided to do it based on operation number :-) */ +/* this function is due to be replaced */ +static void initrpcreply(char *inbuf, char *q) +{ + uint32 callid; + + SCVAL(q, 0, 5); q++; /* RPC version 5 */ + SCVAL(q, 0, 0); q++; /* minor version 0 */ + SCVAL(q, 0, 2); q++; /* RPC response packet */ + SCVAL(q, 0, 3); q++; /* first frag + last frag */ + RSIVAL(q, 0, 0x10000000); q += 4; /* packed data representation */ + RSSVAL(q, 0, 0); q += 2; /* fragment length, fill in later */ + SSVAL(q, 0, 0); q += 2; /* authentication length */ + callid = RIVAL(inbuf, 12); + RSIVAL(q, 0, callid); q += 4; /* call identifier - match incoming RPC */ + SIVAL(q, 0, 0x18); q += 4; /* allocation hint (no idea) */ + SSVAL(q, 0, 0); q += 2; /* presentation context identifier */ + SCVAL(q, 0, 0); q++; /* cancel count */ + SCVAL(q, 0, 0); q++; /* reserved */ +} + +/* this function is due to be replaced */ +static void endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen) +{ + SSVAL(q, 8, datalen + 4); + SIVAL(q,0x10,datalen+4-0x18); /* allocation hint */ + SIVAL(q, datalen, rtnval); + *rlen = datalen + 4; + { int fd; fd = open("/tmp/rpc", O_RDWR); write(fd, q, datalen + 4); } +} + /* RID username mapping function. just for fun, it maps to the unix uid */ static uint32 name_to_rid(char *user_name) { @@ -1051,94 +1081,1079 @@ static void api_lsa_lookup_names( char *param, char *data, *rdata_len = reply_len + 0x18; } -#if 0 - q = data + 0x18; - policyhandle = q; q += 20; - nentries = qIVAL; - DEBUG(4,("lookupnames entries %d\n",nentries)); - q += 4; /* skip second count */ - q += 8 * nentries; /* skip pointers */ - for (nnames = 0; nnames < nentries; nnames++) +BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum = SVAL(data,22); + + int pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ + { + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; + } + + DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum)); + switch (opnum) + { + case LSA_OPENPOLICY: + { + DEBUG(3,("LSA_OPENPOLICY\n")); + api_lsa_open_policy(param, data, rdata, rdata_len); + break; + } + + case LSA_QUERYINFOPOLICY: + { + DEBUG(3,("LSA_QUERYINFOPOLICY\n")); + + api_lsa_query_info(param, data, rdata, rdata_len); + break; + } + + case LSA_ENUMTRUSTDOM: + { + char *q = *rdata + 0x18; + + DEBUG(3,("LSA_ENUMTRUSTDOM\n")); + + initrpcreply(data, *rdata); + + SIVAL(q, 0, 0); /* enumeration context */ + SIVAL(q, 0, 4); /* entries read */ + SIVAL(q, 0, 8); /* trust information */ + + endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len); + + break; + } + + case LSA_CLOSE: + { + char *q = *rdata + 0x18; + + DEBUG(3,("LSA_CLOSE\n")); + + initrpcreply(data, *rdata); + + SIVAL(q, 0, 0); + SIVAL(q, 0, 4); + SIVAL(q, 0, 8); + SIVAL(q, 0, 12); + SIVAL(q, 0, 16); + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + + break; + } + + case LSA_OPENSECRET: + { + char *q = *rdata + 0x18; + DEBUG(3,("LSA_OPENSECRET\n")); + + initrpcreply(data, *rdata); + + SIVAL(q, 0, 0); + SIVAL(q, 0, 4); + SIVAL(q, 0, 8); + SIVAL(q, 0, 12); + SIVAL(q, 0, 16); + + endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len); + + break; + } + + case LSA_LOOKUPSIDS: + { + DEBUG(3,("LSA_OPENSECRET\n")); + api_lsa_lookup_sids(param, data, rdata, rdata_len); + break; + } + + case LSA_LOOKUPNAMES: + { + DEBUG(3,("LSA_LOOKUPNAMES\n")); + api_lsa_lookup_names(param, data, rdata, rdata_len); + break; + } + + default: + { + DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum)); + break; + } + } + return True; +} + + +#ifdef UNDEFINED_NTDOMAIN +/* + PAXX: Someone fix above. + The above API is indexing RPC calls based on RPC flags and + fragment length. I've decided to do it based on operation number :-) +*/ + + BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum; + char *q; + char *domainname; + int domlen; + pstring domsid; + char *p; + int numsubauths; + int subauths[MAXSUBAUTHS]; + struct smb_passwd *smb_pass; /* To check if machine account exists */ + pstring machacct; + pstring foo; + uint16 infoclass; + uint16 revision; /* Domain sid revision */ + int identauth; + int i; + char *logonsrv; + char *unicomp; + char *accountname; + uint16 secchanneltype; + uint32 negflags; + char netcred[8]; + uint32 rcvcred[8]; + char rtncred[8]; + uint32 clnttime; + uint32 rtntime; + char *newpass; + uint16 logonlevel; + uint16 switchval; + uint16 dommaxlen; + uint16 paramcontrol; + uint32 logonid[2]; + uint16 usernamelen; + uint16 usernamemaxlen; + uint16 wslen; + uint16 wsmaxlen; + uchar *rc4lmowfpass; + uchar *rc4ntowfpass; + char *domain; + char *username; + char *ws; + struct uinfo *userinfo; + int pkttype; + uchar rc4key[16]; + uchar ntowfpass[16]; + uint32 nentries; + char *policyhandle; + #define MAXSIDS 64 + uchar *sids[MAXSIDS]; /* for lookup SID */ + int nsids; + #define MAXNAMES 64 + uchar *names[MAXNAMES]; + + opnum = SVAL(data,22); + + pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ { - names[nnames] = q; /* set name string to unicode header */ - q += IVAL(q,0)*2; /* guessing here */ + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; } - /* There's a translated sids structure next but it looks fals */ - - DEBUG(4,("lookupnames line %d\n",__LINE__)); - /* formulate reply */ - q = *rdata + 0x18; - qSIVAL(2); /* bufptr */ - qSIVAL(4); /* number of referenced domains - - need one per each identifier authority in call */ - qSIVAL(2); /* dom bufptr */ - qSIVAL(32); /* max entries */ - qSIVAL(4); /* number of reference domains? */ - - qunihdr(lp_workgroup()); /* reference domain */ - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-1"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-5"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-3"); - qSIVAL(2); /* sid bufptr */ - - qunistr(lp_workgroup()); - DEBUG(4,("lookupnames line %d\n",__LINE__)); - - strcpy(domsid,lp_domainsid()); - p = strtok(domsid+2,"-"); - revision = atoi(p); - identauth = atoi(strtok(0,"-")); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < numsubauths; i++) + + DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum)); + initrpcreply(data, *rdata); + DEBUG(4,("netlogon LINE %d\n",__LINE__)); + switch (opnum) { -qSIVAL(subauths[i]); - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); + case LSAOPENPOLICY: + DEBUG(1,("LSAOPENPOLICY\n")); + char *q = *rdata + 0x18; + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + /* return a 20 byte policy handle */ + /* here's a pretty handle:- */ + qSIVAL(time(NULL)); + qSIVAL(0x810a792f); + qSIVAL(0x11d107d5); + qSIVAL(time(NULL)); + qSIVAL(0x6cbcf800); + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); /* size of data plus return code */ + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + break; + + case LSAQUERYINFOPOLICY: + DEBUG(1,("LSAQUERYINFOPOLICY\n")); + dump_data(1,data,128); + infoclass = SVAL(data, 44); /* also a policy handle but who cares? */ + q = *rdata + 0x18; + qRSIVAL(0x00000022); /* undocumented. Usually a buffer pointer whose + value is ignored */ + qSSVAL(infoclass); + domainname = lp_workgroup(); + domlen = strlen(domainname); + strcpy(domsid,lp_domainsid()); + DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); + /* assume, but should check, that domsid starts "S-" */ + p = strtok(domsid+2,"-"); + revision = atoi(p); + DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); + identauth = atoi(strtok(0,"-")); + DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + + switch (infoclass) + { + case 5: + case 3: + default: + qSSVAL(0); /* 2 undocumented bytes */ + qSSVAL(domlen*2); + qSSVAL(domlen*2); /* unicode domain len and maxlen */ + qSIVAL(4); /* domain buffer pointer */ + qSIVAL(2); /* domain sid pointer */ + qunistr(domainname); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + } + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSAENUMTRUSTDOM: + DEBUG(1,("LSAENUMTRUSTDOM\n")); + q = *rdata + 0x18; + qSIVAL(0); /* enumeration context */ + qSIVAL(0); /* entries read */ + qSIVAL(0); /* trust information */ + endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len); + break; + + case LSACLOSE: + DEBUG(1,("LSACLOSE\n")); + q = *rdata + 0x18; + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; - qunistr("S-1-1"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); + case LSAOPENSECRET: + DEBUG(1,("LSAOPENSECRET\n")); + q = *rdata + 0x18; + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len); + break; + + case LSALOOKUPSIDS: + DEBUG(1,("LSAOPENSECRET\n")); + q = data + 0x18; + policyhandle = q; q += 20; + nentries = qIVAL; + DEBUG(4,("lookupsid entries %d\n",nentries)); + q += (2+nentries) * 4; /* skip bufptrs */ + /* now we have nentries sids of the form: + uint32 Subauthority count (SAC) + char Revision + char Subaurity count again + char[6] Identifier authority + [uint32 subauthority] * SAC + */ + for (nsids = 0; nsids < nentries; nsids++) + { + DEBUG(4,("lookupsid q in %lx\n",q)); + sids[nsids] = q; + DEBUG(4,("lookupsid numsubs %d\n",IVAL(q,0))); + q += 4+1+1+6+IVAL(q,0)*4; + DEBUG(4,("lookupsid q %lx\n",q)); + } + /* There's 16 bytes of something after all of that, don't know + what it is though - incorrectly documented */ + + DEBUG(4,("lookupsid line %d\n",__LINE__)); + /* formulate reply */ + q = *rdata + 0x18; + qSIVAL(2); /* bufptr */ + qSIVAL(4); /* number of referenced domains + - need one per each identifier authority in call */ + qSIVAL(2); /* dom bufptr */ + qSIVAL(32); /* max entries */ + qSIVAL(4); /* number of reference domains? */ + + qunihdr(lp_workgroup()); /* reference domain */ + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-1"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-5"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-3"); + qSIVAL(2); /* sid bufptr */ + + qunistr(lp_workgroup()); + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + strcpy(domsid,lp_domainsid()); + p = strtok(domsid+2,"-"); + revision = atoi(p); + identauth = atoi(strtok(0,"-")); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); - qunistr("S-1-5"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + qunistr("S-1-1"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); - qunistr("S-1-3"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + qunistr("S-1-5"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ - qSIVAL(nentries); - qSIVAL(2); /* bufptr */ - qSIVAL(nentries); - DEBUG(4,("lookupnames line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) + qunistr("S-1-3"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + + qSIVAL(nentries); + qSIVAL(2); /* bufptr */ + qSIVAL(nentries); + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qSSVAL(5); /* SID name use ?! */ + qSSVAL(0); /* undocumented */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + qunihdr(sidtostring(sids[i])); + DEBUG(4,("lookupsid sidname %s\n",sidtostring(sids[i]))); + qSIVAL(0); /* domain index out of above reference domains */ + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qunistr(sidtostring(sids[i])); + } + qSIVAL(nentries); /* mapped count */ + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSALOOKUPNAMES: + DEBUG(1,("LSALOOKUPNAMES\n")); + q = data + 0x18; + policyhandle = q; q += 20; + nentries = qIVAL; + DEBUG(4,("lookupnames entries %d\n",nentries)); + q += 4; /* skip second count */ + q += 8 * nentries; /* skip pointers */ + for (nnames = 0; nnames < nentries; nnames++) + { + names[nnames] = q; /* set name string to unicode header */ + q += IVAL(q,0)*2; /* guessing here */ + } + /* There's a translated sids structure next but it looks fals */ + + DEBUG(4,("lookupnames line %d\n",__LINE__)); + /* formulate reply */ + q = *rdata + 0x18; + qSIVAL(2); /* bufptr */ + qSIVAL(4); /* number of referenced domains + - need one per each identifier authority in call */ + qSIVAL(2); /* dom bufptr */ + qSIVAL(32); /* max entries */ + qSIVAL(4); /* number of reference domains? */ + + qunihdr(lp_workgroup()); /* reference domain */ + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-1"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-5"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-3"); + qSIVAL(2); /* sid bufptr */ + + qunistr(lp_workgroup()); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + + strcpy(domsid,lp_domainsid()); + p = strtok(domsid+2,"-"); + revision = atoi(p); + identauth = atoi(strtok(0,"-")); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-1"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-5"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + + qunistr("S-1-3"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + + qSIVAL(nentries); + qSIVAL(2); /* bufptr */ + qSIVAL(nentries); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ + qSSVAL(5); /* undocumented */ + DEBUG(4,("lookupnames line %d\n",__LINE__)); + qSIVAL(nametorid(names[i])); + DEBUG(4,("lookupnames nametorid %d\n",nametorid(names[i]))); + qSIVAL(0); /* domain index out of above reference domains */ + } + qSIVAL(nentries); /* mapped count */ + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + default: + DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum)); + } + return(True); +} + + BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum; + char *q; + char *domainname; + int domlen; + pstring domsid; + char *p; + int numsubauths; + int subauths[MAXSUBAUTHS]; + struct smb_passwd *smb_pass; /* To check if machine account exists */ + pstring machacct; + pstring foo; + uint16 infoclass; + uint16 revision; /* Domain sid revision */ + int identauth; + int i; + char *logonsrv; + char *unicomp; + char *accountname; + uint16 secchanneltype; + uint32 negflags; + char netcred[8]; + uint32 rcvcred[8]; + char rtncred[8]; + uint32 clnttime; + uint32 rtntime; + char *newpass; + uint16 logonlevel; + uint16 switchval; + uint16 dommaxlen; + uint16 paramcontrol; + uint32 logonid[2]; + uint16 usernamelen; + uint16 usernamemaxlen; + uint16 wslen; + uint16 wsmaxlen; + uchar *rc4lmowfpass; + uchar *rc4ntowfpass; + char *domain; + char *username; + char *ws; + struct uinfo *userinfo; + int pkttype; + ArcfourContext c; + uchar rc4key[16]; + uchar ntowfpass[16]; + + opnum = SVAL(data,22); + + pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ { -qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ -qSSVAL(5); /* undocumented */ - DEBUG(4,("lookupnames line %d\n",__LINE__)); -qSIVAL(name_to_rid(names[i])); - DEBUG(4,("lookupnames name_to_rid %d\n",name_to_rid(names[i]))); -qSIVAL(0); /* domain index out of above reference domains */ + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; } - qSIVAL(nentries); /* mapped count */ - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; -#endif + DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); + initrpcreply(data, *rdata); + DEBUG(4,("netlogon LINE %d\n",__LINE__)); + switch (opnum) + { + case LSAREQCHAL: + DEBUG(1,("LSAREQCHAL\n")); + q = data + 0x18; + dump_data(1,q,128); + logonsrv = q + 16; /* first 16 bytes, buffer ptr, + unicode lenghts */ + q = skip_unicode_string(logonsrv,1) + 12; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1); + + + DEBUG(1,("logonsrv=%s unicomp=%s\n", + unistr(logonsrv), + unistr(unicomp))); + + dcauth[cnum].chal[0] = IVAL(q, 0); + dcauth[cnum].chal[1] = IVAL(q, 4); + dcauth[cnum].cred[0] = IVAL(q, 0); /* this looks weird (tridge) */ + dcauth[cnum].cred[1] = IVAL(q, 4); + +DEBUG(1,("NL: client challenge %08x %08x\n", dcauth[cnum].chal[0],dcauth[cnum].chal[1])); + + /* PAXX: set these to random values */ + dcauth[cnum].svrchal[0] = 0x11111111; + dcauth[cnum].svrchal[1] = 0x22222222; + dcauth[cnum].svrcred[0] = 0x11111111; + dcauth[cnum].svrcred[1] = 0x22222222; + strcpy(machacct,unistr(unicomp)); + strcat(machacct, "$"); + smb_pass = get_smbpwnam(machacct); + if(smb_pass) + memcpy(dcauth[cnum].md4pw, smb_pass->smb_nt_passwd, 16); + else + { + /* No such machine account. Should error out here, but we'll + print and carry on */ + DEBUG(1,("No account in domain at REQCHAL for %s\n", machacct)); + } + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",dcauth[cnum].md4pw[i]); + DEBUG(1,("pass %s %s\n", machacct, foo)); + setsesskey(cnum); + q = *rdata + 0x18; + qSIVAL(dcauth[cnum].svrchal[0]); + qSIVAL(dcauth[cnum].svrchal[1]); + +DEBUG(1,("NL: server challenge %08x %08x\n", + dcauth[cnum].svrchal[0],dcauth[cnum].svrchal[1])); + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSAAUTH2: + DEBUG(1,("LSAAUTH2\n")); + dump_data(1,q,128); + q = data + 0x18; + logonsrv = q + 16; + q = skip_unicode_string(logonsrv,1)+12; + q = align4(q, data); + accountname = q; + + q = skip_unicode_string(accountname,1); + secchanneltype = qSVAL; + q += 12; + q = align4(q, data); + unicomp = q; + dump_data(1,unicomp,32); + q = skip_unicode_string(unicomp,1); + rcvcred[0] = qIVAL; + rcvcred[1] = qIVAL; + q = align4(q, data); + negflags = qIVAL; + DEBUG(3,("AUTH2 logonsrv=%s accountname=%s unicomp=%s %lx %lx %lx\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp), + rcvcred[0], rcvcred[1], negflags)); + +DEBUG(1,("NL: recvcred %08x %08x negflags=%08x\n", + rcvcred[0], rcvcred[1], negflags)); + + checkcred(cnum, rcvcred[0], rcvcred[1], 0); + q = *rdata + 0x18; + makecred(cnum, 0, q); + q += 8; + + qSIVAL(negflags); + /* update stored client credentials */ + dcauth[cnum].cred[0] = dcauth[cnum].svrcred[0] = rcvcred[0]; + dcauth[cnum].cred[1] = dcauth[cnum].svrcred[1] = rcvcred[1]; + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSASVRPWSET: + DEBUG(1,("LSASVRPWSET\n")); + q = data + 0x18; + dump_data(1,q,128); + logonsrv = q + 16; + q = skip_unicode_string(logonsrv,1)+12; + q = align4(q, data); + accountname = q; + q = skip_unicode_string(accountname,1); + secchanneltype = qSVAL; + q += 12; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1); + rcvcred[0] = qIVAL; + rcvcred[1] = qIVAL; + clnttime = qIVAL; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp))); + + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); + newpass = q; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); + + /* PAXX: For the moment we'll reject these */ + /* TODO Need to set newpass in smbpasswd file for accountname */ + q = *rdata + 0x18; + makecred(cnum, clnttime+1, q); + q += 8; + qSIVAL(0); /* timestamp. Seems to be ignored */ + + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + + endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); + break; + + case LSASAMLOGON: + DEBUG(1,("LSASAMLOGON\n")); + dump_data(1,data,128); + q = data + 0x18; + logonsrv = q + 16; + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = skip_unicode_string(logonsrv,1)+16; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1)+4; + DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n", + __LINE__, unistr(logonsrv), unistr(unicomp))); + q = align4(q, data); + rcvcred[0] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[1] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + clnttime = qIVAL; + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + q += 2; + rtncred[0] = qIVAL; /* all these are ignored */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + rtncred[1] = qIVAL; + rtntime = qIVAL; + logonlevel = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + switchval = qSVAL; + switch (switchval) + { + case 1: + + q += 6; + domlen = qSVAL; + dommaxlen = qSVAL; q += 4; + paramcontrol = qIVAL; + logonid[0] = qIVAL; /* low part */ + logonid[1] = qIVAL; /* high part */ + + usernamelen = qSVAL; + + DEBUG(1,("SMLOG %d\n", __LINE__)); + usernamemaxlen = qSVAL; q += 4; + + DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n", + usernamelen, usernamemaxlen, dommaxlen)); + + dump_data(1,q,128); + + wslen = qSVAL; + wsmaxlen = qSVAL; q += 4; + rc4lmowfpass = q; q += 16; + rc4ntowfpass = q; q += 16; + + q += 12; domain = q; q += dommaxlen + 12; + q = align4(q, data); + username = q; q += usernamemaxlen + 12; + q = align4(q, data); + ws = q; + DEBUG(1,("domain=%s username=%s ws=%s\n", + unistr(domain), unistr(username), + unistr(ws))); + break; + default: + DEBUG(0,("unknown switch in SAMLOGON %d\n", + switchval)); + } + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]); + DEBUG(1,("userNAME %s [%s]\n", foo, username)); + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = *rdata + 0x18; + qSIVAL(0x16a4b4); /* magic buffer pointer ? */ + makecred(cnum, clnttime+1, q); + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + q += 8; + qSIVAL(0); /* timestamp. client doesn't care */ + qSSVAL(3); /* switch value 3. May be others? */ + qSSVAL(0); /* undocumented */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + + memset(rc4key, 0, sizeof rc4key); + SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]); + SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]); + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]); + DEBUG(1,("rc4ntowf %s\n", foo)); + arcfour_init(&c, rc4key, sizeof rc4key); + arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass); + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]); + DEBUG(1,("ntowf %s\n", foo)); + + if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) { + qSIVAL(0); /* no buffer */ + qSCVAL(1); /* Authoratitive. Change if passthrough? */ + qSCVAL(0); /* pad for above boolean */ + qSSVAL(0); /* pad for above boolean */ + + endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len); + break; + } + + qSIVAL(2); /* another magic bufptr? */ + DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo)); + qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]); + qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]); + DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1])); + qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]); + qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]); + qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]); + qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]); + DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename)); + qunihdr(userinfo->effectivename); + qunihdr(userinfo->fullname); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunihdr(userinfo->logonscript); + qunihdr(userinfo->profilepath); + qunihdr(userinfo->homedirectory); + qunihdr(userinfo->homedirectorydrive); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSSVAL(userinfo->logoncount); + qSSVAL(userinfo->badpwcount); + qSIVAL(userinfo->uid); + qSIVAL(userinfo->gid); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->ngroups); + qSIVAL(8); /* ptr to groups */ + qSIVAL(userinfo->userflags); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */ + qunihdr(userinfo->logonserver); + qunihdr(userinfo->logondomain); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(2); /* logon domain id ptr */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + memset(q,0,40); q += 40; /* expansion room */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->nsids); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(0); /* ptr to sids and values */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->effectivename); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->fullname); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->logonscript); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->profilepath); + qunistr(userinfo->homedirectory); + qunistr(userinfo->homedirectorydrive); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->ngroups); + for (i = 0; i < userinfo->ngroups; i++) + { + qSIVAL(userinfo->groups[i].gid); + qSIVAL(userinfo->groups[i].attr); + } + qunistr(userinfo->logonserver); + qunistr(userinfo->logondomain); + for (i = 0; i < userinfo->nsids; i++) + { + /* put the extra sids: PAXX: TODO */ + } + /* Assumption. This is the only domain, sending our SID */ + /* PAXX: may want to do passthrough later */ + strcpy(domsid,lp_domainsid()); + DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); + /* assume, but should check, that domsid starts "S-" */ + p = strtok(domsid+2,"-"); + revision = atoi(p); + DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); + identauth = atoi(strtok(0,"-")); + DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + qSCVAL(1); /* Authoratitive. Change if passthrough? */ + qSCVAL(0); /* pad for above boolean */ + qSSVAL(0); /* pad for above boolean */ + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSASAMLOGOFF: + DEBUG(1,("LSASAMLOGOFF\n")); + q = data + 0x18; + logonsrv = q + 16; + DEBUG(1,("SAMLOGOFF %d\n", __LINE__)); + unicomp = skip_unicode_string(logonsrv,1)+16; + if (strlen(unistr(logonsrv)) % 2 == 0) + q += 2; + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = skip_unicode_string(unicomp,1)+4; + if (strlen(unistr(unicomp)) % 2 == 0) + q += 2; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[0] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[1] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + clnttime = qIVAL; + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + q += 4; + rtncred[0] = qIVAL; /* all these are ignored */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + rtncred[1] = qIVAL; + rtntime = qIVAL; + logonlevel = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + switchval = qSVAL; + switch (switchval) + { + case 1: + q += 4; + domlen = qSVAL; + dommaxlen = qSVAL; q += 4; + paramcontrol = qIVAL; + logonid[0] = qIVAL; /* low part */ + logonid[1] = qIVAL; /* high part */ + usernamelen = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + usernamemaxlen = qSVAL; q += 4; + wslen = qSVAL; + wsmaxlen = qSVAL; q += 4; + rc4lmowfpass = q; q += 16; + rc4ntowfpass = q; q += 16; + q += 12; domain = q; q += dommaxlen + 12; + if ((domlen/2) % 2 != 0) q += 2; + username = q; q += usernamemaxlen + 12; /* PAXX: HACK */ + if ((usernamelen/2) % 2 != 0) q += 2; + ws = q; + break; + default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval)); + } + DEBUG(1,("SAMLOGOFF %s\n", unistr(username))); + default: + DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); + } + return(True); +} + +static void checkcred(int cnum, uint32 cred0, uint32 cred1, uint32 time) +{ + uint32 sum[2]; + char netdata[8]; + char netsesskey[8]; + char calccred[8]; + char icv[8]; + char key2[7]; + + SIVAL(netdata, 0, dcauth[cnum].cred[0]+time); + SIVAL(netdata, 4, dcauth[cnum].cred[1]); + SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); + SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); + E1(netsesskey,netdata,icv); + memset(key2, 0, sizeof key2); + key2[0] = netsesskey[7]; + E1(key2, icv, calccred); + if (IVAL(calccred,0) != cred0 || + IVAL(calccred,4) != cred1) + { + DEBUG(1,("Incorrect client credential received cred %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", + cred0, cred1, time, + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].cred[0], dcauth[cnum].cred[1], + IVAL(calccred,0), IVAL(calccred,4))); + /* PAXX: do something about it! */ + } else + DEBUG(4,("Correct client credential received chal %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", + cred0, cred1, time, + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].cred[0], dcauth[cnum].cred[1], + IVAL(calccred,0), IVAL(calccred,4))); +} + +static void makecred(int cnum, uint32 time, char *calccred) +{ + uint32 sum[2]; + char netdata[8]; + char netsesskey[8]; + char icv[8]; + char key2[7]; + + SIVAL(netdata, 0, dcauth[cnum].svrcred[0]+time); + SIVAL(netdata, 4, dcauth[cnum].svrcred[1]); + SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); + SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); + E1(netsesskey,netdata,icv); + memset(key2, 0, sizeof key2); + key2[0] = netsesskey[7]; + E1(key2, icv, calccred); + DEBUG(4,("Server credential: chal %lx %lx sk %lx %lx cred %lx %lx calc %lx %lx\n", + dcauth[cnum].svrchal[0], dcauth[cnum].svrchal[1], + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].svrcred[0], dcauth[cnum].svrcred[1], + IVAL(calccred, 0), IVAL(calccred, 4))); +} + +static void setsesskey(int cnum) +{ + uint32 sum[2]; + char netsum[8]; + char netsesskey[8]; + char icv[8]; + + sum[0] = dcauth[cnum].chal[0] + dcauth[cnum].svrchal[0]; + sum[1] = dcauth[cnum].chal[1] + dcauth[cnum].svrchal[1]; + SIVAL(netsum,0,sum[0]); + SIVAL(netsum,4,sum[1]); + E1(dcauth[cnum].md4pw,netsum,icv); + E1(dcauth[cnum].md4pw+9,icv,netsesskey); + dcauth[cnum].sesskey[0] = IVAL(netsesskey,0); + dcauth[cnum].sesskey[1] = IVAL(netsesskey,4); + +DEBUG(1,("NL: session key %08x %08x\n", + dcauth[cnum].sesskey[0], + dcauth[cnum].sesskey[1])); +} + +static struct uinfo *getuserinfo(char *user, int len, char *ntowfpass) +{ + static struct uinfo u; + static pstring fullnm; + static pstring ascuser; + extern pstring myname; + static pstring stme; + static pstring stdom; + struct smb_passwd *smb_pass; + + strcpy(ascuser,unistr(user)); + ascuser[len/2] = 0; /* PAXX: FIXMEFIXMEFIXME */ + DEBUG(1,("GETUSER username :%s: len=%d\n",ascuser, len)); + + smb_pass = get_smbpwnam(ascuser); + if(!smb_pass) + return 0; + DEBUG(1,("GETU %d\n", __LINE__)); + if (memcmp(ntowfpass, smb_pass->smb_nt_passwd, 16)) { + DEBUG(1,("pass mismatch:\n")); + dump_data(1,ntowfpass,16); + dump_data(1,smb_pass->smb_nt_passwd,16); + return 0; + } + + DEBUG(1,("GETU %d\n", __LINE__)); + u.logontime[0] = 0xffffffff; u.logontime[1] = 0x7fffffff; + u.logofftime[0] = 0xffffffff; u.logofftime[1] = 0x7fffffff; + u.kickofftime[0] = 0xffffffff; u.kickofftime[1] = 0x7fffffff; + DEBUG(1,("GETU %d\n", __LINE__)); + u.passlastsettime[0] = 0xffffffff; u.passlastsettime[1] = 0x7fffffff; + u.passcanchgtime[0] = 0xffffffff; u.passcanchgtime[1] = 0x7fffffff; + u.passmustchgtime[0] = 0xffffffff; u.passmustchgtime[1] = 0x7fffffff; + DEBUG(1,("GETU %d\n", __LINE__)); + u.effectivename = ascuser; + strcpy(fullnm, "Full name of "); + strcat(fullnm, ascuser); + DEBUG(1,("GETU %d\n", __LINE__)); + u.fullname = fullnm; + u.logonscript = "foologin.cmd"; + u.profilepath = "prof"; + u.homedirectory = "foohomes"; + DEBUG(1,("GETU %d\n", __LINE__)); + u.homedirectorydrive = "a:"; + u.logoncount = 7; + u.badpwcount = 8; + u.uid = 778; + DEBUG(1,("GETU %d\n", __LINE__)); + u.gid = 998; + u.ngroups = 2; + u.groups = (struct groupinfo *)(malloc(sizeof (struct groupinfo) * 2)); + u.groups[0].gid = 776; + DEBUG(1,("GETU %d\n", __LINE__)); + u.groups[0].attr = 0x7; + u.groups[1].gid = 776; + u.groups[1].attr = 0x7; + u.userflags = 0x20; + u.logonserver = stme; + get_myname(myname,NULL); + strcpy(stme, myname); + strupper(stme); + DEBUG(1,("LS %s\n", u.logonserver)); + u.logondomain = stdom; + strcpy(stdom, lp_workgroup()); + strupper(stdom); + DEBUG(1,("DOM %s\n", u.logondomain)); + u.nsids = 0; + u.sids = 0; + DEBUG(1,("GETU %d\n", __LINE__)); + return &u; +}; +#endif /* NTDOMAIN */ /* space in front of this function so that make proto doesn't pick it up */ void _dummy_function(void) { @@ -1156,8 +2171,4 @@ qSIVAL(0); /* domain index out of above reference domains */ NULL, NULL); lsa_reply_sam_logon(NULL,NULL,NULL,NULL,t, NULL); lsa_reply_sam_logoff(NULL,NULL,NULL,NULL,t,0); - api_lsa_open_policy(NULL,NULL,NULL,NULL); - api_lsa_query_info(NULL,NULL,NULL,NULL); - api_lsa_lookup_sids (NULL,NULL,NULL,NULL); - api_lsa_lookup_names(NULL,NULL,NULL,NULL); } -- cgit From 3dd03e4bb7af903eae162648bbf51da04fa68200 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 9 Oct 1997 16:14:53 +0000 Subject: added #ifdef NTDOMAIN. added call to api_ntLsarpc instead of api_Lsarpc in ipc.c iff NTDOMAIN is defined. (This used to be commit 7bc4c4c27bf18ce3f632d230dc919ea341b5abb0) --- source3/smbd/pipes.c | 984 +-------------------------------------------------- 1 file changed, 3 insertions(+), 981 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 4dd7aa3e30..6937412e29 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -54,7 +54,7 @@ a packet to ensure chaining works correctly */ char * known_pipes [] = { "lsarpc", -#if 0 +#if NTDOMAIN "NETLOGON", #endif NULL @@ -364,6 +364,8 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, return(True); } + +#ifdef NTDOMAIN /* PAXX: Someone fix above. The above API is indexing RPC calls based on RPC flags and @@ -1191,984 +1193,4 @@ BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, return True; } - -#ifdef UNDEFINED_NTDOMAIN -/* - PAXX: Someone fix above. - The above API is indexing RPC calls based on RPC flags and - fragment length. I've decided to do it based on operation number :-) -*/ - - BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - uint16 opnum; - char *q; - char *domainname; - int domlen; - pstring domsid; - char *p; - int numsubauths; - int subauths[MAXSUBAUTHS]; - struct smb_passwd *smb_pass; /* To check if machine account exists */ - pstring machacct; - pstring foo; - uint16 infoclass; - uint16 revision; /* Domain sid revision */ - int identauth; - int i; - char *logonsrv; - char *unicomp; - char *accountname; - uint16 secchanneltype; - uint32 negflags; - char netcred[8]; - uint32 rcvcred[8]; - char rtncred[8]; - uint32 clnttime; - uint32 rtntime; - char *newpass; - uint16 logonlevel; - uint16 switchval; - uint16 dommaxlen; - uint16 paramcontrol; - uint32 logonid[2]; - uint16 usernamelen; - uint16 usernamemaxlen; - uint16 wslen; - uint16 wsmaxlen; - uchar *rc4lmowfpass; - uchar *rc4ntowfpass; - char *domain; - char *username; - char *ws; - struct uinfo *userinfo; - int pkttype; - uchar rc4key[16]; - uchar ntowfpass[16]; - uint32 nentries; - char *policyhandle; - #define MAXSIDS 64 - uchar *sids[MAXSIDS]; /* for lookup SID */ - int nsids; - #define MAXNAMES 64 - uchar *names[MAXNAMES]; - - opnum = SVAL(data,22); - - pkttype = CVAL(data, 2); - if (pkttype == 0x0b) /* RPC BIND */ - { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } - - DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum)); - initrpcreply(data, *rdata); - DEBUG(4,("netlogon LINE %d\n",__LINE__)); - switch (opnum) - { - case LSAOPENPOLICY: - DEBUG(1,("LSAOPENPOLICY\n")); - char *q = *rdata + 0x18; - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - /* return a 20 byte policy handle */ - /* here's a pretty handle:- */ - qSIVAL(time(NULL)); - qSIVAL(0x810a792f); - qSIVAL(0x11d107d5); - qSIVAL(time(NULL)); - qSIVAL(0x6cbcf800); - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); /* size of data plus return code */ - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - break; - - case LSAQUERYINFOPOLICY: - DEBUG(1,("LSAQUERYINFOPOLICY\n")); - dump_data(1,data,128); - infoclass = SVAL(data, 44); /* also a policy handle but who cares? */ - q = *rdata + 0x18; - qRSIVAL(0x00000022); /* undocumented. Usually a buffer pointer whose - value is ignored */ - qSSVAL(infoclass); - domainname = lp_workgroup(); - domlen = strlen(domainname); - strcpy(domsid,lp_domainsid()); - DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); - /* assume, but should check, that domsid starts "S-" */ - p = strtok(domsid+2,"-"); - revision = atoi(p); - DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); - identauth = atoi(strtok(0,"-")); - DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - - switch (infoclass) - { - case 5: - case 3: - default: - qSSVAL(0); /* 2 undocumented bytes */ - qSSVAL(domlen*2); - qSSVAL(domlen*2); /* unicode domain len and maxlen */ - qSIVAL(4); /* domain buffer pointer */ - qSIVAL(2); /* domain sid pointer */ - qunistr(domainname); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - } - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSAENUMTRUSTDOM: - DEBUG(1,("LSAENUMTRUSTDOM\n")); - q = *rdata + 0x18; - qSIVAL(0); /* enumeration context */ - qSIVAL(0); /* entries read */ - qSIVAL(0); /* trust information */ - endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len); - break; - - case LSACLOSE: - DEBUG(1,("LSACLOSE\n")); - q = *rdata + 0x18; - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSAOPENSECRET: - DEBUG(1,("LSAOPENSECRET\n")); - q = *rdata + 0x18; - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len); - break; - - case LSALOOKUPSIDS: - DEBUG(1,("LSAOPENSECRET\n")); - q = data + 0x18; - policyhandle = q; q += 20; - nentries = qIVAL; - DEBUG(4,("lookupsid entries %d\n",nentries)); - q += (2+nentries) * 4; /* skip bufptrs */ - /* now we have nentries sids of the form: - uint32 Subauthority count (SAC) - char Revision - char Subaurity count again - char[6] Identifier authority - [uint32 subauthority] * SAC - */ - for (nsids = 0; nsids < nentries; nsids++) - { - DEBUG(4,("lookupsid q in %lx\n",q)); - sids[nsids] = q; - DEBUG(4,("lookupsid numsubs %d\n",IVAL(q,0))); - q += 4+1+1+6+IVAL(q,0)*4; - DEBUG(4,("lookupsid q %lx\n",q)); - } - /* There's 16 bytes of something after all of that, don't know - what it is though - incorrectly documented */ - - DEBUG(4,("lookupsid line %d\n",__LINE__)); - /* formulate reply */ - q = *rdata + 0x18; - qSIVAL(2); /* bufptr */ - qSIVAL(4); /* number of referenced domains - - need one per each identifier authority in call */ - qSIVAL(2); /* dom bufptr */ - qSIVAL(32); /* max entries */ - qSIVAL(4); /* number of reference domains? */ - - qunihdr(lp_workgroup()); /* reference domain */ - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-1"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-5"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-3"); - qSIVAL(2); /* sid bufptr */ - - qunistr(lp_workgroup()); - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - strcpy(domsid,lp_domainsid()); - p = strtok(domsid+2,"-"); - revision = atoi(p); - identauth = atoi(strtok(0,"-")); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - qunistr("S-1-1"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - qunistr("S-1-5"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ - - qunistr("S-1-3"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ - - qSIVAL(nentries); - qSIVAL(2); /* bufptr */ - qSIVAL(nentries); - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qSSVAL(5); /* SID name use ?! */ - qSSVAL(0); /* undocumented */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - qunihdr(sidtostring(sids[i])); - DEBUG(4,("lookupsid sidname %s\n",sidtostring(sids[i]))); - qSIVAL(0); /* domain index out of above reference domains */ - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qunistr(sidtostring(sids[i])); - } - qSIVAL(nentries); /* mapped count */ - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSALOOKUPNAMES: - DEBUG(1,("LSALOOKUPNAMES\n")); - q = data + 0x18; - policyhandle = q; q += 20; - nentries = qIVAL; - DEBUG(4,("lookupnames entries %d\n",nentries)); - q += 4; /* skip second count */ - q += 8 * nentries; /* skip pointers */ - for (nnames = 0; nnames < nentries; nnames++) - { - names[nnames] = q; /* set name string to unicode header */ - q += IVAL(q,0)*2; /* guessing here */ - } - /* There's a translated sids structure next but it looks fals */ - - DEBUG(4,("lookupnames line %d\n",__LINE__)); - /* formulate reply */ - q = *rdata + 0x18; - qSIVAL(2); /* bufptr */ - qSIVAL(4); /* number of referenced domains - - need one per each identifier authority in call */ - qSIVAL(2); /* dom bufptr */ - qSIVAL(32); /* max entries */ - qSIVAL(4); /* number of reference domains? */ - - qunihdr(lp_workgroup()); /* reference domain */ - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-1"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-5"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-3"); - qSIVAL(2); /* sid bufptr */ - - qunistr(lp_workgroup()); - DEBUG(4,("lookupnames line %d\n",__LINE__)); - - strcpy(domsid,lp_domainsid()); - p = strtok(domsid+2,"-"); - revision = atoi(p); - identauth = atoi(strtok(0,"-")); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - qunistr("S-1-1"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - qunistr("S-1-5"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ - - qunistr("S-1-3"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ - - qSIVAL(nentries); - qSIVAL(2); /* bufptr */ - qSIVAL(nentries); - DEBUG(4,("lookupnames line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ - qSSVAL(5); /* undocumented */ - DEBUG(4,("lookupnames line %d\n",__LINE__)); - qSIVAL(nametorid(names[i])); - DEBUG(4,("lookupnames nametorid %d\n",nametorid(names[i]))); - qSIVAL(0); /* domain index out of above reference domains */ - } - qSIVAL(nentries); /* mapped count */ - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - default: - DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum)); - } - return(True); -} - - BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - uint16 opnum; - char *q; - char *domainname; - int domlen; - pstring domsid; - char *p; - int numsubauths; - int subauths[MAXSUBAUTHS]; - struct smb_passwd *smb_pass; /* To check if machine account exists */ - pstring machacct; - pstring foo; - uint16 infoclass; - uint16 revision; /* Domain sid revision */ - int identauth; - int i; - char *logonsrv; - char *unicomp; - char *accountname; - uint16 secchanneltype; - uint32 negflags; - char netcred[8]; - uint32 rcvcred[8]; - char rtncred[8]; - uint32 clnttime; - uint32 rtntime; - char *newpass; - uint16 logonlevel; - uint16 switchval; - uint16 dommaxlen; - uint16 paramcontrol; - uint32 logonid[2]; - uint16 usernamelen; - uint16 usernamemaxlen; - uint16 wslen; - uint16 wsmaxlen; - uchar *rc4lmowfpass; - uchar *rc4ntowfpass; - char *domain; - char *username; - char *ws; - struct uinfo *userinfo; - int pkttype; - ArcfourContext c; - uchar rc4key[16]; - uchar ntowfpass[16]; - - opnum = SVAL(data,22); - - pkttype = CVAL(data, 2); - if (pkttype == 0x0b) /* RPC BIND */ - { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } - - DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); - initrpcreply(data, *rdata); - DEBUG(4,("netlogon LINE %d\n",__LINE__)); - switch (opnum) - { - case LSAREQCHAL: - DEBUG(1,("LSAREQCHAL\n")); - q = data + 0x18; - dump_data(1,q,128); - logonsrv = q + 16; /* first 16 bytes, buffer ptr, + unicode lenghts */ - q = skip_unicode_string(logonsrv,1) + 12; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1); - - - DEBUG(1,("logonsrv=%s unicomp=%s\n", - unistr(logonsrv), - unistr(unicomp))); - - dcauth[cnum].chal[0] = IVAL(q, 0); - dcauth[cnum].chal[1] = IVAL(q, 4); - dcauth[cnum].cred[0] = IVAL(q, 0); /* this looks weird (tridge) */ - dcauth[cnum].cred[1] = IVAL(q, 4); - -DEBUG(1,("NL: client challenge %08x %08x\n", dcauth[cnum].chal[0],dcauth[cnum].chal[1])); - - /* PAXX: set these to random values */ - dcauth[cnum].svrchal[0] = 0x11111111; - dcauth[cnum].svrchal[1] = 0x22222222; - dcauth[cnum].svrcred[0] = 0x11111111; - dcauth[cnum].svrcred[1] = 0x22222222; - strcpy(machacct,unistr(unicomp)); - strcat(machacct, "$"); - smb_pass = get_smbpwnam(machacct); - if(smb_pass) - memcpy(dcauth[cnum].md4pw, smb_pass->smb_nt_passwd, 16); - else - { - /* No such machine account. Should error out here, but we'll - print and carry on */ - DEBUG(1,("No account in domain at REQCHAL for %s\n", machacct)); - } - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",dcauth[cnum].md4pw[i]); - DEBUG(1,("pass %s %s\n", machacct, foo)); - setsesskey(cnum); - q = *rdata + 0x18; - qSIVAL(dcauth[cnum].svrchal[0]); - qSIVAL(dcauth[cnum].svrchal[1]); - -DEBUG(1,("NL: server challenge %08x %08x\n", - dcauth[cnum].svrchal[0],dcauth[cnum].svrchal[1])); - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSAAUTH2: - DEBUG(1,("LSAAUTH2\n")); - dump_data(1,q,128); - q = data + 0x18; - logonsrv = q + 16; - q = skip_unicode_string(logonsrv,1)+12; - q = align4(q, data); - accountname = q; - - q = skip_unicode_string(accountname,1); - secchanneltype = qSVAL; - q += 12; - q = align4(q, data); - unicomp = q; - dump_data(1,unicomp,32); - q = skip_unicode_string(unicomp,1); - rcvcred[0] = qIVAL; - rcvcred[1] = qIVAL; - q = align4(q, data); - negflags = qIVAL; - DEBUG(3,("AUTH2 logonsrv=%s accountname=%s unicomp=%s %lx %lx %lx\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp), - rcvcred[0], rcvcred[1], negflags)); - -DEBUG(1,("NL: recvcred %08x %08x negflags=%08x\n", - rcvcred[0], rcvcred[1], negflags)); - - checkcred(cnum, rcvcred[0], rcvcred[1], 0); - q = *rdata + 0x18; - makecred(cnum, 0, q); - q += 8; - - qSIVAL(negflags); - /* update stored client credentials */ - dcauth[cnum].cred[0] = dcauth[cnum].svrcred[0] = rcvcred[0]; - dcauth[cnum].cred[1] = dcauth[cnum].svrcred[1] = rcvcred[1]; - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSASVRPWSET: - DEBUG(1,("LSASVRPWSET\n")); - q = data + 0x18; - dump_data(1,q,128); - logonsrv = q + 16; - q = skip_unicode_string(logonsrv,1)+12; - q = align4(q, data); - accountname = q; - q = skip_unicode_string(accountname,1); - secchanneltype = qSVAL; - q += 12; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1); - rcvcred[0] = qIVAL; - rcvcred[1] = qIVAL; - clnttime = qIVAL; - - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp))); - - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); - newpass = q; - - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); - - /* PAXX: For the moment we'll reject these */ - /* TODO Need to set newpass in smbpasswd file for accountname */ - q = *rdata + 0x18; - makecred(cnum, clnttime+1, q); - q += 8; - qSIVAL(0); /* timestamp. Seems to be ignored */ - - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; - - endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); - break; - - case LSASAMLOGON: - DEBUG(1,("LSASAMLOGON\n")); - dump_data(1,data,128); - q = data + 0x18; - logonsrv = q + 16; - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = skip_unicode_string(logonsrv,1)+16; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1)+4; - DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n", - __LINE__, unistr(logonsrv), unistr(unicomp))); - q = align4(q, data); - rcvcred[0] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[1] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - clnttime = qIVAL; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - q += 2; - rtncred[0] = qIVAL; /* all these are ignored */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - rtncred[1] = qIVAL; - rtntime = qIVAL; - logonlevel = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - switchval = qSVAL; - switch (switchval) - { - case 1: - - q += 6; - domlen = qSVAL; - dommaxlen = qSVAL; q += 4; - paramcontrol = qIVAL; - logonid[0] = qIVAL; /* low part */ - logonid[1] = qIVAL; /* high part */ - - usernamelen = qSVAL; - - DEBUG(1,("SMLOG %d\n", __LINE__)); - usernamemaxlen = qSVAL; q += 4; - - DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n", - usernamelen, usernamemaxlen, dommaxlen)); - - dump_data(1,q,128); - - wslen = qSVAL; - wsmaxlen = qSVAL; q += 4; - rc4lmowfpass = q; q += 16; - rc4ntowfpass = q; q += 16; - - q += 12; domain = q; q += dommaxlen + 12; - q = align4(q, data); - username = q; q += usernamemaxlen + 12; - q = align4(q, data); - ws = q; - DEBUG(1,("domain=%s username=%s ws=%s\n", - unistr(domain), unistr(username), - unistr(ws))); - break; - default: - DEBUG(0,("unknown switch in SAMLOGON %d\n", - switchval)); - } - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]); - DEBUG(1,("userNAME %s [%s]\n", foo, username)); - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = *rdata + 0x18; - qSIVAL(0x16a4b4); /* magic buffer pointer ? */ - makecred(cnum, clnttime+1, q); - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; - q += 8; - qSIVAL(0); /* timestamp. client doesn't care */ - qSSVAL(3); /* switch value 3. May be others? */ - qSSVAL(0); /* undocumented */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - - memset(rc4key, 0, sizeof rc4key); - SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]); - SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]); - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]); - DEBUG(1,("rc4ntowf %s\n", foo)); - arcfour_init(&c, rc4key, sizeof rc4key); - arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass); - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]); - DEBUG(1,("ntowf %s\n", foo)); - - if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) { - qSIVAL(0); /* no buffer */ - qSCVAL(1); /* Authoratitive. Change if passthrough? */ - qSCVAL(0); /* pad for above boolean */ - qSSVAL(0); /* pad for above boolean */ - - endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len); - break; - } - - qSIVAL(2); /* another magic bufptr? */ - DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo)); - qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]); - qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]); - DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1])); - qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]); - qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]); - qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]); - qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]); - DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename)); - qunihdr(userinfo->effectivename); - qunihdr(userinfo->fullname); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunihdr(userinfo->logonscript); - qunihdr(userinfo->profilepath); - qunihdr(userinfo->homedirectory); - qunihdr(userinfo->homedirectorydrive); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSSVAL(userinfo->logoncount); - qSSVAL(userinfo->badpwcount); - qSIVAL(userinfo->uid); - qSIVAL(userinfo->gid); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->ngroups); - qSIVAL(8); /* ptr to groups */ - qSIVAL(userinfo->userflags); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */ - qunihdr(userinfo->logonserver); - qunihdr(userinfo->logondomain); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(2); /* logon domain id ptr */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - memset(q,0,40); q += 40; /* expansion room */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->nsids); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(0); /* ptr to sids and values */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->effectivename); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->fullname); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->logonscript); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->profilepath); - qunistr(userinfo->homedirectory); - qunistr(userinfo->homedirectorydrive); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->ngroups); - for (i = 0; i < userinfo->ngroups; i++) - { - qSIVAL(userinfo->groups[i].gid); - qSIVAL(userinfo->groups[i].attr); - } - qunistr(userinfo->logonserver); - qunistr(userinfo->logondomain); - for (i = 0; i < userinfo->nsids; i++) - { - /* put the extra sids: PAXX: TODO */ - } - /* Assumption. This is the only domain, sending our SID */ - /* PAXX: may want to do passthrough later */ - strcpy(domsid,lp_domainsid()); - DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); - /* assume, but should check, that domsid starts "S-" */ - p = strtok(domsid+2,"-"); - revision = atoi(p); - DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); - identauth = atoi(strtok(0,"-")); - DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - qSCVAL(1); /* Authoratitive. Change if passthrough? */ - qSCVAL(0); /* pad for above boolean */ - qSSVAL(0); /* pad for above boolean */ - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSASAMLOGOFF: - DEBUG(1,("LSASAMLOGOFF\n")); - q = data + 0x18; - logonsrv = q + 16; - DEBUG(1,("SAMLOGOFF %d\n", __LINE__)); - unicomp = skip_unicode_string(logonsrv,1)+16; - if (strlen(unistr(logonsrv)) % 2 == 0) - q += 2; - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = skip_unicode_string(unicomp,1)+4; - if (strlen(unistr(unicomp)) % 2 == 0) - q += 2; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[0] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[1] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - clnttime = qIVAL; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - q += 4; - rtncred[0] = qIVAL; /* all these are ignored */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - rtncred[1] = qIVAL; - rtntime = qIVAL; - logonlevel = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - switchval = qSVAL; - switch (switchval) - { - case 1: - q += 4; - domlen = qSVAL; - dommaxlen = qSVAL; q += 4; - paramcontrol = qIVAL; - logonid[0] = qIVAL; /* low part */ - logonid[1] = qIVAL; /* high part */ - usernamelen = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - usernamemaxlen = qSVAL; q += 4; - wslen = qSVAL; - wsmaxlen = qSVAL; q += 4; - rc4lmowfpass = q; q += 16; - rc4ntowfpass = q; q += 16; - q += 12; domain = q; q += dommaxlen + 12; - if ((domlen/2) % 2 != 0) q += 2; - username = q; q += usernamemaxlen + 12; /* PAXX: HACK */ - if ((usernamelen/2) % 2 != 0) q += 2; - ws = q; - break; - default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval)); - } - DEBUG(1,("SAMLOGOFF %s\n", unistr(username))); - default: - DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); - } - return(True); -} - -static void checkcred(int cnum, uint32 cred0, uint32 cred1, uint32 time) -{ - uint32 sum[2]; - char netdata[8]; - char netsesskey[8]; - char calccred[8]; - char icv[8]; - char key2[7]; - - SIVAL(netdata, 0, dcauth[cnum].cred[0]+time); - SIVAL(netdata, 4, dcauth[cnum].cred[1]); - SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); - SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); - E1(netsesskey,netdata,icv); - memset(key2, 0, sizeof key2); - key2[0] = netsesskey[7]; - E1(key2, icv, calccred); - if (IVAL(calccred,0) != cred0 || - IVAL(calccred,4) != cred1) - { - DEBUG(1,("Incorrect client credential received cred %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", - cred0, cred1, time, - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].cred[0], dcauth[cnum].cred[1], - IVAL(calccred,0), IVAL(calccred,4))); - /* PAXX: do something about it! */ - } else - DEBUG(4,("Correct client credential received chal %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", - cred0, cred1, time, - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].cred[0], dcauth[cnum].cred[1], - IVAL(calccred,0), IVAL(calccred,4))); -} - -static void makecred(int cnum, uint32 time, char *calccred) -{ - uint32 sum[2]; - char netdata[8]; - char netsesskey[8]; - char icv[8]; - char key2[7]; - - SIVAL(netdata, 0, dcauth[cnum].svrcred[0]+time); - SIVAL(netdata, 4, dcauth[cnum].svrcred[1]); - SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); - SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); - E1(netsesskey,netdata,icv); - memset(key2, 0, sizeof key2); - key2[0] = netsesskey[7]; - E1(key2, icv, calccred); - DEBUG(4,("Server credential: chal %lx %lx sk %lx %lx cred %lx %lx calc %lx %lx\n", - dcauth[cnum].svrchal[0], dcauth[cnum].svrchal[1], - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].svrcred[0], dcauth[cnum].svrcred[1], - IVAL(calccred, 0), IVAL(calccred, 4))); -} - -static void setsesskey(int cnum) -{ - uint32 sum[2]; - char netsum[8]; - char netsesskey[8]; - char icv[8]; - - sum[0] = dcauth[cnum].chal[0] + dcauth[cnum].svrchal[0]; - sum[1] = dcauth[cnum].chal[1] + dcauth[cnum].svrchal[1]; - SIVAL(netsum,0,sum[0]); - SIVAL(netsum,4,sum[1]); - E1(dcauth[cnum].md4pw,netsum,icv); - E1(dcauth[cnum].md4pw+9,icv,netsesskey); - dcauth[cnum].sesskey[0] = IVAL(netsesskey,0); - dcauth[cnum].sesskey[1] = IVAL(netsesskey,4); - -DEBUG(1,("NL: session key %08x %08x\n", - dcauth[cnum].sesskey[0], - dcauth[cnum].sesskey[1])); -} - -static struct uinfo *getuserinfo(char *user, int len, char *ntowfpass) -{ - static struct uinfo u; - static pstring fullnm; - static pstring ascuser; - extern pstring myname; - static pstring stme; - static pstring stdom; - struct smb_passwd *smb_pass; - - strcpy(ascuser,unistr(user)); - ascuser[len/2] = 0; /* PAXX: FIXMEFIXMEFIXME */ - DEBUG(1,("GETUSER username :%s: len=%d\n",ascuser, len)); - - smb_pass = get_smbpwnam(ascuser); - if(!smb_pass) - return 0; - DEBUG(1,("GETU %d\n", __LINE__)); - if (memcmp(ntowfpass, smb_pass->smb_nt_passwd, 16)) { - DEBUG(1,("pass mismatch:\n")); - dump_data(1,ntowfpass,16); - dump_data(1,smb_pass->smb_nt_passwd,16); - return 0; - } - - DEBUG(1,("GETU %d\n", __LINE__)); - u.logontime[0] = 0xffffffff; u.logontime[1] = 0x7fffffff; - u.logofftime[0] = 0xffffffff; u.logofftime[1] = 0x7fffffff; - u.kickofftime[0] = 0xffffffff; u.kickofftime[1] = 0x7fffffff; - DEBUG(1,("GETU %d\n", __LINE__)); - u.passlastsettime[0] = 0xffffffff; u.passlastsettime[1] = 0x7fffffff; - u.passcanchgtime[0] = 0xffffffff; u.passcanchgtime[1] = 0x7fffffff; - u.passmustchgtime[0] = 0xffffffff; u.passmustchgtime[1] = 0x7fffffff; - DEBUG(1,("GETU %d\n", __LINE__)); - u.effectivename = ascuser; - strcpy(fullnm, "Full name of "); - strcat(fullnm, ascuser); - DEBUG(1,("GETU %d\n", __LINE__)); - u.fullname = fullnm; - u.logonscript = "foologin.cmd"; - u.profilepath = "prof"; - u.homedirectory = "foohomes"; - DEBUG(1,("GETU %d\n", __LINE__)); - u.homedirectorydrive = "a:"; - u.logoncount = 7; - u.badpwcount = 8; - u.uid = 778; - DEBUG(1,("GETU %d\n", __LINE__)); - u.gid = 998; - u.ngroups = 2; - u.groups = (struct groupinfo *)(malloc(sizeof (struct groupinfo) * 2)); - u.groups[0].gid = 776; - DEBUG(1,("GETU %d\n", __LINE__)); - u.groups[0].attr = 0x7; - u.groups[1].gid = 776; - u.groups[1].attr = 0x7; - u.userflags = 0x20; - u.logonserver = stme; - get_myname(myname,NULL); - strcpy(stme, myname); - strupper(stme); - DEBUG(1,("LS %s\n", u.logonserver)); - u.logondomain = stdom; - strcpy(stdom, lp_workgroup()); - strupper(stdom); - DEBUG(1,("DOM %s\n", u.logondomain)); - u.nsids = 0; - u.sids = 0; - DEBUG(1,("GETU %d\n", __LINE__)); - return &u; -}; - - #endif /* NTDOMAIN */ -/* space in front of this function so that make proto doesn't pick it up */ - void _dummy_function(void) -{ - UTIME t; - lsa_reply_req_chal(NULL, NULL, NULL, NULL); - lsa_reply_auth_2(NULL, NULL, NULL, NULL, 0); - lsa_reply_srv_pwset(NULL, NULL, NULL, NULL, t, 0); - make_lsa_user_info(NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - 0, 0, - 0, 0, 0, NULL, 0, - NULL, - NULL, NULL, - NULL, NULL); - lsa_reply_sam_logon(NULL,NULL,NULL,NULL,t, NULL); - lsa_reply_sam_logoff(NULL,NULL,NULL,NULL,t,0); -} -- cgit From c5e739febe5ab3bcc5d147fe791c788ec72531a3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 10 Oct 1997 14:48:05 +0000 Subject: Makefile: added credentials.c to smbd credentials.c: using credential structures instead of char* password.c uid.c server.c: added sid and attr to user_struct. smbdes.c: smbhash and str_to_key make public instead of private. pipes.c smb.h: lsa structures, sub-functions. proto.h: usual. (This used to be commit 87a0a944855a673d693d934e446bdc231b1c7f02) --- source3/smbd/pipes.c | 1063 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1047 insertions(+), 16 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 6937412e29..5a6da643d9 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -492,13 +492,13 @@ static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) hdr->reserved = 0; /* reserved */ } -static void make_rpc_reply(char *inbuf, char *q, int data_len) +static int make_rpc_reply(char *inbuf, char *q, int data_len) { uint32 callid = RIVAL(inbuf, 12); RPC_HDR hdr; create_rpc_reply(&hdr, callid, data_len); - smb_io_rpc_hdr(False, &hdr, q, q, 4); + return smb_io_rpc_hdr(False, &hdr, q, q, 4) - q; } static int lsa_reply_open_policy(char *q, char *base) @@ -723,30 +723,22 @@ static int lsa_reply_lookup_rids(char *q, char *base, return q - start; } -static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, char chal[8], int status) +static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, + DOM_CHAL *srv_chal, int status) { - memcpy(r_c->srv_chal.data, chal, sizeof(r_c->srv_chal.data)); + memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(r_c->srv_chal.data)); r_c->status = status; } -#if 0 - char chal[8]; - /* PAXX: set these to random values */ - for (int i = 0; i < 8; i+++) - { - chal[i] = 0xA5; - } -#endif - static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, - char chal[8]) + DOM_CHAL *srv_chal) { char *start = q; LSA_R_REQ_CHAL r_c; /* set up the LSA REQUEST CHALLENGE response */ - make_lsa_r_req_chal(&r_c, chal, 0); + make_lsa_r_req_chal(&r_c, srv_chal, 0); /* store the response in the SMB stream */ q = lsa_io_r_req_chal(False, &r_c, q, base, 4); @@ -1083,7 +1075,7 @@ static void api_lsa_lookup_names( char *param, char *data, *rdata_len = reply_len + 0x18; } -BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, +BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1193,4 +1185,1043 @@ BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, return True; } +static void api_lsa_req_chal( user_struct *vuser, + char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + int i; + LSA_Q_REQ_CHAL q_r; + + fstring mach_acct; + struct smb_passwd *smb_pass; + + /* grab the challenge... */ + lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4); + + fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer)); + + DEBUG(1,("logonsrv=%s unicomp=%s\n", + unistr2(q_r.uni_logon_srv .buffer), + mach_acct)); + + strcat(mach_acct, "$"); + + smb_pass = get_smbpwnam(mach_acct); + if (smb_pass != NULL) + { + memcpy(vuser->dc.md4pw, smb_pass->smb_nt_passwd, sizeof(vuser->dc.md4pw)); + } + else + { + /* No such machine account. Should error out here, but we'll + print and carry on */ + DEBUG(1,("No account in domain at REQCHAL for %s\n", mach_acct)); + } + + { + char foo[16]; + for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", vuser->dc.md4pw[i]); + DEBUG(1,("pass %s %s\n", mach_acct, foo)); + } + + /* from client / server challenges and md4 password, generate sess key */ + cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal), + vuser->dc.md4pw, vuser->dc.sess_key); + + /* copy the client credentials for later use */ + memcpy(vuser->dc.srv_chal.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data)); + memcpy(vuser->dc.srv_cred.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data)); + + /* create a server challenge for the client */ + /* PAXX: set these to random values. */ + /* lkcl: paul, you mentioned that it doesn't really matter much */ + for (i = 0; i < 8; i++) + { + vuser->dc.srv_chal.data[i] = 0xA5; + } + + /* construct reply. return status is always 0x0 */ + reply_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata + 0x18, + &(vuser->dc.srv_chal)); + + /* construct header, now that we know the reply length */ + reply_len += make_rpc_reply(data, *rdata, reply_len); + + *rdata_len = reply_len; +} + +void no_fn(uint uid) +{ + user_struct *vuser = get_valid_user_struct(uid); + DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); +#if defined(NETGROUP) && defined(AUTOMOUNT) + DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share)); +#endif +} + +#endif /* NTDOMAIN */ + +#ifdef UNDEFINED_NTDOMAIN +/* + PAXX: Someone fix above. + The above API is indexing RPC calls based on RPC flags and + fragment length. I've decided to do it based on operation number :-) +*/ + + BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum; + char *q; + char *domainname; + int domlen; + pstring domsid; + char *p; + int numsubauths; + int subauths[MAXSUBAUTHS]; + struct smb_passwd *smb_pass; /* To check if machine account exists */ + pstring machacct; + pstring foo; + uint16 infoclass; + uint16 revision; /* Domain sid revision */ + int identauth; + int i; + char *logonsrv; + char *unicomp; + char *accountname; + uint16 secchanneltype; + uint32 negflags; + char netcred[8]; + uint32 rcvcred[8]; + char rtncred[8]; + uint32 clnttime; + uint32 rtntime; + char *newpass; + uint16 logonlevel; + uint16 switchval; + uint16 dommaxlen; + uint16 paramcontrol; + uint32 logonid[2]; + uint16 usernamelen; + uint16 usernamemaxlen; + uint16 wslen; + uint16 wsmaxlen; + uchar *rc4lmowfpass; + uchar *rc4ntowfpass; + char *domain; + char *username; + char *ws; + struct uinfo *userinfo; + int pkttype; + uchar rc4key[16]; + uchar ntowfpass[16]; + uint32 nentries; + char *policyhandle; + #define MAXSIDS 64 + uchar *sids[MAXSIDS]; /* for lookup SID */ + int nsids; + #define MAXNAMES 64 + uchar *names[MAXNAMES]; + + opnum = SVAL(data,22); + + pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ + { + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; + } + + DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum)); + initrpcreply(data, *rdata); + DEBUG(4,("netlogon LINE %d\n",__LINE__)); + switch (opnum) + { + case LSAOPENPOLICY: + DEBUG(1,("LSAOPENPOLICY\n")); + char *q = *rdata + 0x18; + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + /* return a 20 byte policy handle */ + /* here's a pretty handle:- */ + qSIVAL(time(NULL)); + qSIVAL(0x810a792f); + qSIVAL(0x11d107d5); + qSIVAL(time(NULL)); + qSIVAL(0x6cbcf800); + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); /* size of data plus return code */ + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + break; + + case LSAQUERYINFOPOLICY: + DEBUG(1,("LSAQUERYINFOPOLICY\n")); + dump_data(1,data,128); + infoclass = SVAL(data, 44); /* also a policy handle but who cares? */ + q = *rdata + 0x18; + qRSIVAL(0x00000022); /* undocumented. Usually a buffer pointer whose + value is ignored */ + qSSVAL(infoclass); + domainname = lp_workgroup(); + domlen = strlen(domainname); + strcpy(domsid,lp_domainsid()); + DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); + /* assume, but should check, that domsid starts "S-" */ + p = strtok(domsid+2,"-"); + revision = atoi(p); + DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); + identauth = atoi(strtok(0,"-")); + DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); + + switch (infoclass) + { + case 5: + case 3: + default: + qSSVAL(0); /* 2 undocumented bytes */ + qSSVAL(domlen*2); + qSSVAL(domlen*2); /* unicode domain len and maxlen */ + qSIVAL(4); /* domain buffer pointer */ + qSIVAL(2); /* domain sid pointer */ + qunistr(domainname); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + } + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSAENUMTRUSTDOM: + DEBUG(1,("LSAENUMTRUSTDOM\n")); + q = *rdata + 0x18; + qSIVAL(0); /* enumeration context */ + qSIVAL(0); /* entries read */ + qSIVAL(0); /* trust information */ + endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len); + break; + + case LSACLOSE: + DEBUG(1,("LSACLOSE\n")); + q = *rdata + 0x18; + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSAOPENSECRET: + DEBUG(1,("LSAOPENSECRET\n")); + q = *rdata + 0x18; + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + qSIVAL(0); + endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len); + break; + + case LSALOOKUPSIDS: + DEBUG(1,("LSAOPENSECRET\n")); + q = data + 0x18; + policyhandle = q; q += 20; + nentries = qIVAL; + DEBUG(4,("lookupsid entries %d\n",nentries)); + q += (2+nentries) * 4; /* skip bufptrs */ + /* now we have nentries sids of the form: + uint32 Subauthority count (SAC) + char Revision + char Subaurity count again + char[6] Identifier authority + [uint32 subauthority] * SAC + */ + for (nsids = 0; nsids < nentries; nsids++) + { + DEBUG(4,("lookupsid q in %lx\n",q)); + sids[nsids] = q; + DEBUG(4,("lookupsid numsubs %d\n",IVAL(q,0))); + q += 4+1+1+6+IVAL(q,0)*4; + DEBUG(4,("lookupsid q %lx\n",q)); + } + /* There's 16 bytes of something after all of that, don't know + what it is though - incorrectly documented */ + + DEBUG(4,("lookupsid line %d\n",__LINE__)); + /* formulate reply */ + q = *rdata + 0x18; + qSIVAL(2); /* bufptr */ + qSIVAL(4); /* number of referenced domains + - need one per each identifier authority in call */ + qSIVAL(2); /* dom bufptr */ + qSIVAL(32); /* max entries */ + qSIVAL(4); /* number of reference domains? */ + + qunihdr(lp_workgroup()); /* reference domain */ + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-1"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-5"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-3"); + qSIVAL(2); /* sid bufptr */ + + qunistr(lp_workgroup()); + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + strcpy(domsid,lp_domainsid()); + p = strtok(domsid+2,"-"); + revision = atoi(p); + identauth = atoi(strtok(0,"-")); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-1"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-5"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + + qunistr("S-1-3"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + + qSIVAL(nentries); + qSIVAL(2); /* bufptr */ + qSIVAL(nentries); + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qSSVAL(5); /* SID name use ?! */ + qSSVAL(0); /* undocumented */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + qunihdr(sidtostring(sids[i])); + DEBUG(4,("lookupsid sidname %s\n",sidtostring(sids[i]))); + qSIVAL(0); /* domain index out of above reference domains */ + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qunistr(sidtostring(sids[i])); + } + qSIVAL(nentries); /* mapped count */ + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSALOOKUPNAMES: + DEBUG(1,("LSALOOKUPNAMES\n")); + q = data + 0x18; + policyhandle = q; q += 20; + nentries = qIVAL; + DEBUG(4,("lookupnames entries %d\n",nentries)); + q += 4; /* skip second count */ + q += 8 * nentries; /* skip pointers */ + for (nnames = 0; nnames < nentries; nnames++) + { + names[nnames] = q; /* set name string to unicode header */ + q += IVAL(q,0)*2; /* guessing here */ + } + /* There's a translated sids structure next but it looks fals */ + + DEBUG(4,("lookupnames line %d\n",__LINE__)); + /* formulate reply */ + q = *rdata + 0x18; + qSIVAL(2); /* bufptr */ + qSIVAL(4); /* number of referenced domains + - need one per each identifier authority in call */ + qSIVAL(2); /* dom bufptr */ + qSIVAL(32); /* max entries */ + qSIVAL(4); /* number of reference domains? */ + + qunihdr(lp_workgroup()); /* reference domain */ + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-1"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-5"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-3"); + qSIVAL(2); /* sid bufptr */ + + qunistr(lp_workgroup()); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + + strcpy(domsid,lp_domainsid()); + p = strtok(domsid+2,"-"); + revision = atoi(p); + identauth = atoi(strtok(0,"-")); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-1"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-5"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + + qunistr("S-1-3"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + + qSIVAL(nentries); + qSIVAL(2); /* bufptr */ + qSIVAL(nentries); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { + qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ + qSSVAL(5); /* undocumented */ + DEBUG(4,("lookupnames line %d\n",__LINE__)); + qSIVAL(nametorid(names[i])); + DEBUG(4,("lookupnames nametorid %d\n",nametorid(names[i]))); + qSIVAL(0); /* domain index out of above reference domains */ + } + qSIVAL(nentries); /* mapped count */ + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + default: + DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum)); + } + return(True); +} + + BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum; + char *q; + char *domainname; + int domlen; + pstring domsid; + char *p; + int numsubauths; + int subauths[MAXSUBAUTHS]; + struct smb_passwd *smb_pass; /* To check if machine account exists */ + pstring machacct; + pstring foo; + uint16 infoclass; + uint16 revision; /* Domain sid revision */ + int identauth; + int i; + char *logonsrv; + char *unicomp; + char *accountname; + uint16 secchanneltype; + uint32 negflags; + char netcred[8]; + uint32 rcvcred[8]; + char rtncred[8]; + uint32 clnttime; + uint32 rtntime; + char *newpass; + uint16 logonlevel; + uint16 switchval; + uint16 dommaxlen; + uint16 paramcontrol; + uint32 logonid[2]; + uint16 usernamelen; + uint16 usernamemaxlen; + uint16 wslen; + uint16 wsmaxlen; + uchar *rc4lmowfpass; + uchar *rc4ntowfpass; + char *domain; + char *username; + char *ws; + struct uinfo *userinfo; + int pkttype; + ArcfourContext c; + uchar rc4key[16]; + uchar ntowfpass[16]; + + opnum = SVAL(data,22); + + pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ + { + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; + } + + DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); + initrpcreply(data, *rdata); + DEBUG(4,("netlogon LINE %d\n",__LINE__)); + switch (opnum) + { + case LSAREQCHAL: + DEBUG(1,("LSAREQCHAL\n")); + q = data + 0x18; + dump_data(1,q,128); + logonsrv = q + 16; /* first 16 bytes, buffer ptr, + unicode lenghts */ + q = skip_unicode_string(logonsrv,1) + 12; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1); + + + DEBUG(1,("logonsrv=%s unicomp=%s\n", + unistr(logonsrv), + unistr(unicomp))); + + dcauth[cnum].chal[0] = IVAL(q, 0); + dcauth[cnum].chal[1] = IVAL(q, 4); + dcauth[cnum].cred[0] = IVAL(q, 0); /* this looks weird (tridge) */ + dcauth[cnum].cred[1] = IVAL(q, 4); + +DEBUG(1,("NL: client challenge %08x %08x\n", dcauth[cnum].chal[0],dcauth[cnum].chal[1])); + + /* PAXX: set these to random values */ + dcauth[cnum].svrchal[0] = 0x11111111; + dcauth[cnum].svrchal[1] = 0x22222222; + dcauth[cnum].svrcred[0] = 0x11111111; + dcauth[cnum].svrcred[1] = 0x22222222; + strcpy(machacct,unistr(unicomp)); + strcat(machacct, "$"); + smb_pass = get_smbpwnam(machacct); + if(smb_pass) + memcpy(dcauth[cnum].md4pw, smb_pass->smb_nt_passwd, 16); + else + { + /* No such machine account. Should error out here, but we'll + print and carry on */ + DEBUG(1,("No account in domain at REQCHAL for %s\n", machacct)); + } + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",dcauth[cnum].md4pw[i]); + DEBUG(1,("pass %s %s\n", machacct, foo)); + setsesskey(cnum); + q = *rdata + 0x18; + qSIVAL(dcauth[cnum].svrchal[0]); + qSIVAL(dcauth[cnum].svrchal[1]); + +DEBUG(1,("NL: server challenge %08x %08x\n", + dcauth[cnum].svrchal[0],dcauth[cnum].svrchal[1])); + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSAAUTH2: + DEBUG(1,("LSAAUTH2\n")); + dump_data(1,q,128); + q = data + 0x18; + logonsrv = q + 16; + q = skip_unicode_string(logonsrv,1)+12; + q = align4(q, data); + accountname = q; + + q = skip_unicode_string(accountname,1); + secchanneltype = qSVAL; + q += 12; + q = align4(q, data); + unicomp = q; + dump_data(1,unicomp,32); + q = skip_unicode_string(unicomp,1); + rcvcred[0] = qIVAL; + rcvcred[1] = qIVAL; + q = align4(q, data); + negflags = qIVAL; + DEBUG(3,("AUTH2 logonsrv=%s accountname=%s unicomp=%s %lx %lx %lx\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp), + rcvcred[0], rcvcred[1], negflags)); + +DEBUG(1,("NL: recvcred %08x %08x negflags=%08x\n", + rcvcred[0], rcvcred[1], negflags)); + + checkcred(cnum, rcvcred[0], rcvcred[1], 0); + q = *rdata + 0x18; + makecred(cnum, 0, q); + q += 8; + + qSIVAL(negflags); + /* update stored client credentials */ + dcauth[cnum].cred[0] = dcauth[cnum].svrcred[0] = rcvcred[0]; + dcauth[cnum].cred[1] = dcauth[cnum].svrcred[1] = rcvcred[1]; + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSASVRPWSET: + DEBUG(1,("LSASVRPWSET\n")); + q = data + 0x18; + dump_data(1,q,128); + logonsrv = q + 16; + q = skip_unicode_string(logonsrv,1)+12; + q = align4(q, data); + accountname = q; + q = skip_unicode_string(accountname,1); + secchanneltype = qSVAL; + q += 12; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1); + rcvcred[0] = qIVAL; + rcvcred[1] = qIVAL; + clnttime = qIVAL; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp))); + + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); + newpass = q; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); + + /* PAXX: For the moment we'll reject these */ + /* TODO Need to set newpass in smbpasswd file for accountname */ + q = *rdata + 0x18; + makecred(cnum, clnttime+1, q); + q += 8; + qSIVAL(0); /* timestamp. Seems to be ignored */ + + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + + endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); + break; + + case LSASAMLOGON: + DEBUG(1,("LSASAMLOGON\n")); + dump_data(1,data,128); + q = data + 0x18; + logonsrv = q + 16; + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = skip_unicode_string(logonsrv,1)+16; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1)+4; + DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n", + __LINE__, unistr(logonsrv), unistr(unicomp))); + q = align4(q, data); + rcvcred[0] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[1] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + clnttime = qIVAL; + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + q += 2; + rtncred[0] = qIVAL; /* all these are ignored */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + rtncred[1] = qIVAL; + rtntime = qIVAL; + logonlevel = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + switchval = qSVAL; + switch (switchval) + { + case 1: + + q += 6; + domlen = qSVAL; + dommaxlen = qSVAL; q += 4; + paramcontrol = qIVAL; + logonid[0] = qIVAL; /* low part */ + logonid[1] = qIVAL; /* high part */ + + usernamelen = qSVAL; + + DEBUG(1,("SMLOG %d\n", __LINE__)); + usernamemaxlen = qSVAL; q += 4; + + DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n", + usernamelen, usernamemaxlen, dommaxlen)); + + dump_data(1,q,128); + + wslen = qSVAL; + wsmaxlen = qSVAL; q += 4; + rc4lmowfpass = q; q += 16; + rc4ntowfpass = q; q += 16; + + q += 12; domain = q; q += dommaxlen + 12; + q = align4(q, data); + username = q; q += usernamemaxlen + 12; + q = align4(q, data); + ws = q; + DEBUG(1,("domain=%s username=%s ws=%s\n", + unistr(domain), unistr(username), + unistr(ws))); + break; + default: + DEBUG(0,("unknown switch in SAMLOGON %d\n", + switchval)); + } + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]); + DEBUG(1,("userNAME %s [%s]\n", foo, username)); + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = *rdata + 0x18; + qSIVAL(0x16a4b4); /* magic buffer pointer ? */ + makecred(cnum, clnttime+1, q); + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + q += 8; + qSIVAL(0); /* timestamp. client doesn't care */ + qSSVAL(3); /* switch value 3. May be others? */ + qSSVAL(0); /* undocumented */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + + memset(rc4key, 0, sizeof rc4key); + SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]); + SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]); + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]); + DEBUG(1,("rc4ntowf %s\n", foo)); + arcfour_init(&c, rc4key, sizeof rc4key); + arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass); + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]); + DEBUG(1,("ntowf %s\n", foo)); + + if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) { + qSIVAL(0); /* no buffer */ + qSCVAL(1); /* Authoratitive. Change if passthrough? */ + qSCVAL(0); /* pad for above boolean */ + qSSVAL(0); /* pad for above boolean */ + + endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len); + break; + } + + qSIVAL(2); /* another magic bufptr? */ + DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo)); + qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]); + qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]); + DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1])); + qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]); + qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]); + qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]); + qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]); + DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename)); + qunihdr(userinfo->effectivename); + qunihdr(userinfo->fullname); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunihdr(userinfo->logonscript); + qunihdr(userinfo->profilepath); + qunihdr(userinfo->homedirectory); + qunihdr(userinfo->homedirectorydrive); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSSVAL(userinfo->logoncount); + qSSVAL(userinfo->badpwcount); + qSIVAL(userinfo->uid); + qSIVAL(userinfo->gid); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->ngroups); + qSIVAL(8); /* ptr to groups */ + qSIVAL(userinfo->userflags); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */ + qunihdr(userinfo->logonserver); + qunihdr(userinfo->logondomain); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(2); /* logon domain id ptr */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + memset(q,0,40); q += 40; /* expansion room */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->nsids); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(0); /* ptr to sids and values */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->effectivename); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->fullname); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->logonscript); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->profilepath); + qunistr(userinfo->homedirectory); + qunistr(userinfo->homedirectorydrive); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->ngroups); + for (i = 0; i < userinfo->ngroups; i++) + { + qSIVAL(userinfo->groups[i].gid); + qSIVAL(userinfo->groups[i].attr); + } + qunistr(userinfo->logonserver); + qunistr(userinfo->logondomain); + for (i = 0; i < userinfo->nsids; i++) + { + /* put the extra sids: PAXX: TODO */ + } + /* Assumption. This is the only domain, sending our SID */ + /* PAXX: may want to do passthrough later */ + strcpy(domsid,lp_domainsid()); + DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); + /* assume, but should check, that domsid starts "S-" */ + p = strtok(domsid+2,"-"); + revision = atoi(p); + DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); + identauth = atoi(strtok(0,"-")); + DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + for (i = 0; i < numsubauths; i++) + { + qSIVAL(subauths[i]); + } + qSCVAL(1); /* Authoratitive. Change if passthrough? */ + qSCVAL(0); /* pad for above boolean */ + qSSVAL(0); /* pad for above boolean */ + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + + case LSASAMLOGOFF: + DEBUG(1,("LSASAMLOGOFF\n")); + q = data + 0x18; + logonsrv = q + 16; + DEBUG(1,("SAMLOGOFF %d\n", __LINE__)); + unicomp = skip_unicode_string(logonsrv,1)+16; + if (strlen(unistr(logonsrv)) % 2 == 0) + q += 2; + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = skip_unicode_string(unicomp,1)+4; + if (strlen(unistr(unicomp)) % 2 == 0) + q += 2; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[0] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[1] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + clnttime = qIVAL; + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + q += 4; + rtncred[0] = qIVAL; /* all these are ignored */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + rtncred[1] = qIVAL; + rtntime = qIVAL; + logonlevel = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + switchval = qSVAL; + switch (switchval) + { + case 1: + q += 4; + domlen = qSVAL; + dommaxlen = qSVAL; q += 4; + paramcontrol = qIVAL; + logonid[0] = qIVAL; /* low part */ + logonid[1] = qIVAL; /* high part */ + usernamelen = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + usernamemaxlen = qSVAL; q += 4; + wslen = qSVAL; + wsmaxlen = qSVAL; q += 4; + rc4lmowfpass = q; q += 16; + rc4ntowfpass = q; q += 16; + q += 12; domain = q; q += dommaxlen + 12; + if ((domlen/2) % 2 != 0) q += 2; + username = q; q += usernamemaxlen + 12; /* PAXX: HACK */ + if ((usernamelen/2) % 2 != 0) q += 2; + ws = q; + break; + default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval)); + } + DEBUG(1,("SAMLOGOFF %s\n", unistr(username))); + default: + DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); + } + return(True); +} + +static void checkcred(int cnum, uint32 cred0, uint32 cred1, uint32 time) +{ + uint32 sum[2]; + char netdata[8]; + char netsesskey[8]; + char calccred[8]; + char icv[8]; + char key2[7]; + + SIVAL(netdata, 0, dcauth[cnum].cred[0]+time); + SIVAL(netdata, 4, dcauth[cnum].cred[1]); + SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); + SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); + E1(netsesskey,netdata,icv); + memset(key2, 0, sizeof key2); + key2[0] = netsesskey[7]; + E1(key2, icv, calccred); + if (IVAL(calccred,0) != cred0 || + IVAL(calccred,4) != cred1) + { + DEBUG(1,("Incorrect client credential received cred %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", + cred0, cred1, time, + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].cred[0], dcauth[cnum].cred[1], + IVAL(calccred,0), IVAL(calccred,4))); + /* PAXX: do something about it! */ + } else + DEBUG(4,("Correct client credential received chal %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", + cred0, cred1, time, + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].cred[0], dcauth[cnum].cred[1], + IVAL(calccred,0), IVAL(calccred,4))); +} + +static void makecred(int cnum, uint32 time, char *calccred) +{ + uint32 sum[2]; + char netdata[8]; + char netsesskey[8]; + char icv[8]; + char key2[7]; + + SIVAL(netdata, 0, dcauth[cnum].svrcred[0]+time); + SIVAL(netdata, 4, dcauth[cnum].svrcred[1]); + SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); + SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); + E1(netsesskey,netdata,icv); + memset(key2, 0, sizeof key2); + key2[0] = netsesskey[7]; + E1(key2, icv, calccred); + DEBUG(4,("Server credential: chal %lx %lx sk %lx %lx cred %lx %lx calc %lx %lx\n", + dcauth[cnum].svrchal[0], dcauth[cnum].svrchal[1], + dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], + dcauth[cnum].svrcred[0], dcauth[cnum].svrcred[1], + IVAL(calccred, 0), IVAL(calccred, 4))); +} + +static void setsesskey(int cnum) +{ + uint32 sum[2]; + char netsum[8]; + char netsesskey[8]; + char icv[8]; + + sum[0] = dcauth[cnum].chal[0] + dcauth[cnum].svrchal[0]; + sum[1] = dcauth[cnum].chal[1] + dcauth[cnum].svrchal[1]; + SIVAL(netsum,0,sum[0]); + SIVAL(netsum,4,sum[1]); + E1(dcauth[cnum].md4pw,netsum,icv); + E1(dcauth[cnum].md4pw+9,icv,netsesskey); + dcauth[cnum].sesskey[0] = IVAL(netsesskey,0); + dcauth[cnum].sesskey[1] = IVAL(netsesskey,4); + +DEBUG(1,("NL: session key %08x %08x\n", + dcauth[cnum].sesskey[0], + dcauth[cnum].sesskey[1])); +} + +static struct uinfo *getuserinfo(char *user, int len, char *ntowfpass) +{ + static struct uinfo u; + static pstring fullnm; + static pstring ascuser; + extern pstring myname; + static pstring stme; + static pstring stdom; + struct smb_passwd *smb_pass; + + strcpy(ascuser,unistr(user)); + ascuser[len/2] = 0; /* PAXX: FIXMEFIXMEFIXME */ + DEBUG(1,("GETUSER username :%s: len=%d\n",ascuser, len)); + + smb_pass = get_smbpwnam(ascuser); + if(!smb_pass) + return 0; + DEBUG(1,("GETU %d\n", __LINE__)); + if (memcmp(ntowfpass, smb_pass->smb_nt_passwd, 16)) { + DEBUG(1,("pass mismatch:\n")); + dump_data(1,ntowfpass,16); + dump_data(1,smb_pass->smb_nt_passwd,16); + return 0; + } + + DEBUG(1,("GETU %d\n", __LINE__)); + u.logontime[0] = 0xffffffff; u.logontime[1] = 0x7fffffff; + u.logofftime[0] = 0xffffffff; u.logofftime[1] = 0x7fffffff; + u.kickofftime[0] = 0xffffffff; u.kickofftime[1] = 0x7fffffff; + DEBUG(1,("GETU %d\n", __LINE__)); + u.passlastsettime[0] = 0xffffffff; u.passlastsettime[1] = 0x7fffffff; + u.passcanchgtime[0] = 0xffffffff; u.passcanchgtime[1] = 0x7fffffff; + u.passmustchgtime[0] = 0xffffffff; u.passmustchgtime[1] = 0x7fffffff; + DEBUG(1,("GETU %d\n", __LINE__)); + u.effectivename = ascuser; + strcpy(fullnm, "Full name of "); + strcat(fullnm, ascuser); + DEBUG(1,("GETU %d\n", __LINE__)); + u.fullname = fullnm; + u.logonscript = "foologin.cmd"; + u.profilepath = "prof"; + u.homedirectory = "foohomes"; + DEBUG(1,("GETU %d\n", __LINE__)); + u.homedirectorydrive = "a:"; + u.logoncount = 7; + u.badpwcount = 8; + u.uid = 778; + DEBUG(1,("GETU %d\n", __LINE__)); + u.gid = 998; + u.ngroups = 2; + u.groups = (struct groupinfo *)(malloc(sizeof (struct groupinfo) * 2)); + u.groups[0].gid = 776; + DEBUG(1,("GETU %d\n", __LINE__)); + u.groups[0].attr = 0x7; + u.groups[1].gid = 776; + u.groups[1].attr = 0x7; + u.userflags = 0x20; + u.logonserver = stme; + get_myname(myname,NULL); + strcpy(stme, myname); + strupper(stme); + DEBUG(1,("LS %s\n", u.logonserver)); + u.logondomain = stdom; + strcpy(stdom, lp_workgroup()); + strupper(stdom); + DEBUG(1,("DOM %s\n", u.logondomain)); + u.nsids = 0; + u.sids = 0; + DEBUG(1,("GETU %d\n", __LINE__)); + return &u; +}; + + #endif /* NTDOMAIN */ -- cgit From b94ddf082d73249e3ad1590ee24a5c9c33a15e94 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 10 Oct 1997 16:40:23 +0000 Subject: ipc.c : #if NTDOMAIN call to api_netlogRPC #endif lsaparse.c : renamed lsa_io_q_auth2 to lsa_io_q_auth_2. pipes.c : added api_lsa_reply_auth_2() and api_netlogRPC. proto.h : the usual. (This used to be commit e2e1979b6215080593728942d414a273505877df) --- source3/smbd/pipes.c | 1366 +++++++++++++++----------------------------------- 1 file changed, 393 insertions(+), 973 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 5a6da643d9..24f15ba7fd 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -753,15 +753,15 @@ static void make_lsa_chal(DOM_CHAL *cred, char resp_cred[8]) } static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, - char resp_cred[8], NEG_FLAGS *flgs, int status) + DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status) { - make_lsa_chal(&(r_a->srv_chal), resp_cred); - memcpy(&(r_a->srv_flgs), flgs, sizeof(r_a->srv_flgs)); + memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); + memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs)); r_a->status = status; } static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, - char resp_cred[8], int status) + DOM_CHAL *resp_cred, int status) { char *start = q; LSA_R_AUTH_2 r_a; @@ -1185,63 +1185,67 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, return True; } -static void api_lsa_req_chal( user_struct *vuser, - char *param, char *data, - char **rdata, int *rdata_len ) +static BOOL update_dcinfo(struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct) { - int reply_len; - + struct smb_passwd *smb_pass = get_smbpwnam(mach_acct); int i; - LSA_Q_REQ_CHAL q_r; - - fstring mach_acct; - struct smb_passwd *smb_pass; - - /* grab the challenge... */ - lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4); - fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer)); - - DEBUG(1,("logonsrv=%s unicomp=%s\n", - unistr2(q_r.uni_logon_srv .buffer), - mach_acct)); - - strcat(mach_acct, "$"); - - smb_pass = get_smbpwnam(mach_acct); if (smb_pass != NULL) { - memcpy(vuser->dc.md4pw, smb_pass->smb_nt_passwd, sizeof(vuser->dc.md4pw)); + memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw)); } else { /* No such machine account. Should error out here, but we'll print and carry on */ - DEBUG(1,("No account in domain at REQCHAL for %s\n", mach_acct)); + DEBUG(1,("No account in domain for %s\n", mach_acct)); + return False; } { char foo[16]; - for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", vuser->dc.md4pw[i]); - DEBUG(1,("pass %s %s\n", mach_acct, foo)); + for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", dc->md4pw[i]); + DEBUG(4,("pass %s %s\n", mach_acct, foo)); } /* from client / server challenges and md4 password, generate sess key */ - cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal), - vuser->dc.md4pw, vuser->dc.sess_key); + cred_session_key(&(dc->clnt_chal), &(dc->srv_chal), + dc->md4pw, dc->sess_key); /* copy the client credentials for later use */ - memcpy(vuser->dc.srv_chal.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data)); - memcpy(vuser->dc.srv_cred.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data)); + memcpy(dc->srv_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); + memcpy(dc->srv_cred.data, clnt_chal->data, sizeof(clnt_chal->data)); /* create a server challenge for the client */ /* PAXX: set these to random values. */ /* lkcl: paul, you mentioned that it doesn't really matter much */ for (i = 0; i < 8; i++) { - vuser->dc.srv_chal.data[i] = 0xA5; + dc->srv_chal.data[i] = 0xA5; } + return True; +} + +static void api_lsa_req_chal( user_struct *vuser, + char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + LSA_Q_REQ_CHAL q_r; + + fstring mach_acct; + + /* grab the challenge... */ + lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4); + + fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer)); + + strcat(mach_acct, "$"); + + update_dcinfo(&(vuser->dc), &(q_r.clnt_chal), mach_acct); + /* construct reply. return status is always 0x0 */ reply_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata + 0x18, &(vuser->dc.srv_chal)); @@ -1252,976 +1256,392 @@ static void api_lsa_req_chal( user_struct *vuser, *rdata_len = reply_len; } -void no_fn(uint uid) +static void api_lsa_auth_2( user_struct *vuser, + char *param, char *data, + char **rdata, int *rdata_len ) { - user_struct *vuser = get_valid_user_struct(uid); - DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); -#if defined(NETGROUP) && defined(AUTOMOUNT) - DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share)); -#endif -} + int reply_len; + LSA_Q_AUTH_2 q_a; -#endif /* NTDOMAIN */ + DOM_CHAL srv_chal; + UTIME srv_time; + + srv_time.time = 0; + + /* grab the challenge... */ + lsa_io_q_auth_2(True, &q_a, data + 0x18, data + 0x18, 4); + + /* check that the client credentials are valid */ + cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key, + &(vuser->dc.srv_cred), srv_time); + + /* create server credentials for inclusion in the reply */ + cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred), srv_time, &srv_chal); + + /* construct reply. return status is always 0x0 */ + reply_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata + 0x18, + &srv_chal, 0x0); + + /* construct header, now that we know the reply length */ + reply_len += make_rpc_reply(data, *rdata, reply_len); + + *rdata_len = reply_len; +} -#ifdef UNDEFINED_NTDOMAIN -/* - PAXX: Someone fix above. - The above API is indexing RPC calls based on RPC flags and - fragment length. I've decided to do it based on operation number :-) -*/ - BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data, +BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - uint16 opnum; - char *q; - char *domainname; - int domlen; - pstring domsid; - char *p; - int numsubauths; - int subauths[MAXSUBAUTHS]; - struct smb_passwd *smb_pass; /* To check if machine account exists */ - pstring machacct; - pstring foo; - uint16 infoclass; - uint16 revision; /* Domain sid revision */ - int identauth; - int i; - char *logonsrv; - char *unicomp; - char *accountname; - uint16 secchanneltype; - uint32 negflags; - char netcred[8]; - uint32 rcvcred[8]; - char rtncred[8]; - uint32 clnttime; - uint32 rtntime; - char *newpass; - uint16 logonlevel; - uint16 switchval; - uint16 dommaxlen; - uint16 paramcontrol; - uint32 logonid[2]; - uint16 usernamelen; - uint16 usernamemaxlen; - uint16 wslen; - uint16 wsmaxlen; - uchar *rc4lmowfpass; - uchar *rc4ntowfpass; - char *domain; - char *username; - char *ws; - struct uinfo *userinfo; - int pkttype; - uchar rc4key[16]; - uchar ntowfpass[16]; - uint32 nentries; - char *policyhandle; - #define MAXSIDS 64 - uchar *sids[MAXSIDS]; /* for lookup SID */ - int nsids; - #define MAXNAMES 64 - uchar *names[MAXNAMES]; - - opnum = SVAL(data,22); - - pkttype = CVAL(data, 2); - if (pkttype == 0x0b) /* RPC BIND */ - { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } + uint16 opnum = SVAL(data,22); + int pkttype = CVAL(data, 2); - DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum)); - initrpcreply(data, *rdata); - DEBUG(4,("netlogon LINE %d\n",__LINE__)); - switch (opnum) - { - case LSAOPENPOLICY: - DEBUG(1,("LSAOPENPOLICY\n")); - char *q = *rdata + 0x18; - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - /* return a 20 byte policy handle */ - /* here's a pretty handle:- */ - qSIVAL(time(NULL)); - qSIVAL(0x810a792f); - qSIVAL(0x11d107d5); - qSIVAL(time(NULL)); - qSIVAL(0x6cbcf800); - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); /* size of data plus return code */ - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - break; - - case LSAQUERYINFOPOLICY: - DEBUG(1,("LSAQUERYINFOPOLICY\n")); - dump_data(1,data,128); - infoclass = SVAL(data, 44); /* also a policy handle but who cares? */ - q = *rdata + 0x18; - qRSIVAL(0x00000022); /* undocumented. Usually a buffer pointer whose - value is ignored */ - qSSVAL(infoclass); - domainname = lp_workgroup(); - domlen = strlen(domainname); - strcpy(domsid,lp_domainsid()); - DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); - /* assume, but should check, that domsid starts "S-" */ - p = strtok(domsid+2,"-"); - revision = atoi(p); - DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); - identauth = atoi(strtok(0,"-")); - DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q)); - - switch (infoclass) - { - case 5: - case 3: - default: - qSSVAL(0); /* 2 undocumented bytes */ - qSSVAL(domlen*2); - qSSVAL(domlen*2); /* unicode domain len and maxlen */ - qSIVAL(4); /* domain buffer pointer */ - qSIVAL(2); /* domain sid pointer */ - qunistr(domainname); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - } - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSAENUMTRUSTDOM: - DEBUG(1,("LSAENUMTRUSTDOM\n")); - q = *rdata + 0x18; - qSIVAL(0); /* enumeration context */ - qSIVAL(0); /* entries read */ - qSIVAL(0); /* trust information */ - endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len); - break; - - case LSACLOSE: - DEBUG(1,("LSACLOSE\n")); - q = *rdata + 0x18; - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; + user_struct *vuser = get_valid_user_struct(uid); - case LSAOPENSECRET: - DEBUG(1,("LSAOPENSECRET\n")); - q = *rdata + 0x18; - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - qSIVAL(0); - endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len); - break; + if (pkttype == 0x0b) /* RPC BIND */ + { + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; + } - case LSALOOKUPSIDS: - DEBUG(1,("LSAOPENSECRET\n")); - q = data + 0x18; - policyhandle = q; q += 20; - nentries = qIVAL; - DEBUG(4,("lookupsid entries %d\n",nentries)); - q += (2+nentries) * 4; /* skip bufptrs */ - /* now we have nentries sids of the form: - uint32 Subauthority count (SAC) - char Revision - char Subaurity count again - char[6] Identifier authority - [uint32 subauthority] * SAC - */ - for (nsids = 0; nsids < nentries; nsids++) - { - DEBUG(4,("lookupsid q in %lx\n",q)); - sids[nsids] = q; - DEBUG(4,("lookupsid numsubs %d\n",IVAL(q,0))); - q += 4+1+1+6+IVAL(q,0)*4; - DEBUG(4,("lookupsid q %lx\n",q)); - } - /* There's 16 bytes of something after all of that, don't know - what it is though - incorrectly documented */ - - DEBUG(4,("lookupsid line %d\n",__LINE__)); - /* formulate reply */ - q = *rdata + 0x18; - qSIVAL(2); /* bufptr */ - qSIVAL(4); /* number of referenced domains - - need one per each identifier authority in call */ - qSIVAL(2); /* dom bufptr */ - qSIVAL(32); /* max entries */ - qSIVAL(4); /* number of reference domains? */ - - qunihdr(lp_workgroup()); /* reference domain */ - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-1"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-5"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-3"); - qSIVAL(2); /* sid bufptr */ - - qunistr(lp_workgroup()); - DEBUG(4,("lookupsid line %d\n",__LINE__)); - - strcpy(domsid,lp_domainsid()); - p = strtok(domsid+2,"-"); - revision = atoi(p); - identauth = atoi(strtok(0,"-")); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); + DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); - qunistr("S-1-1"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); + if (vuser == NULL) return False; - qunistr("S-1-5"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); +#if defined(NETGROUP) && defined(AUTOMOUNT) + DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share)); +#endif - qunistr("S-1-3"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + switch (opnum) + { + case LSA_REQCHAL: + { + DEBUG(3,("LSA_REQCHAL\n")); + api_lsa_req_chal(vuser, param, data, rdata, rdata_len); + break; + } - qSIVAL(nentries); - qSIVAL(2); /* bufptr */ - qSIVAL(nentries); - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qSSVAL(5); /* SID name use ?! */ - qSSVAL(0); /* undocumented */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - qunihdr(sidtostring(sids[i])); - DEBUG(4,("lookupsid sidname %s\n",sidtostring(sids[i]))); - qSIVAL(0); /* domain index out of above reference domains */ - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qunistr(sidtostring(sids[i])); - } - qSIVAL(nentries); /* mapped count */ - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; + case LSA_AUTH2: + { + DEBUG(3,("LSA_AUTH2\n")); + api_lsa_auth_2(vuser, param, data, rdata, rdata_len); + break; + } - case LSALOOKUPNAMES: - DEBUG(1,("LSALOOKUPNAMES\n")); - q = data + 0x18; - policyhandle = q; q += 20; - nentries = qIVAL; - DEBUG(4,("lookupnames entries %d\n",nentries)); - q += 4; /* skip second count */ - q += 8 * nentries; /* skip pointers */ - for (nnames = 0; nnames < nentries; nnames++) - { - names[nnames] = q; /* set name string to unicode header */ - q += IVAL(q,0)*2; /* guessing here */ - } - /* There's a translated sids structure next but it looks fals */ - - DEBUG(4,("lookupnames line %d\n",__LINE__)); - /* formulate reply */ - q = *rdata + 0x18; - qSIVAL(2); /* bufptr */ - qSIVAL(4); /* number of referenced domains - - need one per each identifier authority in call */ - qSIVAL(2); /* dom bufptr */ - qSIVAL(32); /* max entries */ - qSIVAL(4); /* number of reference domains? */ - - qunihdr(lp_workgroup()); /* reference domain */ - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-1"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-5"); - qSIVAL(2); /* sid bufptr */ - - qunihdr("S-1-3"); - qSIVAL(2); /* sid bufptr */ - - qunistr(lp_workgroup()); - DEBUG(4,("lookupnames line %d\n",__LINE__)); - - strcpy(domsid,lp_domainsid()); - p = strtok(domsid+2,"-"); - revision = atoi(p); - identauth = atoi(strtok(0,"-")); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - DEBUG(4,("lookupsid line %d\n",__LINE__)); + default: + { + DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); + break; + } + } - qunistr("S-1-1"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ - DEBUG(4,("lookupsid line %d\n",__LINE__)); + return True; +} - qunistr("S-1-5"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ - qunistr("S-1-3"); - qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ +#if 0 - qSIVAL(nentries); - qSIVAL(2); /* bufptr */ - qSIVAL(nentries); - DEBUG(4,("lookupnames line %d\n",__LINE__)); - for (i = 0; i < nentries; i++) - { - qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ - qSSVAL(5); /* undocumented */ - DEBUG(4,("lookupnames line %d\n",__LINE__)); - qSIVAL(nametorid(names[i])); - DEBUG(4,("lookupnames nametorid %d\n",nametorid(names[i]))); - qSIVAL(0); /* domain index out of above reference domains */ - } - qSIVAL(nentries); /* mapped count */ - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; +case LSASVRPWSET: + DEBUG(1,("LSASVRPWSET\n")); + q = data + 0x18; + dump_data(1,q,128); + logonsrv = q + 16; + q = skip_unicode_string(logonsrv,1)+12; + q = align4(q, data); + accountname = q; + q = skip_unicode_string(accountname,1); + secchanneltype = qSVAL; + q += 12; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1); + rcvcred[0] = qIVAL; + rcvcred[1] = qIVAL; + clnttime = qIVAL; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp))); + + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); + newpass = q; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); + + /* PAXX: For the moment we'll reject these */ + /* TODO Need to set newpass in smbpasswd file for accountname */ + q = *rdata + 0x18; + makecred(cnum, clnttime+1, q); + q += 8; + qSIVAL(0); /* timestamp. Seems to be ignored */ + + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + + endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); + break; + +case LSASAMLOGON: + DEBUG(1,("LSASAMLOGON\n")); + dump_data(1,data,128); + q = data + 0x18; + logonsrv = q + 16; + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = skip_unicode_string(logonsrv,1)+16; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1)+4; + DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n", + __LINE__, unistr(logonsrv), unistr(unicomp))); + q = align4(q, data); + rcvcred[0] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[1] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + clnttime = qIVAL; + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + q += 2; + rtncred[0] = qIVAL; /* all these are ignored */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + rtncred[1] = qIVAL; + rtntime = qIVAL; + logonlevel = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + switchval = qSVAL; + switch (switchval) + { + case 1: + + q += 6; + domlen = qSVAL; + dommaxlen = qSVAL; q += 4; + paramcontrol = qIVAL; + logonid[0] = qIVAL; /* low part */ + logonid[1] = qIVAL; /* high part */ + + usernamelen = qSVAL; + + DEBUG(1,("SMLOG %d\n", __LINE__)); + usernamemaxlen = qSVAL; q += 4; + + DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n", + usernamelen, usernamemaxlen, dommaxlen)); + + dump_data(1,q,128); + + wslen = qSVAL; + wsmaxlen = qSVAL; q += 4; + rc4lmowfpass = q; q += 16; + rc4ntowfpass = q; q += 16; + + q += 12; domain = q; q += dommaxlen + 12; + q = align4(q, data); + username = q; q += usernamemaxlen + 12; + q = align4(q, data); + ws = q; + DEBUG(1,("domain=%s username=%s ws=%s\n", + unistr(domain), unistr(username), + unistr(ws))); + break; + default: + DEBUG(0,("unknown switch in SAMLOGON %d\n", + switchval)); + } + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]); + DEBUG(1,("userNAME %s [%s]\n", foo, username)); + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = *rdata + 0x18; + qSIVAL(0x16a4b4); /* magic buffer pointer ? */ + makecred(cnum, clnttime+1, q); + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + q += 8; + qSIVAL(0); /* timestamp. client doesn't care */ + qSSVAL(3); /* switch value 3. May be others? */ + qSSVAL(0); /* undocumented */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + + memset(rc4key, 0, sizeof rc4key); + SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]); + SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]); + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]); + DEBUG(1,("rc4ntowf %s\n", foo)); + arcfour_init(&c, rc4key, sizeof rc4key); + arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass); + for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]); + DEBUG(1,("ntowf %s\n", foo)); + + if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) { + qSIVAL(0); /* no buffer */ + qSCVAL(1); /* Authoratitive. Change if passthrough? */ + qSCVAL(0); /* pad for above boolean */ + qSSVAL(0); /* pad for above boolean */ + + endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len); + break; + } - default: - DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum)); + qSIVAL(2); /* another magic bufptr? */ + DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo)); + qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]); + qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]); + DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1])); + qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]); + qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]); + qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]); + qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]); + DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename)); + qunihdr(userinfo->effectivename); + qunihdr(userinfo->fullname); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunihdr(userinfo->logonscript); + qunihdr(userinfo->profilepath); + qunihdr(userinfo->homedirectory); + qunihdr(userinfo->homedirectorydrive); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSSVAL(userinfo->logoncount); + qSSVAL(userinfo->badpwcount); + qSIVAL(userinfo->uid); + qSIVAL(userinfo->gid); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->ngroups); + qSIVAL(8); /* ptr to groups */ + qSIVAL(userinfo->userflags); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */ + qunihdr(userinfo->logonserver); + qunihdr(userinfo->logondomain); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(2); /* logon domain id ptr */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + memset(q,0,40); q += 40; /* expansion room */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->nsids); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(0); /* ptr to sids and values */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->effectivename); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->fullname); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->logonscript); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qunistr(userinfo->profilepath); + qunistr(userinfo->homedirectory); + qunistr(userinfo->homedirectorydrive); + DEBUG(1,("SMLOG %d\n", __LINE__)); + qSIVAL(userinfo->ngroups); + for (i = 0; i < userinfo->ngroups; i++) + { + qSIVAL(userinfo->groups[i].gid); + qSIVAL(userinfo->groups[i].attr); } - return(True); -} - - BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - uint16 opnum; - char *q; - char *domainname; - int domlen; - pstring domsid; - char *p; - int numsubauths; - int subauths[MAXSUBAUTHS]; - struct smb_passwd *smb_pass; /* To check if machine account exists */ - pstring machacct; - pstring foo; - uint16 infoclass; - uint16 revision; /* Domain sid revision */ - int identauth; - int i; - char *logonsrv; - char *unicomp; - char *accountname; - uint16 secchanneltype; - uint32 negflags; - char netcred[8]; - uint32 rcvcred[8]; - char rtncred[8]; - uint32 clnttime; - uint32 rtntime; - char *newpass; - uint16 logonlevel; - uint16 switchval; - uint16 dommaxlen; - uint16 paramcontrol; - uint32 logonid[2]; - uint16 usernamelen; - uint16 usernamemaxlen; - uint16 wslen; - uint16 wsmaxlen; - uchar *rc4lmowfpass; - uchar *rc4ntowfpass; - char *domain; - char *username; - char *ws; - struct uinfo *userinfo; - int pkttype; - ArcfourContext c; - uchar rc4key[16]; - uchar ntowfpass[16]; - - opnum = SVAL(data,22); - - pkttype = CVAL(data, 2); - if (pkttype == 0x0b) /* RPC BIND */ + qunistr(userinfo->logonserver); + qunistr(userinfo->logondomain); + for (i = 0; i < userinfo->nsids; i++) { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; + /* put the extra sids: PAXX: TODO */ } - - DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); - initrpcreply(data, *rdata); - DEBUG(4,("netlogon LINE %d\n",__LINE__)); - switch (opnum) + /* Assumption. This is the only domain, sending our SID */ + /* PAXX: may want to do passthrough later */ + strcpy(domsid,lp_domainsid()); +DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); + /* assume, but should check, that domsid starts "S-" */ + p = strtok(domsid+2,"-"); + revision = atoi(p); +DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); + identauth = atoi(strtok(0,"-")); +DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + for (i = 0; i < numsubauths; i++) { - case LSAREQCHAL: - DEBUG(1,("LSAREQCHAL\n")); - q = data + 0x18; - dump_data(1,q,128); - logonsrv = q + 16; /* first 16 bytes, buffer ptr, + unicode lenghts */ - q = skip_unicode_string(logonsrv,1) + 12; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1); - - - DEBUG(1,("logonsrv=%s unicomp=%s\n", - unistr(logonsrv), - unistr(unicomp))); - - dcauth[cnum].chal[0] = IVAL(q, 0); - dcauth[cnum].chal[1] = IVAL(q, 4); - dcauth[cnum].cred[0] = IVAL(q, 0); /* this looks weird (tridge) */ - dcauth[cnum].cred[1] = IVAL(q, 4); - -DEBUG(1,("NL: client challenge %08x %08x\n", dcauth[cnum].chal[0],dcauth[cnum].chal[1])); - - /* PAXX: set these to random values */ - dcauth[cnum].svrchal[0] = 0x11111111; - dcauth[cnum].svrchal[1] = 0x22222222; - dcauth[cnum].svrcred[0] = 0x11111111; - dcauth[cnum].svrcred[1] = 0x22222222; - strcpy(machacct,unistr(unicomp)); - strcat(machacct, "$"); - smb_pass = get_smbpwnam(machacct); - if(smb_pass) - memcpy(dcauth[cnum].md4pw, smb_pass->smb_nt_passwd, 16); - else - { - /* No such machine account. Should error out here, but we'll - print and carry on */ - DEBUG(1,("No account in domain at REQCHAL for %s\n", machacct)); - } - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",dcauth[cnum].md4pw[i]); - DEBUG(1,("pass %s %s\n", machacct, foo)); - setsesskey(cnum); - q = *rdata + 0x18; - qSIVAL(dcauth[cnum].svrchal[0]); - qSIVAL(dcauth[cnum].svrchal[1]); - -DEBUG(1,("NL: server challenge %08x %08x\n", - dcauth[cnum].svrchal[0],dcauth[cnum].svrchal[1])); - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSAAUTH2: - DEBUG(1,("LSAAUTH2\n")); - dump_data(1,q,128); - q = data + 0x18; - logonsrv = q + 16; - q = skip_unicode_string(logonsrv,1)+12; - q = align4(q, data); - accountname = q; - - q = skip_unicode_string(accountname,1); - secchanneltype = qSVAL; - q += 12; - q = align4(q, data); - unicomp = q; - dump_data(1,unicomp,32); - q = skip_unicode_string(unicomp,1); - rcvcred[0] = qIVAL; - rcvcred[1] = qIVAL; - q = align4(q, data); - negflags = qIVAL; - DEBUG(3,("AUTH2 logonsrv=%s accountname=%s unicomp=%s %lx %lx %lx\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp), - rcvcred[0], rcvcred[1], negflags)); - -DEBUG(1,("NL: recvcred %08x %08x negflags=%08x\n", - rcvcred[0], rcvcred[1], negflags)); - - checkcred(cnum, rcvcred[0], rcvcred[1], 0); - q = *rdata + 0x18; - makecred(cnum, 0, q); - q += 8; - - qSIVAL(negflags); - /* update stored client credentials */ - dcauth[cnum].cred[0] = dcauth[cnum].svrcred[0] = rcvcred[0]; - dcauth[cnum].cred[1] = dcauth[cnum].svrcred[1] = rcvcred[1]; - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSASVRPWSET: - DEBUG(1,("LSASVRPWSET\n")); - q = data + 0x18; - dump_data(1,q,128); - logonsrv = q + 16; - q = skip_unicode_string(logonsrv,1)+12; - q = align4(q, data); - accountname = q; - q = skip_unicode_string(accountname,1); - secchanneltype = qSVAL; - q += 12; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1); - rcvcred[0] = qIVAL; - rcvcred[1] = qIVAL; - clnttime = qIVAL; - - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp))); - - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); - newpass = q; - - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); - - /* PAXX: For the moment we'll reject these */ - /* TODO Need to set newpass in smbpasswd file for accountname */ - q = *rdata + 0x18; - makecred(cnum, clnttime+1, q); - q += 8; - qSIVAL(0); /* timestamp. Seems to be ignored */ - - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; - - endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); - break; - - case LSASAMLOGON: - DEBUG(1,("LSASAMLOGON\n")); - dump_data(1,data,128); - q = data + 0x18; - logonsrv = q + 16; - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = skip_unicode_string(logonsrv,1)+16; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1)+4; - DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n", - __LINE__, unistr(logonsrv), unistr(unicomp))); - q = align4(q, data); - rcvcred[0] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[1] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - clnttime = qIVAL; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - q += 2; - rtncred[0] = qIVAL; /* all these are ignored */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - rtncred[1] = qIVAL; - rtntime = qIVAL; - logonlevel = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - switchval = qSVAL; - switch (switchval) - { - case 1: - - q += 6; - domlen = qSVAL; - dommaxlen = qSVAL; q += 4; - paramcontrol = qIVAL; - logonid[0] = qIVAL; /* low part */ - logonid[1] = qIVAL; /* high part */ - - usernamelen = qSVAL; - - DEBUG(1,("SMLOG %d\n", __LINE__)); - usernamemaxlen = qSVAL; q += 4; - - DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n", - usernamelen, usernamemaxlen, dommaxlen)); - - dump_data(1,q,128); - - wslen = qSVAL; - wsmaxlen = qSVAL; q += 4; - rc4lmowfpass = q; q += 16; - rc4ntowfpass = q; q += 16; - - q += 12; domain = q; q += dommaxlen + 12; - q = align4(q, data); - username = q; q += usernamemaxlen + 12; - q = align4(q, data); - ws = q; - DEBUG(1,("domain=%s username=%s ws=%s\n", - unistr(domain), unistr(username), - unistr(ws))); - break; - default: - DEBUG(0,("unknown switch in SAMLOGON %d\n", - switchval)); - } - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]); - DEBUG(1,("userNAME %s [%s]\n", foo, username)); - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = *rdata + 0x18; - qSIVAL(0x16a4b4); /* magic buffer pointer ? */ - makecred(cnum, clnttime+1, q); - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; - q += 8; - qSIVAL(0); /* timestamp. client doesn't care */ - qSSVAL(3); /* switch value 3. May be others? */ - qSSVAL(0); /* undocumented */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - - memset(rc4key, 0, sizeof rc4key); - SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]); - SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]); - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]); - DEBUG(1,("rc4ntowf %s\n", foo)); - arcfour_init(&c, rc4key, sizeof rc4key); - arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass); - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]); - DEBUG(1,("ntowf %s\n", foo)); - - if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) { - qSIVAL(0); /* no buffer */ - qSCVAL(1); /* Authoratitive. Change if passthrough? */ - qSCVAL(0); /* pad for above boolean */ - qSSVAL(0); /* pad for above boolean */ - - endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len); - break; - } - - qSIVAL(2); /* another magic bufptr? */ - DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo)); - qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]); - qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]); - DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1])); - qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]); - qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]); - qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]); - qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]); - DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename)); - qunihdr(userinfo->effectivename); - qunihdr(userinfo->fullname); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunihdr(userinfo->logonscript); - qunihdr(userinfo->profilepath); - qunihdr(userinfo->homedirectory); - qunihdr(userinfo->homedirectorydrive); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSSVAL(userinfo->logoncount); - qSSVAL(userinfo->badpwcount); - qSIVAL(userinfo->uid); - qSIVAL(userinfo->gid); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->ngroups); - qSIVAL(8); /* ptr to groups */ - qSIVAL(userinfo->userflags); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */ - qunihdr(userinfo->logonserver); - qunihdr(userinfo->logondomain); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(2); /* logon domain id ptr */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - memset(q,0,40); q += 40; /* expansion room */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->nsids); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(0); /* ptr to sids and values */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->effectivename); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->fullname); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->logonscript); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->profilepath); - qunistr(userinfo->homedirectory); - qunistr(userinfo->homedirectorydrive); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->ngroups); - for (i = 0; i < userinfo->ngroups; i++) - { - qSIVAL(userinfo->groups[i].gid); - qSIVAL(userinfo->groups[i].attr); - } - qunistr(userinfo->logonserver); - qunistr(userinfo->logondomain); - for (i = 0; i < userinfo->nsids; i++) - { - /* put the extra sids: PAXX: TODO */ - } - /* Assumption. This is the only domain, sending our SID */ - /* PAXX: may want to do passthrough later */ - strcpy(domsid,lp_domainsid()); - DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); - /* assume, but should check, that domsid starts "S-" */ - p = strtok(domsid+2,"-"); - revision = atoi(p); - DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); - identauth = atoi(strtok(0,"-")); - DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - qSCVAL(1); /* Authoratitive. Change if passthrough? */ - qSCVAL(0); /* pad for above boolean */ - qSSVAL(0); /* pad for above boolean */ - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - - case LSASAMLOGOFF: - DEBUG(1,("LSASAMLOGOFF\n")); - q = data + 0x18; - logonsrv = q + 16; - DEBUG(1,("SAMLOGOFF %d\n", __LINE__)); - unicomp = skip_unicode_string(logonsrv,1)+16; - if (strlen(unistr(logonsrv)) % 2 == 0) - q += 2; - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = skip_unicode_string(unicomp,1)+4; - if (strlen(unistr(unicomp)) % 2 == 0) - q += 2; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[0] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[1] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - clnttime = qIVAL; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - q += 4; - rtncred[0] = qIVAL; /* all these are ignored */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - rtncred[1] = qIVAL; - rtntime = qIVAL; - logonlevel = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - switchval = qSVAL; - switch (switchval) - { - case 1: - q += 4; - domlen = qSVAL; - dommaxlen = qSVAL; q += 4; - paramcontrol = qIVAL; - logonid[0] = qIVAL; /* low part */ - logonid[1] = qIVAL; /* high part */ - usernamelen = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - usernamemaxlen = qSVAL; q += 4; - wslen = qSVAL; - wsmaxlen = qSVAL; q += 4; - rc4lmowfpass = q; q += 16; - rc4ntowfpass = q; q += 16; - q += 12; domain = q; q += dommaxlen + 12; - if ((domlen/2) % 2 != 0) q += 2; - username = q; q += usernamemaxlen + 12; /* PAXX: HACK */ - if ((usernamelen/2) % 2 != 0) q += 2; - ws = q; - break; - default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval)); - } - DEBUG(1,("SAMLOGOFF %s\n", unistr(username))); - default: - DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); + qSIVAL(subauths[i]); } - return(True); -} - -static void checkcred(int cnum, uint32 cred0, uint32 cred1, uint32 time) -{ - uint32 sum[2]; - char netdata[8]; - char netsesskey[8]; - char calccred[8]; - char icv[8]; - char key2[7]; - - SIVAL(netdata, 0, dcauth[cnum].cred[0]+time); - SIVAL(netdata, 4, dcauth[cnum].cred[1]); - SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); - SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); - E1(netsesskey,netdata,icv); - memset(key2, 0, sizeof key2); - key2[0] = netsesskey[7]; - E1(key2, icv, calccred); - if (IVAL(calccred,0) != cred0 || - IVAL(calccred,4) != cred1) - { - DEBUG(1,("Incorrect client credential received cred %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", - cred0, cred1, time, - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].cred[0], dcauth[cnum].cred[1], - IVAL(calccred,0), IVAL(calccred,4))); - /* PAXX: do something about it! */ - } else - DEBUG(4,("Correct client credential received chal %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n", - cred0, cred1, time, - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].cred[0], dcauth[cnum].cred[1], - IVAL(calccred,0), IVAL(calccred,4))); -} + qSCVAL(1); /* Authoratitive. Change if passthrough? */ + qSCVAL(0); /* pad for above boolean */ + qSSVAL(0); /* pad for above boolean */ + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + +case LSASAMLOGOFF: + DEBUG(1,("LSASAMLOGOFF\n")); + q = data + 0x18; + logonsrv = q + 16; + DEBUG(1,("SAMLOGOFF %d\n", __LINE__)); + unicomp = skip_unicode_string(logonsrv,1)+16; + if (strlen(unistr(logonsrv)) % 2 == 0) +q += 2; + DEBUG(1,("SMLOG %d\n", __LINE__)); + q = skip_unicode_string(unicomp,1)+4; + if (strlen(unistr(unicomp)) % 2 == 0) +q += 2; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[0] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + rcvcred[1] = qIVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + clnttime = qIVAL; + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + q += 4; + rtncred[0] = qIVAL; /* all these are ignored */ + DEBUG(1,("SMLOG %d\n", __LINE__)); + rtncred[1] = qIVAL; + rtntime = qIVAL; + logonlevel = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + switchval = qSVAL; + switch (switchval) + { + case 1: + q += 4; + domlen = qSVAL; + dommaxlen = qSVAL; q += 4; + paramcontrol = qIVAL; + logonid[0] = qIVAL; /* low part */ + logonid[1] = qIVAL; /* high part */ + usernamelen = qSVAL; + DEBUG(1,("SMLOG %d\n", __LINE__)); + usernamemaxlen = qSVAL; q += 4; + wslen = qSVAL; + wsmaxlen = qSVAL; q += 4; + rc4lmowfpass = q; q += 16; + rc4ntowfpass = q; q += 16; + q += 12; domain = q; q += dommaxlen + 12; + if ((domlen/2) % 2 != 0) q += 2; + username = q; q += usernamemaxlen + 12; /* PAXX: HACK */ + if ((usernamelen/2) % 2 != 0) q += 2; + ws = q; + break; +default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval)); + } + DEBUG(1,("SAMLOGOFF %s\n", unistr(username))); +default: + DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); -static void makecred(int cnum, uint32 time, char *calccred) -{ - uint32 sum[2]; - char netdata[8]; - char netsesskey[8]; - char icv[8]; - char key2[7]; - - SIVAL(netdata, 0, dcauth[cnum].svrcred[0]+time); - SIVAL(netdata, 4, dcauth[cnum].svrcred[1]); - SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]); - SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]); - E1(netsesskey,netdata,icv); - memset(key2, 0, sizeof key2); - key2[0] = netsesskey[7]; - E1(key2, icv, calccred); - DEBUG(4,("Server credential: chal %lx %lx sk %lx %lx cred %lx %lx calc %lx %lx\n", - dcauth[cnum].svrchal[0], dcauth[cnum].svrchal[1], - dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1], - dcauth[cnum].svrcred[0], dcauth[cnum].svrcred[1], - IVAL(calccred, 0), IVAL(calccred, 4))); -} +#endif /* 0 */ -static void setsesskey(int cnum) +void no_fn(uint uid) { - uint32 sum[2]; - char netsum[8]; - char netsesskey[8]; - char icv[8]; - - sum[0] = dcauth[cnum].chal[0] + dcauth[cnum].svrchal[0]; - sum[1] = dcauth[cnum].chal[1] + dcauth[cnum].svrchal[1]; - SIVAL(netsum,0,sum[0]); - SIVAL(netsum,4,sum[1]); - E1(dcauth[cnum].md4pw,netsum,icv); - E1(dcauth[cnum].md4pw+9,icv,netsesskey); - dcauth[cnum].sesskey[0] = IVAL(netsesskey,0); - dcauth[cnum].sesskey[1] = IVAL(netsesskey,4); - -DEBUG(1,("NL: session key %08x %08x\n", - dcauth[cnum].sesskey[0], - dcauth[cnum].sesskey[1])); } -static struct uinfo *getuserinfo(char *user, int len, char *ntowfpass) -{ - static struct uinfo u; - static pstring fullnm; - static pstring ascuser; - extern pstring myname; - static pstring stme; - static pstring stdom; - struct smb_passwd *smb_pass; - - strcpy(ascuser,unistr(user)); - ascuser[len/2] = 0; /* PAXX: FIXMEFIXMEFIXME */ - DEBUG(1,("GETUSER username :%s: len=%d\n",ascuser, len)); - - smb_pass = get_smbpwnam(ascuser); - if(!smb_pass) - return 0; - DEBUG(1,("GETU %d\n", __LINE__)); - if (memcmp(ntowfpass, smb_pass->smb_nt_passwd, 16)) { - DEBUG(1,("pass mismatch:\n")); - dump_data(1,ntowfpass,16); - dump_data(1,smb_pass->smb_nt_passwd,16); - return 0; - } - - DEBUG(1,("GETU %d\n", __LINE__)); - u.logontime[0] = 0xffffffff; u.logontime[1] = 0x7fffffff; - u.logofftime[0] = 0xffffffff; u.logofftime[1] = 0x7fffffff; - u.kickofftime[0] = 0xffffffff; u.kickofftime[1] = 0x7fffffff; - DEBUG(1,("GETU %d\n", __LINE__)); - u.passlastsettime[0] = 0xffffffff; u.passlastsettime[1] = 0x7fffffff; - u.passcanchgtime[0] = 0xffffffff; u.passcanchgtime[1] = 0x7fffffff; - u.passmustchgtime[0] = 0xffffffff; u.passmustchgtime[1] = 0x7fffffff; - DEBUG(1,("GETU %d\n", __LINE__)); - u.effectivename = ascuser; - strcpy(fullnm, "Full name of "); - strcat(fullnm, ascuser); - DEBUG(1,("GETU %d\n", __LINE__)); - u.fullname = fullnm; - u.logonscript = "foologin.cmd"; - u.profilepath = "prof"; - u.homedirectory = "foohomes"; - DEBUG(1,("GETU %d\n", __LINE__)); - u.homedirectorydrive = "a:"; - u.logoncount = 7; - u.badpwcount = 8; - u.uid = 778; - DEBUG(1,("GETU %d\n", __LINE__)); - u.gid = 998; - u.ngroups = 2; - u.groups = (struct groupinfo *)(malloc(sizeof (struct groupinfo) * 2)); - u.groups[0].gid = 776; - DEBUG(1,("GETU %d\n", __LINE__)); - u.groups[0].attr = 0x7; - u.groups[1].gid = 776; - u.groups[1].attr = 0x7; - u.userflags = 0x20; - u.logonserver = stme; - get_myname(myname,NULL); - strcpy(stme, myname); - strupper(stme); - DEBUG(1,("LS %s\n", u.logonserver)); - u.logondomain = stdom; - strcpy(stdom, lp_workgroup()); - strupper(stdom); - DEBUG(1,("DOM %s\n", u.logondomain)); - u.nsids = 0; - u.sids = 0; - DEBUG(1,("GETU %d\n", __LINE__)); - return &u; -}; +#endif /* NTDOMAIN */ +#ifdef UNDEFINED_NTDOMAIN +/* + PAXX: Someone fix above. + The above API is indexing RPC calls based on RPC flags and + fragment length. I've decided to do it based on operation number :-) +*/ #endif /* NTDOMAIN */ -- cgit From 7f296a8f905cc40972ed249567e5d985c0ce3825 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 10 Oct 1997 18:03:30 +0000 Subject: added lsa_reply_srv_pwset() (This used to be commit 0d043cfef289ee82287bb6014a164ba83ca87f30) --- source3/smbd/pipes.c | 162 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 66 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 24f15ba7fd..0a94be0aa0 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -747,11 +747,6 @@ static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, return q - start; } -static void make_lsa_chal(DOM_CHAL *cred, char resp_cred[8]) -{ - memcpy(cred->data, resp_cred, sizeof(cred->data)); -} - static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status) { @@ -777,22 +772,22 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, return q - start; } -static void make_lsa_dom_chal(DOM_CRED *cred, char srv_chal[8], UTIME srv_time) +static void make_lsa_dom_chal(DOM_CRED *cred, DOM_CHAL *srv_chal, UTIME srv_time) { - make_lsa_chal(&(cred->challenge), srv_chal); + memcpy(cred->challenge.data, srv_chal->data, sizeof(srv_chal->data)); cred->timestamp = srv_time; } static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, - char srv_chal[8], UTIME srv_time, int status) + DOM_CHAL *srv_chal, UTIME srv_time, int status) { make_lsa_dom_chal(&(r_a->srv_cred), srv_chal, srv_time); r_a->status = status; } static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, - char srv_cred[8], UTIME srv_time, + DOM_CHAL *srv_cred, UTIME srv_time, int status) { char *start = q; @@ -922,7 +917,7 @@ static void make_lsa_user_info(LSA_USER_INFO *usr, static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, - char srv_cred[8], UTIME srv_time, + DOM_CHAL *srv_cred, UTIME srv_time, LSA_USER_INFO *user_info) { char *start = q; @@ -946,7 +941,7 @@ static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, - char srv_cred[8], UTIME srv_time, + DOM_CHAL *srv_cred, UTIME srv_time, uint32 status) { char *start = q; @@ -1276,9 +1271,9 @@ static void api_lsa_auth_2( user_struct *vuser, &(vuser->dc.srv_cred), srv_time); /* create server credentials for inclusion in the reply */ - cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred), srv_time, &srv_chal); + cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), srv_time, &srv_chal); - /* construct reply. return status is always 0x0 */ + /* construct reply. */ reply_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata + 0x18, &srv_chal, 0x0); @@ -1289,6 +1284,87 @@ static void api_lsa_auth_2( user_struct *vuser, } +static void api_lsa_srv_pwset( user_struct *vuser, + char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + LSA_Q_SRV_PWSET q_a; + + DOM_CHAL srv_chal; + UTIME srv_time; + UTIME new_clnt_time; + + srv_time.time = 0; + + /* grab the challenge... */ + lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4); + + /* check that the client credentials are valid */ + cred_assert(&(q_a.clnt_id.cred.challenge), vuser->dc.sess_key, + &(vuser->dc.srv_cred), srv_time); + + new_clnt_time.time = q_a.clnt_id.cred.timestamp.time + 1; + + /* create server credentials for inclusion in the reply */ + cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time, &srv_chal); + + *(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time ); + + /* construct reply. always indicate failure. nt keeps going... */ + reply_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata + 0x18, + &srv_chal, srv_time, + NT_STATUS_WRONG_PASSWORD|0xC000000); + + /* construct header, now that we know the reply length */ + reply_len += make_rpc_reply(data, *rdata, reply_len); + + *rdata_len = reply_len; +} + +#if 0 +case LSASRVPWSET: + DEBUG(1,("LSASRVPWSET\n")); + q = data + 0x18; + dump_data(1,q,128); + logonsrv = q + 16; + q = skip_unicode_string(logonsrv,1)+12; + q = align4(q, data); + accountname = q; + q = skip_unicode_string(accountname,1); + secchanneltype = qSVAL; + q += 12; + q = align4(q, data); + unicomp = q; + q = skip_unicode_string(unicomp,1); + rcvcred[0] = qIVAL; + rcvcred[1] = qIVAL; + clnttime = qIVAL; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp))); + + checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); + DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); + newpass = q; + + DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", + unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); + + /* PAXX: For the moment we'll reject these */ + /* TODO Need to set newpass in smbpasswd file for accountname */ + q = *rdata + 0x18; + makecred(cnum, clnttime+1, q); + q += 8; + qSIVAL(0); /* timestamp. Seems to be ignored */ + + dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + + endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); + break; +#endif + + BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, @@ -1331,6 +1407,13 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, break; } + case LSA_SRVPWSET: + { + DEBUG(3,("LSA_SRVPWSET\n")); + api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len); + break; + } + default: { DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); @@ -1344,46 +1427,6 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, #if 0 -case LSASVRPWSET: - DEBUG(1,("LSASVRPWSET\n")); - q = data + 0x18; - dump_data(1,q,128); - logonsrv = q + 16; - q = skip_unicode_string(logonsrv,1)+12; - q = align4(q, data); - accountname = q; - q = skip_unicode_string(accountname,1); - secchanneltype = qSVAL; - q += 12; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1); - rcvcred[0] = qIVAL; - rcvcred[1] = qIVAL; - clnttime = qIVAL; - - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp))); - - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); - newpass = q; - - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); - - /* PAXX: For the moment we'll reject these */ - /* TODO Need to set newpass in smbpasswd file for accountname */ - q = *rdata + 0x18; - makecred(cnum, clnttime+1, q); - q += 8; - qSIVAL(0); /* timestamp. Seems to be ignored */ - - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; - - endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); - break; - case LSASAMLOGON: DEBUG(1,("LSASAMLOGON\n")); dump_data(1,data,128); @@ -1631,17 +1674,4 @@ default: #endif /* 0 */ -void no_fn(uint uid) -{ -} - -#endif /* NTDOMAIN */ - -#ifdef UNDEFINED_NTDOMAIN -/* - PAXX: Someone fix above. - The above API is indexing RPC calls based on RPC flags and - fragment length. I've decided to do it based on operation number :-) -*/ - #endif /* NTDOMAIN */ -- cgit From 422c54ff38c338e213c57f5b882bea8cf8c14b98 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 10 Oct 1997 19:48:51 +0000 Subject: added api_lsa_sam_logon() and api_sam_logoff(). that's it. lots of run-time debugging, now. (This used to be commit 75f32987d8599d10b294dc4e0c0160eecda7296b) --- source3/smbd/pipes.c | 386 ++++++++++++++++++++++++++++----------------------- 1 file changed, 216 insertions(+), 170 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 0a94be0aa0..e6c29fadf6 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -772,29 +772,21 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, return q - start; } -static void make_lsa_dom_chal(DOM_CRED *cred, DOM_CHAL *srv_chal, UTIME srv_time) -{ - memcpy(cred->challenge.data, srv_chal->data, sizeof(srv_chal->data)); - cred->timestamp = srv_time; -} - - static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, - DOM_CHAL *srv_chal, UTIME srv_time, int status) + DOM_CRED *srv_cred, int status) { - make_lsa_dom_chal(&(r_a->srv_cred), srv_chal, srv_time); + memcpy(&(r_a->srv_cred), srv_cred, sizeof(r_a->srv_cred)); r_a->status = status; } static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, - DOM_CHAL *srv_cred, UTIME srv_time, - int status) + DOM_CRED *srv_cred, int status) { char *start = q; LSA_R_SRV_PWSET r_s; /* set up the LSA Server Password Set response */ - make_lsa_r_srv_pwset(&r_s, srv_cred, srv_time, status); + make_lsa_r_srv_pwset(&r_s, srv_cred, status); /* store the response in the SMB stream */ q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4); @@ -917,15 +909,14 @@ static void make_lsa_user_info(LSA_USER_INFO *usr, static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, - DOM_CHAL *srv_cred, UTIME srv_time, - LSA_USER_INFO *user_info) + DOM_CRED *srv_cred, LSA_USER_INFO *user_info) { char *start = q; LSA_R_SAM_LOGON r_s; /* XXXX maybe we want to say 'no', reject the client's credentials */ r_s.buffer_creds = 1; /* yes, we have valid server credentials */ - make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time); + memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds)); /* store the user information, if there is any. */ r_s.user = user_info; @@ -941,7 +932,7 @@ static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, - DOM_CHAL *srv_cred, UTIME srv_time, + DOM_CRED *srv_cred, uint32 status) { char *start = q; @@ -949,7 +940,7 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, /* XXXX maybe we want to say 'no', reject the client's credentials */ r_s.buffer_creds = 1; /* yes, we have valid server credentials */ - make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time); + memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds)); r_s.status = status; @@ -1284,36 +1275,52 @@ static void api_lsa_auth_2( user_struct *vuser, } -static void api_lsa_srv_pwset( user_struct *vuser, - char *param, char *data, - char **rdata, int *rdata_len ) +static BOOL deal_with_credentials(user_struct *vuser, + DOM_CRED *clnt_cred, DOM_CRED *srv_cred) { - int reply_len; - LSA_Q_SRV_PWSET q_a; - - DOM_CHAL srv_chal; - UTIME srv_time; UTIME new_clnt_time; - srv_time.time = 0; - - /* grab the challenge... */ - lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4); + /* doesn't matter that server time is 0 */ + srv_cred->timestamp.time = 0; /* check that the client credentials are valid */ - cred_assert(&(q_a.clnt_id.cred.challenge), vuser->dc.sess_key, - &(vuser->dc.srv_cred), srv_time); + if (cred_assert(&(clnt_cred->challenge), vuser->dc.sess_key, + &(vuser->dc.srv_cred), clnt_cred->timestamp)) + { + return False; + } - new_clnt_time.time = q_a.clnt_id.cred.timestamp.time + 1; + /* increment client time by one second */ + new_clnt_time.time = clnt_cred->timestamp.time + 1; /* create server credentials for inclusion in the reply */ - cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time, &srv_chal); + cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time, + &(srv_cred->challenge)); + /* update the client and server credentials, for use next time... */ *(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time ); + return True; +} + +static void api_lsa_srv_pwset( user_struct *vuser, + char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + LSA_Q_SRV_PWSET q_a; + + DOM_CRED srv_cred; + + /* grab the challenge and encrypted password ... */ + lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4); + + /* checks and updates credentials. creates reply credentials */ + deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred); + /* construct reply. always indicate failure. nt keeps going... */ reply_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata + 0x18, - &srv_chal, srv_time, + &srv_cred, NT_STATUS_WRONG_PASSWORD|0xC000000); /* construct header, now that we know the reply length */ @@ -1322,111 +1329,133 @@ static void api_lsa_srv_pwset( user_struct *vuser, *rdata_len = reply_len; } -#if 0 -case LSASRVPWSET: - DEBUG(1,("LSASRVPWSET\n")); - q = data + 0x18; - dump_data(1,q,128); - logonsrv = q + 16; - q = skip_unicode_string(logonsrv,1)+12; - q = align4(q, data); - accountname = q; - q = skip_unicode_string(accountname,1); - secchanneltype = qSVAL; - q += 12; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1); - rcvcred[0] = qIVAL; - rcvcred[1] = qIVAL; - clnttime = qIVAL; - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp))); +static void api_lsa_sam_logoff( user_struct *vuser, + char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + LSA_Q_SAM_LOGOFF q_l; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags)); - newpass = q; + DOM_CRED srv_cred; + + /* grab the challenge... */ + lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data + 0x18, 4); - DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n", - unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass)); + /* checks and updates credentials. creates reply credentials */ + deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred); - /* PAXX: For the moment we'll reject these */ - /* TODO Need to set newpass in smbpasswd file for accountname */ - q = *rdata + 0x18; - makecred(cnum, clnttime+1, q); - q += 8; - qSIVAL(0); /* timestamp. Seems to be ignored */ - - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; + /* construct reply. always indicate success */ + reply_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata + 0x18, + &srv_cred, + 0x0); - endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len); - break; -#endif + /* construct header, now that we know the reply length */ + reply_len += make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len; +} -BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) + +static void api_lsa_sam_logon( user_struct *vuser, + char *param, char *data, + char **rdata, int *rdata_len ) { - uint16 opnum = SVAL(data,22); - int pkttype = CVAL(data, 2); + int reply_len; + LSA_Q_SAM_LOGON q_l; + LSA_USER_INFO usr_info; + LSA_USER_INFO *p_usr_info = NULL; - user_struct *vuser = get_valid_user_struct(uid); + DOM_CRED srv_creds; - if (pkttype == 0x0b) /* RPC BIND */ + lsa_io_q_sam_logon(True, &q_l, data + 0x18, data + 0x18, 4); + + /* checks and updates credentials. creates reply credentials */ + deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds); + + if (vuser != NULL) { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } + NTTIME dummy_time; + pstring logon_script; + pstring profile_path; + pstring home_dir; + pstring home_drive; + pstring my_name; + pstring my_workgroup; + pstring dom_sid; + pstring username; + extern pstring myname; + + dummy_time.low = 0xffffffff; + dummy_time.high = 0x7fffffff; + + get_myname(myname, NULL); + + pstrcpy(logon_script, lp_logon_script()); + pstrcpy(profile_path, lp_logon_path ()); + pstrcpy(dom_sid , lp_domainsid ()); + pstrcpy(my_workgroup, lp_workgroup ()); + + pstrcpy(username, unistr2(q_l.sam_id.client.login.uni_acct_name.buffer)); + pstrcpy(my_name , myname ); + strupper(my_name); + + pstrcpy(home_drive , "a:" ); + +#if (defined(NETGROUP) && defined(AUTOMOUNT)) + pstrcpy(home_dir , vuser->home_share); +#else + pstrcpy(home_dir , "\\\\%L\\%U"); + standard_sub_basic(home_dir); +#endif - DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); + p_usr_info = &usr_info; - if (vuser == NULL) return False; + make_lsa_user_info(p_usr_info, - DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); -#if defined(NETGROUP) && defined(AUTOMOUNT) - DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share)); -#endif + &dummy_time, /* logon_time */ + &dummy_time, /* logoff_time */ + &dummy_time, /* kickoff_time */ + &dummy_time, /* pass_last_set_time */ + &dummy_time, /* pass_can_change_time */ + &dummy_time, /* pass_must_change_time */ - switch (opnum) - { - case LSA_REQCHAL: - { - DEBUG(3,("LSA_REQCHAL\n")); - api_lsa_req_chal(vuser, param, data, rdata, rdata_len); - break; - } + username, /* user_name */ + vuser->real_name, /* full_name */ + logon_script, /* logon_script */ + profile_path, /* profile_path */ + home_dir, /* home_dir */ + home_drive, /* dir_drive */ - case LSA_AUTH2: - { - DEBUG(3,("LSA_AUTH2\n")); - api_lsa_auth_2(vuser, param, data, rdata, rdata_len); - break; - } + 0, /* logon_count */ + 0, /* bad_pw_count */ - case LSA_SRVPWSET: - { - DEBUG(3,("LSA_SRVPWSET\n")); - api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len); - break; - } + vuser->uid, /* uint32 user_id */ + vuser->gid, /* uint32 group_id */ + 0, /* uint32 num_groups */ + NULL, /* DOM_GID *gids */ + 0x20, /* uint32 user_flgs */ - default: - { - DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); - break; - } + NULL, /* char sess_key[16] */ + + my_name, /* char *logon_srv */ + my_workgroup, /* char *logon_dom */ + + dom_sid, /* char *dom_sid */ + NULL); /* char *other_sids */ } - return True; + reply_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata + 0x18, + &srv_creds, p_usr_info); + + /* construct header, now that we know the reply length */ + reply_len += make_rpc_reply(data, *rdata, reply_len); + + *rdata_len = reply_len; } #if 0 - case LSASAMLOGON: DEBUG(1,("LSASAMLOGON\n")); dump_data(1,data,128); @@ -1616,62 +1645,79 @@ DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); break; +#endif -case LSASAMLOGOFF: - DEBUG(1,("LSASAMLOGOFF\n")); - q = data + 0x18; - logonsrv = q + 16; - DEBUG(1,("SAMLOGOFF %d\n", __LINE__)); - unicomp = skip_unicode_string(logonsrv,1)+16; - if (strlen(unistr(logonsrv)) % 2 == 0) -q += 2; - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = skip_unicode_string(unicomp,1)+4; - if (strlen(unistr(unicomp)) % 2 == 0) -q += 2; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[0] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[1] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - clnttime = qIVAL; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - q += 4; - rtncred[0] = qIVAL; /* all these are ignored */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - rtncred[1] = qIVAL; - rtntime = qIVAL; - logonlevel = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - switchval = qSVAL; - switch (switchval) - { - case 1: - q += 4; - domlen = qSVAL; - dommaxlen = qSVAL; q += 4; - paramcontrol = qIVAL; - logonid[0] = qIVAL; /* low part */ - logonid[1] = qIVAL; /* high part */ - usernamelen = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - usernamemaxlen = qSVAL; q += 4; - wslen = qSVAL; - wsmaxlen = qSVAL; q += 4; - rc4lmowfpass = q; q += 16; - rc4ntowfpass = q; q += 16; - q += 12; domain = q; q += dommaxlen + 12; - if ((domlen/2) % 2 != 0) q += 2; - username = q; q += usernamemaxlen + 12; /* PAXX: HACK */ - if ((usernamelen/2) % 2 != 0) q += 2; - ws = q; - break; -default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval)); - } - DEBUG(1,("SAMLOGOFF %s\n", unistr(username))); -default: - DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); +BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum = SVAL(data,22); + int pkttype = CVAL(data, 2); + + user_struct *vuser = get_valid_user_struct(uid); + + if (pkttype == 0x0b) /* RPC BIND */ + { + DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; + } -#endif /* 0 */ + DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); + + if (vuser == NULL) return False; + + DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); +#if defined(NETGROUP) && defined(AUTOMOUNT) + DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share)); +#endif + + switch (opnum) + { + case LSA_REQCHAL: + { + DEBUG(3,("LSA_REQCHAL\n")); + api_lsa_req_chal(vuser, param, data, rdata, rdata_len); + break; + } + + case LSA_AUTH2: + { + DEBUG(3,("LSA_AUTH2\n")); + api_lsa_auth_2(vuser, param, data, rdata, rdata_len); + break; + } + + case LSA_SRVPWSET: + { + DEBUG(3,("LSA_SRVPWSET\n")); + api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len); + break; + } + + case LSA_SAMLOGON: + { + DEBUG(3,("LSA_SAMLOGON\n")); + api_lsa_sam_logon(vuser, param, data, rdata, rdata_len); + break; + } + + case LSA_SAMLOGOFF: + { + DEBUG(3,("LSA_SAMLOGOFF\n")); + api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len); + break; + } + + default: + { + DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); + break; + } + } + + return True; +} #endif /* NTDOMAIN */ -- cgit From a26037ac7c1ac218863f9d674dcf85293eb2f085 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Oct 1997 11:46:42 +0000 Subject: added debugging macros (suitable eventually for use in tcpdump, hopefully) (This used to be commit 946d73cf838976b905550288cac3aea7c43959f6) --- source3/smbd/pipes.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index e6c29fadf6..3bfee3e3cf 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -503,15 +503,20 @@ static int make_rpc_reply(char *inbuf, char *q, int data_len) static int lsa_reply_open_policy(char *q, char *base) { + int i; char *start = q; LSA_R_OPEN_POL r_o; /* set up the LSA QUERY INFO response */ - bzero(&(r_o.pol.data), POL_HND_SIZE); + /* bzero(&(r_o.pol.data), POL_HND_SIZE); */ + for (i = 0; i < POL_HND_SIZE; i++) + { + r_o.pol.data[i] = i; + } r_o.status = 0x0; /* store the response in the SMB stream */ - q = lsa_io_r_open_pol(False, &r_o, q, base, 4); + q = lsa_io_r_open_pol(False, &r_o, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -601,7 +606,7 @@ static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, r_q.status = 0x0; /* store the response in the SMB stream */ - q = lsa_io_r_query(False, &r_q, q, base, 4); + q = lsa_io_r_query(False, &r_q, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -697,7 +702,7 @@ static int lsa_reply_lookup_sids(char *q, char *base, r_l.status = 0x0; /* store the response in the SMB stream */ - q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4); + q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -717,7 +722,7 @@ static int lsa_reply_lookup_rids(char *q, char *base, r_l.status = 0x0; /* store the response in the SMB stream */ - q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4); + q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -741,7 +746,7 @@ static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, make_lsa_r_req_chal(&r_c, srv_chal, 0); /* store the response in the SMB stream */ - q = lsa_io_r_req_chal(False, &r_c, q, base, 4); + q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -766,7 +771,7 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status); /* store the response in the SMB stream */ - q = lsa_io_r_auth_2(False, &r_a, q, base, 4); + q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -789,7 +794,7 @@ static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, make_lsa_r_srv_pwset(&r_s, srv_cred, status); /* store the response in the SMB stream */ - q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4); + q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -924,7 +929,7 @@ static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER); /* store the response in the SMB stream */ - q = lsa_io_r_sam_logon(False, &r_s, q, base, 4); + q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -945,7 +950,7 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, r_s.status = status; /* store the response in the SMB stream */ - q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4); + q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ return q - start; @@ -978,7 +983,7 @@ static void api_lsa_query_info( char *param, char *data, pstring dom_sid; /* grab the info class and policy handle */ - lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4); + lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4, 0); pstrcpy(dom_name, lp_workgroup()); pstrcpy(dom_sid , lp_domainsid()); @@ -1004,7 +1009,7 @@ static void api_lsa_lookup_sids( char *param, char *data, fstring dom_sids[MAX_LOOKUP_SIDS]; /* grab the info class and policy handle */ - lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4); + lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4, 0); pstrcpy(dom_name, lp_workgroup()); pstrcpy(dom_sid , lp_domainsid()); @@ -1038,7 +1043,7 @@ static void api_lsa_lookup_names( char *param, char *data, uint32 dom_rids[MAX_LOOKUP_SIDS]; /* grab the info class and policy handle */ - lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4); + lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4, 0); pstrcpy(dom_name, lp_workgroup()); pstrcpy(dom_sid , lp_domainsid()); @@ -1224,7 +1229,7 @@ static void api_lsa_req_chal( user_struct *vuser, fstring mach_acct; /* grab the challenge... */ - lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4); + lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4, 0); fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer)); @@ -1255,7 +1260,7 @@ static void api_lsa_auth_2( user_struct *vuser, srv_time.time = 0; /* grab the challenge... */ - lsa_io_q_auth_2(True, &q_a, data + 0x18, data + 0x18, 4); + lsa_io_q_auth_2(True, &q_a, data + 0x18, data + 0x18, 4, 0); /* check that the client credentials are valid */ cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key, @@ -1313,7 +1318,7 @@ static void api_lsa_srv_pwset( user_struct *vuser, DOM_CRED srv_cred; /* grab the challenge and encrypted password ... */ - lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4); + lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4, 0); /* checks and updates credentials. creates reply credentials */ deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred); @@ -1340,7 +1345,7 @@ static void api_lsa_sam_logoff( user_struct *vuser, DOM_CRED srv_cred; /* grab the challenge... */ - lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data + 0x18, 4); + lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data + 0x18, 4, 0); /* checks and updates credentials. creates reply credentials */ deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred); @@ -1368,7 +1373,7 @@ static void api_lsa_sam_logon( user_struct *vuser, DOM_CRED srv_creds; - lsa_io_q_sam_logon(True, &q_l, data + 0x18, data + 0x18, 4); + lsa_io_q_sam_logon(True, &q_l, data + 0x18, data + 0x18, 4, 0); /* checks and updates credentials. creates reply credentials */ deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds); @@ -1655,7 +1660,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, uint16 opnum = SVAL(data,22); int pkttype = CVAL(data, 2); - user_struct *vuser = get_valid_user_struct(uid); + user_struct *vuser; if (pkttype == 0x0b) /* RPC BIND */ { @@ -1666,7 +1671,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); - if (vuser == NULL) return False; + if ((vuser = get_valid_user_struct(uid)) == NULL) return False; DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); #if defined(NETGROUP) && defined(AUTOMOUNT) -- cgit From 60575a888aebec898fdaf0f6c0c8269607b2571f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Oct 1997 14:17:55 +0000 Subject: ipc.c: debugging info. found that data = NULL because of short packet length indicated from the ntlsaRPC pipe _royally_ stuffs NT's packet handling. maybe this should go down as a service denial bug to the ntbugtraq list. pipes.c lsaparse.c smbparse.c : added more debug stuff. added length of header to data_len in MSRPC fragment_length field (0x18 bytes short) which caused the above bug from NT 4.0. oops. (This used to be commit a6f8de6815e0b85bb23b302980730501ac0b87e5) --- source3/smbd/pipes.c | 69 +++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 3bfee3e3cf..820f596572 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -482,7 +482,7 @@ static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) hdr->minor = 0; /* minor version 0 */ hdr->pkt_type = 2; /* RPC response packet */ hdr->frag = 3; /* first frag + last frag */ - hdr->pack_type = 1; /* packed data representation */ + hdr->pack_type = 0x10; /* packed data representation */ hdr->frag_len = data_len; /* fragment length, fill in later */ hdr->auth_len = 0; /* authentication length */ hdr->call_id = call_id; /* call identifier - match incoming RPC */ @@ -507,11 +507,18 @@ static int lsa_reply_open_policy(char *q, char *base) char *start = q; LSA_R_OPEN_POL r_o; + static char handle[20] = + { 0x00, 0x00, 0x00, 0x00, + 0x2f, 0x79, 0x0a, 0x81, + 0xd5, 0x17, 0xd1, 0x11, + 0x80, 0xaf, 0x96, 0xcd, + 0x50, 0xf8, 0xbc, 0x6c + }; /* set up the LSA QUERY INFO response */ /* bzero(&(r_o.pol.data), POL_HND_SIZE); */ for (i = 0; i < POL_HND_SIZE; i++) { - r_o.pol.data[i] = i; + r_o.pol.data[i] = handle[i]; } r_o.status = 0x0; @@ -960,24 +967,16 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, static void api_lsa_open_policy( char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - /* we might actually want to decode the query, but it's not necessary */ /* lsa_io_q_open_policy(...); */ - /* return a 20 byte policy handle */ - reply_len = lsa_reply_open_policy(*rdata + 0x18, *rdata + 0x18); - - /* construct header, now that we know the reply length */ - make_rpc_reply(data, *rdata, reply_len); - *rdata_len = reply_len + 0x18; + /* construct a 20 byte policy handle. return length*/ + *rdata_len = lsa_reply_open_policy(*rdata + 0x18, *rdata); } -static void api_lsa_query_info( char *param, char *data, +static int api_lsa_query_info( char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - LSA_Q_QUERY_INFO q_i; pstring dom_name; pstring dom_sid; @@ -989,19 +988,13 @@ static void api_lsa_query_info( char *param, char *data, pstrcpy(dom_sid , lp_domainsid()); /* construct reply. return status is always 0x0 */ - reply_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata + 0x18, + return lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata, dom_name, dom_sid); - - /* construct header, now that we know the reply length */ - make_rpc_reply(data, *rdata, reply_len); - *rdata_len = reply_len + 0x18; } static void api_lsa_lookup_sids( char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - int i; LSA_Q_LOOKUP_SIDS q_l; pstring dom_name; @@ -1021,21 +1014,15 @@ static void api_lsa_lookup_sids( char *param, char *data, } /* construct reply. return status is always 0x0 */ - reply_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata, q_l.num_entries, dom_sids, /* text-converted SIDs */ dom_name, dom_sid, /* domain name, domain SID */ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ - - /* construct header, now that we know the reply length */ - make_rpc_reply(data, *rdata, reply_len); - *rdata_len = reply_len + 0x18; } static void api_lsa_lookup_names( char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - int i; LSA_Q_LOOKUP_RIDS q_l; pstring dom_name; @@ -1056,14 +1043,10 @@ static void api_lsa_lookup_names( char *param, char *data, } /* construct reply. return status is always 0x0 */ - reply_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata, q_l.num_entries, dom_rids, /* text-converted SIDs */ dom_name, dom_sid, /* domain name, domain SID */ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ - - /* construct header, now that we know the reply length */ - make_rpc_reply(data, *rdata, reply_len); - *rdata_len = reply_len + 0x18; } BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, @@ -1088,6 +1071,8 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_OPENPOLICY\n")); api_lsa_open_policy(param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); + break; } @@ -1096,6 +1081,8 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, DEBUG(3,("LSA_QUERYINFOPOLICY\n")); api_lsa_query_info(param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); + break; } @@ -1157,6 +1144,8 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_OPENSECRET\n")); api_lsa_lookup_sids(param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); + break; } @@ -1164,6 +1153,8 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_LOOKUPNAMES\n")); api_lsa_lookup_names(param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); + break; } @@ -1657,11 +1648,17 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - uint16 opnum = SVAL(data,22); - int pkttype = CVAL(data, 2); - + uint16 opnum; + char pkttype; user_struct *vuser; + DEBUG(5,("api_netlogrpcTNP data:%x\n", data)); + + if (data == NULL) return False; + + opnum = SVAL(data,22); + pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ { DEBUG(4,("netlogon rpc bind %x\n",pkttype)); @@ -1669,7 +1666,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, return True; } - DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); + DEBUG(4,("netlogon TransactNamedPipe op %x\n", opnum)); if ((vuser = get_valid_user_struct(uid)) == NULL) return False; -- cgit From 78f6bc4eba9f6d68c31b1c7e35243a1b81619b0d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Oct 1997 17:07:35 +0000 Subject: updated rpc header reply: callid wrong; alloc hint a uint32 not a uint16. still doesn't get rid of the netlogon trans2 request with zero data. (This used to be commit 0cf67955f09d99c452bfc3fdde00dcea98e21db1) --- source3/smbd/pipes.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 820f596572..4f1d015216 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -53,10 +53,11 @@ a packet to ensure chaining works correctly */ char * known_pipes [] = { - "lsarpc", #if NTDOMAIN "NETLOGON", + "srvsvc", #endif + "lsarpc", NULL }; @@ -494,17 +495,18 @@ static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) static int make_rpc_reply(char *inbuf, char *q, int data_len) { - uint32 callid = RIVAL(inbuf, 12); + uint32 callid = IVAL(inbuf, 12); RPC_HDR hdr; + DEBUG(5,("make_rpc_reply. callid: %x\n", callid)); + create_rpc_reply(&hdr, callid, data_len); - return smb_io_rpc_hdr(False, &hdr, q, q, 4) - q; + return PTR_DIFF(smb_io_rpc_hdr(False, &hdr, q, q, 4), q); } static int lsa_reply_open_policy(char *q, char *base) { int i; - char *start = q; LSA_R_OPEN_POL r_o; static char handle[20] = @@ -526,7 +528,7 @@ static int lsa_reply_open_policy(char *q, char *base) q = lsa_io_r_open_pol(False, &r_o, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate) @@ -600,7 +602,6 @@ static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, char *dom_name, char *dom_sid) { - char *start = q; LSA_R_QUERY_INFO r_q; /* set up the LSA QUERY INFO response */ @@ -616,7 +617,7 @@ static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, q = lsa_io_r_query(False, &r_q, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } /* pretty much hard-coded choice of "other" sids, unfortunately... */ @@ -700,7 +701,6 @@ static int lsa_reply_lookup_sids(char *q, char *base, char *dom_name, char *dom_sid, char *other_sid1, char *other_sid2, char *other_sid3) { - char *start = q; LSA_R_LOOKUP_SIDS r_l; /* set up the LSA Lookup SIDs response */ @@ -712,7 +712,7 @@ static int lsa_reply_lookup_sids(char *q, char *base, q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static int lsa_reply_lookup_rids(char *q, char *base, @@ -720,7 +720,6 @@ static int lsa_reply_lookup_rids(char *q, char *base, char *dom_name, char *dom_sid, char *other_sid1, char *other_sid2, char *other_sid3) { - char *start = q; LSA_R_LOOKUP_RIDS r_l; /* set up the LSA Lookup RIDs response */ @@ -732,7 +731,7 @@ static int lsa_reply_lookup_rids(char *q, char *base, q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, @@ -745,7 +744,6 @@ static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, DOM_CHAL *srv_chal) { - char *start = q; LSA_R_REQ_CHAL r_c; /* set up the LSA REQUEST CHALLENGE response */ @@ -756,7 +754,7 @@ static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, @@ -770,7 +768,6 @@ static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, DOM_CHAL *resp_cred, int status) { - char *start = q; LSA_R_AUTH_2 r_a; /* set up the LSA AUTH 2 response */ @@ -781,7 +778,7 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, @@ -794,7 +791,6 @@ static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, DOM_CRED *srv_cred, int status) { - char *start = q; LSA_R_SRV_PWSET r_s; /* set up the LSA Server Password Set response */ @@ -804,7 +800,7 @@ static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_lsa_user_info(LSA_USER_INFO *usr, @@ -923,7 +919,6 @@ static void make_lsa_user_info(LSA_USER_INFO *usr, static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, DOM_CRED *srv_cred, LSA_USER_INFO *user_info) { - char *start = q; LSA_R_SAM_LOGON r_s; /* XXXX maybe we want to say 'no', reject the client's credentials */ @@ -939,7 +934,7 @@ static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } @@ -947,7 +942,6 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, DOM_CRED *srv_cred, uint32 status) { - char *start = q; LSA_R_SAM_LOGOFF r_s; /* XXXX maybe we want to say 'no', reject the client's credentials */ @@ -960,7 +954,7 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } -- cgit From db20ab9bbdcc8fbfa81883c2d0c952386820de4c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Oct 1997 19:02:55 +0000 Subject: getting somewhere. ipc.c : removed srvsvc pipe reference: have to do that. pipes.c lsaparse.c smbparse.c : more debugging info. looks a bit like netmon output. (This used to be commit e02aa88e25ae6d4da7953aaff04ff2ae9a656d05) --- source3/smbd/pipes.c | 109 ++++++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 48 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 4f1d015216..eb8215b7a3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -53,11 +53,10 @@ a packet to ensure chaining works correctly */ char * known_pipes [] = { + "lsarpc", #if NTDOMAIN "NETLOGON", - "srvsvc", #endif - "lsarpc", NULL }; @@ -483,7 +482,7 @@ static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) hdr->minor = 0; /* minor version 0 */ hdr->pkt_type = 2; /* RPC response packet */ hdr->frag = 3; /* first frag + last frag */ - hdr->pack_type = 0x10; /* packed data representation */ + hdr->pack_type = 1; /* packed data representation */ hdr->frag_len = data_len; /* fragment length, fill in later */ hdr->auth_len = 0; /* authentication length */ hdr->call_id = call_id; /* call identifier - match incoming RPC */ @@ -495,32 +494,24 @@ static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) static int make_rpc_reply(char *inbuf, char *q, int data_len) { - uint32 callid = IVAL(inbuf, 12); + uint32 callid = RIVAL(inbuf, 12); RPC_HDR hdr; - DEBUG(5,("make_rpc_reply. callid: %x\n", callid)); - create_rpc_reply(&hdr, callid, data_len); - return PTR_DIFF(smb_io_rpc_hdr(False, &hdr, q, q, 4), q); + return smb_io_rpc_hdr(False, &hdr, q, q, 4, 0) - q; } static int lsa_reply_open_policy(char *q, char *base) { int i; + char *start = q; LSA_R_OPEN_POL r_o; - static char handle[20] = - { 0x00, 0x00, 0x00, 0x00, - 0x2f, 0x79, 0x0a, 0x81, - 0xd5, 0x17, 0xd1, 0x11, - 0x80, 0xaf, 0x96, 0xcd, - 0x50, 0xf8, 0xbc, 0x6c - }; /* set up the LSA QUERY INFO response */ /* bzero(&(r_o.pol.data), POL_HND_SIZE); */ for (i = 0; i < POL_HND_SIZE; i++) { - r_o.pol.data[i] = handle[i]; + r_o.pol.data[i] = i; } r_o.status = 0x0; @@ -528,7 +519,7 @@ static int lsa_reply_open_policy(char *q, char *base) q = lsa_io_r_open_pol(False, &r_o, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate) @@ -602,6 +593,7 @@ static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, char *dom_name, char *dom_sid) { + char *start = q; LSA_R_QUERY_INFO r_q; /* set up the LSA QUERY INFO response */ @@ -617,7 +609,7 @@ static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, q = lsa_io_r_query(False, &r_q, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } /* pretty much hard-coded choice of "other" sids, unfortunately... */ @@ -701,6 +693,7 @@ static int lsa_reply_lookup_sids(char *q, char *base, char *dom_name, char *dom_sid, char *other_sid1, char *other_sid2, char *other_sid3) { + char *start = q; LSA_R_LOOKUP_SIDS r_l; /* set up the LSA Lookup SIDs response */ @@ -712,7 +705,7 @@ static int lsa_reply_lookup_sids(char *q, char *base, q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } static int lsa_reply_lookup_rids(char *q, char *base, @@ -720,6 +713,7 @@ static int lsa_reply_lookup_rids(char *q, char *base, char *dom_name, char *dom_sid, char *other_sid1, char *other_sid2, char *other_sid3) { + char *start = q; LSA_R_LOOKUP_RIDS r_l; /* set up the LSA Lookup RIDs response */ @@ -731,7 +725,7 @@ static int lsa_reply_lookup_rids(char *q, char *base, q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, @@ -739,11 +733,16 @@ static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, { memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(r_c->srv_chal.data)); r_c->status = status; + + DEBUG(5,("make_lsa_r_req_chal srv_chal: %lx %lx\n", + *(uint32*)(&((r_c->srv_chal.data[0]))), + *(uint32*)(&((r_c->srv_chal.data[4]))) )); } static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, DOM_CHAL *srv_chal) { + char *start = q; LSA_R_REQ_CHAL r_c; /* set up the LSA REQUEST CHALLENGE response */ @@ -754,7 +753,7 @@ static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, @@ -768,6 +767,7 @@ static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, DOM_CHAL *resp_cred, int status) { + char *start = q; LSA_R_AUTH_2 r_a; /* set up the LSA AUTH 2 response */ @@ -778,7 +778,7 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, @@ -791,6 +791,7 @@ static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, DOM_CRED *srv_cred, int status) { + char *start = q; LSA_R_SRV_PWSET r_s; /* set up the LSA Server Password Set response */ @@ -800,7 +801,7 @@ static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } static void make_lsa_user_info(LSA_USER_INFO *usr, @@ -919,6 +920,7 @@ static void make_lsa_user_info(LSA_USER_INFO *usr, static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, DOM_CRED *srv_cred, LSA_USER_INFO *user_info) { + char *start = q; LSA_R_SAM_LOGON r_s; /* XXXX maybe we want to say 'no', reject the client's credentials */ @@ -934,7 +936,7 @@ static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } @@ -942,6 +944,7 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, DOM_CRED *srv_cred, uint32 status) { + char *start = q; LSA_R_SAM_LOGOFF r_s; /* XXXX maybe we want to say 'no', reject the client's credentials */ @@ -954,23 +957,31 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return PTR_DIFF(q, base); + return q - start; } static void api_lsa_open_policy( char *param, char *data, char **rdata, int *rdata_len ) { + int reply_len; + /* we might actually want to decode the query, but it's not necessary */ /* lsa_io_q_open_policy(...); */ - /* construct a 20 byte policy handle. return length*/ - *rdata_len = lsa_reply_open_policy(*rdata + 0x18, *rdata); + /* return a 20 byte policy handle */ + reply_len = lsa_reply_open_policy(*rdata + 0x18, *rdata + 0x18); + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; } -static int api_lsa_query_info( char *param, char *data, +static void api_lsa_query_info( char *param, char *data, char **rdata, int *rdata_len ) { + int reply_len; + LSA_Q_QUERY_INFO q_i; pstring dom_name; pstring dom_sid; @@ -982,13 +993,19 @@ static int api_lsa_query_info( char *param, char *data, pstrcpy(dom_sid , lp_domainsid()); /* construct reply. return status is always 0x0 */ - return lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata, + reply_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata + 0x18, dom_name, dom_sid); + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; } static void api_lsa_lookup_sids( char *param, char *data, char **rdata, int *rdata_len ) { + int reply_len; + int i; LSA_Q_LOOKUP_SIDS q_l; pstring dom_name; @@ -1008,15 +1025,21 @@ static void api_lsa_lookup_sids( char *param, char *data, } /* construct reply. return status is always 0x0 */ - *rdata_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata, + reply_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata + 0x18, q_l.num_entries, dom_sids, /* text-converted SIDs */ dom_name, dom_sid, /* domain name, domain SID */ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; } static void api_lsa_lookup_names( char *param, char *data, char **rdata, int *rdata_len ) { + int reply_len; + int i; LSA_Q_LOOKUP_RIDS q_l; pstring dom_name; @@ -1037,10 +1060,14 @@ static void api_lsa_lookup_names( char *param, char *data, } /* construct reply. return status is always 0x0 */ - *rdata_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata, + reply_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata + 0x18, q_l.num_entries, dom_rids, /* text-converted SIDs */ dom_name, dom_sid, /* domain name, domain SID */ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; } BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, @@ -1065,8 +1092,6 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_OPENPOLICY\n")); api_lsa_open_policy(param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; } @@ -1075,8 +1100,6 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, DEBUG(3,("LSA_QUERYINFOPOLICY\n")); api_lsa_query_info(param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; } @@ -1138,8 +1161,6 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_OPENSECRET\n")); api_lsa_lookup_sids(param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; } @@ -1147,8 +1168,6 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_LOOKUPNAMES\n")); api_lsa_lookup_names(param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; } @@ -1642,16 +1661,10 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - uint16 opnum; - char pkttype; - user_struct *vuser; - - DEBUG(5,("api_netlogrpcTNP data:%x\n", data)); - - if (data == NULL) return False; + uint16 opnum = SVAL(data,22); + int pkttype = CVAL(data, 2); - opnum = SVAL(data,22); - pkttype = CVAL(data, 2); + user_struct *vuser; if (pkttype == 0x0b) /* RPC BIND */ { @@ -1660,7 +1673,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, return True; } - DEBUG(4,("netlogon TransactNamedPipe op %x\n", opnum)); + DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); if ((vuser = get_valid_user_struct(uid)) == NULL) return False; -- cgit From 2259e56a947104b19a1196154af4e43ab15e4b7c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 13 Oct 1997 12:21:56 +0000 Subject: byteorder.h : debugging output wasn't (still isn't) perfect. credentials.c lsaparse.c smbparse.c : added DEBUG strings. pipes.c : lost some changes, to do with setup of RPC headers. arg. (This used to be commit 9fdd697d17b68293bb95fd68f44c24f0f5b97f5f) --- source3/smbd/pipes.c | 346 ++++++++------------------------------------------- 1 file changed, 54 insertions(+), 292 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index eb8215b7a3..173b3cdd06 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -504,7 +504,6 @@ static int make_rpc_reply(char *inbuf, char *q, int data_len) static int lsa_reply_open_policy(char *q, char *base) { int i; - char *start = q; LSA_R_OPEN_POL r_o; /* set up the LSA QUERY INFO response */ @@ -519,7 +518,7 @@ static int lsa_reply_open_policy(char *q, char *base) q = lsa_io_r_open_pol(False, &r_o, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate) @@ -593,7 +592,6 @@ static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, char *dom_name, char *dom_sid) { - char *start = q; LSA_R_QUERY_INFO r_q; /* set up the LSA QUERY INFO response */ @@ -609,7 +607,7 @@ static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, q = lsa_io_r_query(False, &r_q, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } /* pretty much hard-coded choice of "other" sids, unfortunately... */ @@ -693,7 +691,6 @@ static int lsa_reply_lookup_sids(char *q, char *base, char *dom_name, char *dom_sid, char *other_sid1, char *other_sid2, char *other_sid3) { - char *start = q; LSA_R_LOOKUP_SIDS r_l; /* set up the LSA Lookup SIDs response */ @@ -705,7 +702,7 @@ static int lsa_reply_lookup_sids(char *q, char *base, q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static int lsa_reply_lookup_rids(char *q, char *base, @@ -713,7 +710,6 @@ static int lsa_reply_lookup_rids(char *q, char *base, char *dom_name, char *dom_sid, char *other_sid1, char *other_sid2, char *other_sid3) { - char *start = q; LSA_R_LOOKUP_RIDS r_l; /* set up the LSA Lookup RIDs response */ @@ -725,35 +721,35 @@ static int lsa_reply_lookup_rids(char *q, char *base, q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, DOM_CHAL *srv_chal, int status) { - memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(r_c->srv_chal.data)); + DEBUG(6,("make_lsa_r_req_chal: %d\n", __LINE__)); + memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data)); r_c->status = status; - - DEBUG(5,("make_lsa_r_req_chal srv_chal: %lx %lx\n", - *(uint32*)(&((r_c->srv_chal.data[0]))), - *(uint32*)(&((r_c->srv_chal.data[4]))) )); } static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, DOM_CHAL *srv_chal) { - char *start = q; LSA_R_REQ_CHAL r_c; - /* set up the LSA REQUEST CHALLENGE response */ + DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__)); + memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data)); + /* set up the LSA REQUEST CHALLENGE response */ make_lsa_r_req_chal(&r_c, srv_chal, 0); /* store the response in the SMB stream */ q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0); + DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__)); + /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, @@ -767,7 +763,6 @@ static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, DOM_CHAL *resp_cred, int status) { - char *start = q; LSA_R_AUTH_2 r_a; /* set up the LSA AUTH 2 response */ @@ -778,7 +773,7 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, @@ -791,7 +786,6 @@ static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, DOM_CRED *srv_cred, int status) { - char *start = q; LSA_R_SRV_PWSET r_s; /* set up the LSA Server Password Set response */ @@ -801,7 +795,7 @@ static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void make_lsa_user_info(LSA_USER_INFO *usr, @@ -920,7 +914,6 @@ static void make_lsa_user_info(LSA_USER_INFO *usr, static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, DOM_CRED *srv_cred, LSA_USER_INFO *user_info) { - char *start = q; LSA_R_SAM_LOGON r_s; /* XXXX maybe we want to say 'no', reject the client's credentials */ @@ -936,7 +929,7 @@ static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } @@ -944,7 +937,6 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, DOM_CRED *srv_cred, uint32 status) { - char *start = q; LSA_R_SAM_LOGOFF r_s; /* XXXX maybe we want to say 'no', reject the client's credentials */ @@ -957,55 +949,41 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0); /* return length of SMB data stored */ - return q - start; + return PTR_DIFF(q, base); } static void api_lsa_open_policy( char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - /* we might actually want to decode the query, but it's not necessary */ /* lsa_io_q_open_policy(...); */ /* return a 20 byte policy handle */ - reply_len = lsa_reply_open_policy(*rdata + 0x18, *rdata + 0x18); - - /* construct header, now that we know the reply length */ - make_rpc_reply(data, *rdata, reply_len); - *rdata_len = reply_len + 0x18; + *rdata_len = lsa_reply_open_policy(*rdata + 0x18, *rdata); } static void api_lsa_query_info( char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - LSA_Q_QUERY_INFO q_i; pstring dom_name; pstring dom_sid; /* grab the info class and policy handle */ - lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4, 0); + lsa_io_q_query(True, &q_i, data + 0x18, data, 4, 0); pstrcpy(dom_name, lp_workgroup()); pstrcpy(dom_sid , lp_domainsid()); /* construct reply. return status is always 0x0 */ - reply_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata, dom_name, dom_sid); - - /* construct header, now that we know the reply length */ - make_rpc_reply(data, *rdata, reply_len); - *rdata_len = reply_len + 0x18; } static void api_lsa_lookup_sids( char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - int i; LSA_Q_LOOKUP_SIDS q_l; pstring dom_name; @@ -1013,7 +991,7 @@ static void api_lsa_lookup_sids( char *param, char *data, fstring dom_sids[MAX_LOOKUP_SIDS]; /* grab the info class and policy handle */ - lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4, 0); + lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data, 4, 0); pstrcpy(dom_name, lp_workgroup()); pstrcpy(dom_sid , lp_domainsid()); @@ -1025,21 +1003,15 @@ static void api_lsa_lookup_sids( char *param, char *data, } /* construct reply. return status is always 0x0 */ - reply_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata, q_l.num_entries, dom_sids, /* text-converted SIDs */ dom_name, dom_sid, /* domain name, domain SID */ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ - - /* construct header, now that we know the reply length */ - make_rpc_reply(data, *rdata, reply_len); - *rdata_len = reply_len + 0x18; } static void api_lsa_lookup_names( char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - int i; LSA_Q_LOOKUP_RIDS q_l; pstring dom_name; @@ -1047,7 +1019,7 @@ static void api_lsa_lookup_names( char *param, char *data, uint32 dom_rids[MAX_LOOKUP_SIDS]; /* grab the info class and policy handle */ - lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4, 0); + lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data, 4, 0); pstrcpy(dom_name, lp_workgroup()); pstrcpy(dom_sid , lp_domainsid()); @@ -1060,14 +1032,10 @@ static void api_lsa_lookup_names( char *param, char *data, } /* construct reply. return status is always 0x0 */ - reply_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata, q_l.num_entries, dom_rids, /* text-converted SIDs */ dom_name, dom_sid, /* domain name, domain SID */ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ - - /* construct header, now that we know the reply length */ - make_rpc_reply(data, *rdata, reply_len); - *rdata_len = reply_len + 0x18; } BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, @@ -1092,6 +1060,7 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_OPENPOLICY\n")); api_lsa_open_policy(param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); break; } @@ -1100,6 +1069,7 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, DEBUG(3,("LSA_QUERYINFOPOLICY\n")); api_lsa_query_info(param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); break; } @@ -1161,6 +1131,7 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_OPENSECRET\n")); api_lsa_lookup_sids(param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); break; } @@ -1168,6 +1139,7 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_LOOKUPNAMES\n")); api_lsa_lookup_names(param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); break; } @@ -1180,11 +1152,16 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, return True; } -static BOOL update_dcinfo(struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct) +static BOOL update_dcinfo(int cnum, uint16 vuid, + struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct) { - struct smb_passwd *smb_pass = get_smbpwnam(mach_acct); + struct smb_passwd *smb_pass; int i; + unbecome_user(); + smb_pass = get_smbpwnam(mach_acct); + become_user(cnum, vuid); + if (smb_pass != NULL) { memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw)); @@ -1219,43 +1196,39 @@ static BOOL update_dcinfo(struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acc dc->srv_chal.data[i] = 0xA5; } + DEBUG(6,("update_dcinfo: %d\n", __LINE__)); + return True; } -static void api_lsa_req_chal( user_struct *vuser, +static void api_lsa_req_chal( int cnum, uint16 vuid, + user_struct *vuser, char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; - LSA_Q_REQ_CHAL q_r; fstring mach_acct; /* grab the challenge... */ - lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4, 0); + lsa_io_q_req_chal(True, &q_r, data + 0x18, data, 4, 0); fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer)); strcat(mach_acct, "$"); - update_dcinfo(&(vuser->dc), &(q_r.clnt_chal), mach_acct); + update_dcinfo(cnum, vuid, &(vuser->dc), &(q_r.clnt_chal), mach_acct); /* construct reply. return status is always 0x0 */ - reply_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata, &(vuser->dc.srv_chal)); - /* construct header, now that we know the reply length */ - reply_len += make_rpc_reply(data, *rdata, reply_len); - - *rdata_len = reply_len; } static void api_lsa_auth_2( user_struct *vuser, char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; LSA_Q_AUTH_2 q_a; DOM_CHAL srv_chal; @@ -1264,7 +1237,7 @@ static void api_lsa_auth_2( user_struct *vuser, srv_time.time = 0; /* grab the challenge... */ - lsa_io_q_auth_2(True, &q_a, data + 0x18, data + 0x18, 4, 0); + lsa_io_q_auth_2(True, &q_a, data + 0x18, data, 4, 0); /* check that the client credentials are valid */ cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key, @@ -1274,13 +1247,8 @@ static void api_lsa_auth_2( user_struct *vuser, cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), srv_time, &srv_chal); /* construct reply. */ - reply_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata, &srv_chal, 0x0); - - /* construct header, now that we know the reply length */ - reply_len += make_rpc_reply(data, *rdata, reply_len); - - *rdata_len = reply_len; } @@ -1316,26 +1284,20 @@ static void api_lsa_srv_pwset( user_struct *vuser, char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; LSA_Q_SRV_PWSET q_a; DOM_CRED srv_cred; /* grab the challenge and encrypted password ... */ - lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4, 0); + lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data, 4, 0); /* checks and updates credentials. creates reply credentials */ deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred); /* construct reply. always indicate failure. nt keeps going... */ - reply_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata, &srv_cred, NT_STATUS_WRONG_PASSWORD|0xC000000); - - /* construct header, now that we know the reply length */ - reply_len += make_rpc_reply(data, *rdata, reply_len); - - *rdata_len = reply_len; } @@ -1343,26 +1305,20 @@ static void api_lsa_sam_logoff( user_struct *vuser, char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; LSA_Q_SAM_LOGOFF q_l; DOM_CRED srv_cred; /* grab the challenge... */ - lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data + 0x18, 4, 0); + lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data, 4, 0); /* checks and updates credentials. creates reply credentials */ deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred); /* construct reply. always indicate success */ - reply_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata, &srv_cred, 0x0); - - /* construct header, now that we know the reply length */ - reply_len += make_rpc_reply(data, *rdata, reply_len); - - *rdata_len = reply_len; } @@ -1370,14 +1326,13 @@ static void api_lsa_sam_logon( user_struct *vuser, char *param, char *data, char **rdata, int *rdata_len ) { - int reply_len; LSA_Q_SAM_LOGON q_l; LSA_USER_INFO usr_info; LSA_USER_INFO *p_usr_info = NULL; DOM_CRED srv_creds; - lsa_io_q_sam_logon(True, &q_l, data + 0x18, data + 0x18, 4, 0); + lsa_io_q_sam_logon(True, &q_l, data + 0x18, data, 4, 0); /* checks and updates credentials. creates reply credentials */ deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds); @@ -1454,208 +1409,11 @@ static void api_lsa_sam_logon( user_struct *vuser, NULL); /* char *other_sids */ } - reply_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata + 0x18, + *rdata_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata, &srv_creds, p_usr_info); - - /* construct header, now that we know the reply length */ - reply_len += make_rpc_reply(data, *rdata, reply_len); - - *rdata_len = reply_len; } -#if 0 -case LSASAMLOGON: - DEBUG(1,("LSASAMLOGON\n")); - dump_data(1,data,128); - q = data + 0x18; - logonsrv = q + 16; - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = skip_unicode_string(logonsrv,1)+16; - q = align4(q, data); - unicomp = q; - q = skip_unicode_string(unicomp,1)+4; - DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n", - __LINE__, unistr(logonsrv), unistr(unicomp))); - q = align4(q, data); - rcvcred[0] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - rcvcred[1] = qIVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - clnttime = qIVAL; - checkcred(cnum, rcvcred[0], rcvcred[1], clnttime); - q += 2; - rtncred[0] = qIVAL; /* all these are ignored */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - rtncred[1] = qIVAL; - rtntime = qIVAL; - logonlevel = qSVAL; - DEBUG(1,("SMLOG %d\n", __LINE__)); - switchval = qSVAL; - switch (switchval) - { - case 1: - - q += 6; - domlen = qSVAL; - dommaxlen = qSVAL; q += 4; - paramcontrol = qIVAL; - logonid[0] = qIVAL; /* low part */ - logonid[1] = qIVAL; /* high part */ - - usernamelen = qSVAL; - - DEBUG(1,("SMLOG %d\n", __LINE__)); - usernamemaxlen = qSVAL; q += 4; - - DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n", - usernamelen, usernamemaxlen, dommaxlen)); - - dump_data(1,q,128); - - wslen = qSVAL; - wsmaxlen = qSVAL; q += 4; - rc4lmowfpass = q; q += 16; - rc4ntowfpass = q; q += 16; - - q += 12; domain = q; q += dommaxlen + 12; - q = align4(q, data); - username = q; q += usernamemaxlen + 12; - q = align4(q, data); - ws = q; - DEBUG(1,("domain=%s username=%s ws=%s\n", - unistr(domain), unistr(username), - unistr(ws))); - break; - default: - DEBUG(0,("unknown switch in SAMLOGON %d\n", - switchval)); - } - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]); - DEBUG(1,("userNAME %s [%s]\n", foo, username)); - DEBUG(1,("SMLOG %d\n", __LINE__)); - q = *rdata + 0x18; - qSIVAL(0x16a4b4); /* magic buffer pointer ? */ - makecred(cnum, clnttime+1, q); - dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1; - q += 8; - qSIVAL(0); /* timestamp. client doesn't care */ - qSSVAL(3); /* switch value 3. May be others? */ - qSSVAL(0); /* undocumented */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - - memset(rc4key, 0, sizeof rc4key); - SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]); - SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]); - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]); - DEBUG(1,("rc4ntowf %s\n", foo)); - arcfour_init(&c, rc4key, sizeof rc4key); - arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass); - for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]); - DEBUG(1,("ntowf %s\n", foo)); - - if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) { - qSIVAL(0); /* no buffer */ - qSCVAL(1); /* Authoratitive. Change if passthrough? */ - qSCVAL(0); /* pad for above boolean */ - qSSVAL(0); /* pad for above boolean */ - - endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len); - break; - } - - qSIVAL(2); /* another magic bufptr? */ - DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo)); - qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]); - qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]); - DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1])); - qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]); - qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]); - qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]); - qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]); - DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename)); - qunihdr(userinfo->effectivename); - qunihdr(userinfo->fullname); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunihdr(userinfo->logonscript); - qunihdr(userinfo->profilepath); - qunihdr(userinfo->homedirectory); - qunihdr(userinfo->homedirectorydrive); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSSVAL(userinfo->logoncount); - qSSVAL(userinfo->badpwcount); - qSIVAL(userinfo->uid); - qSIVAL(userinfo->gid); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->ngroups); - qSIVAL(8); /* ptr to groups */ - qSIVAL(userinfo->userflags); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */ - qunihdr(userinfo->logonserver); - qunihdr(userinfo->logondomain); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(2); /* logon domain id ptr */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - memset(q,0,40); q += 40; /* expansion room */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->nsids); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(0); /* ptr to sids and values */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->effectivename); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->fullname); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->logonscript); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qunistr(userinfo->profilepath); - qunistr(userinfo->homedirectory); - qunistr(userinfo->homedirectorydrive); - DEBUG(1,("SMLOG %d\n", __LINE__)); - qSIVAL(userinfo->ngroups); - for (i = 0; i < userinfo->ngroups; i++) - { - qSIVAL(userinfo->groups[i].gid); - qSIVAL(userinfo->groups[i].attr); - } - qunistr(userinfo->logonserver); - qunistr(userinfo->logondomain); - for (i = 0; i < userinfo->nsids; i++) - { - /* put the extra sids: PAXX: TODO */ - } - /* Assumption. This is the only domain, sending our SID */ - /* PAXX: may want to do passthrough later */ - strcpy(domsid,lp_domainsid()); -DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid)); - /* assume, but should check, that domsid starts "S-" */ - p = strtok(domsid+2,"-"); - revision = atoi(p); -DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision)); - identauth = atoi(strtok(0,"-")); -DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth)); - numsubauths = 0; - while (p = strtok(0, "-")) - subauths[numsubauths++] = atoi(p); - qSIVAL(numsubauths); - qSCVAL(revision); - qSCVAL(numsubauths); - qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */ - qRSIVAL(identauth); /* next 4 bytes */ - DEBUG(1,("SMLOG %d\n", __LINE__)); - for (i = 0; i < numsubauths; i++) - { - qSIVAL(subauths[i]); - } - qSCVAL(1); /* Authoratitive. Change if passthrough? */ - qSCVAL(0); /* pad for above boolean */ - qSSVAL(0); /* pad for above boolean */ - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; -#endif - BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, @@ -1687,7 +1445,8 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, case LSA_REQCHAL: { DEBUG(3,("LSA_REQCHAL\n")); - api_lsa_req_chal(vuser, param, data, rdata, rdata_len); + api_lsa_req_chal(cnum, uid, vuser, param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); break; } @@ -1695,6 +1454,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_AUTH2\n")); api_lsa_auth_2(vuser, param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); break; } @@ -1702,6 +1462,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_SRVPWSET\n")); api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); break; } @@ -1709,6 +1470,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_SAMLOGON\n")); api_lsa_sam_logon(vuser, param, data, rdata, rdata_len); + make_rpc_reply(data, *rdata, *rdata_len); break; } -- cgit From 081dcc7e8b7c6a336a1fe5e46b90d6cbb9b1a3d2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 13 Oct 1997 12:55:07 +0000 Subject: checked in a file with a compile error. oops! (This used to be commit 28d96c7e6de19a28346d406ccc6fc8b00305903b) --- source3/smbd/pipes.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 173b3cdd06..772e49f41d 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -739,7 +739,6 @@ static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__)); - memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data)); /* set up the LSA REQUEST CHALLENGE response */ make_lsa_r_req_chal(&r_c, srv_chal, 0); -- cgit From 2225fe13766ae07a44e27cc4a1fb665cf5afc804 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 13 Oct 1997 13:35:37 +0000 Subject: debug info added (This used to be commit a3f96555b47265b8cd4d1f735af58375e2591d56) --- source3/smbd/pipes.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 772e49f41d..59592a04ae 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -1164,6 +1164,8 @@ static BOOL update_dcinfo(int cnum, uint16 vuid, if (smb_pass != NULL) { memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw)); + DEBUG(5,("dc->md4pw(%d) :", sizeof(dc->md4pw))); + dump_data(5, dc->md4pw, 16); } else { @@ -1218,6 +1220,8 @@ static void api_lsa_req_chal( int cnum, uint16 vuid, update_dcinfo(cnum, vuid, &(vuser->dc), &(q_r.clnt_chal), mach_acct); + DEBUG(6,("api_lsa_req_chal: %d\n", __LINE__)); + /* construct reply. return status is always 0x0 */ *rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata, &(vuser->dc.srv_chal)); -- cgit From fcc885e0169ac6418cca9e6030863a225dee6adf Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 13 Oct 1997 14:19:17 +0000 Subject: debugging... no idea what i'm doing. (This used to be commit d7a9a02e0a9e1e791810c24bcfcbd39a6bd7dac5) --- source3/smbd/pipes.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 59592a04ae..74bde7493d 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -1181,13 +1181,9 @@ static BOOL update_dcinfo(int cnum, uint16 vuid, DEBUG(4,("pass %s %s\n", mach_acct, foo)); } - /* from client / server challenges and md4 password, generate sess key */ - cred_session_key(&(dc->clnt_chal), &(dc->srv_chal), - dc->md4pw, dc->sess_key); - - /* copy the client credentials for later use */ - memcpy(dc->srv_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); - memcpy(dc->srv_cred.data, clnt_chal->data, sizeof(clnt_chal->data)); + /* copy the client credentials */ + memcpy(dc->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); + memcpy(dc->clnt_cred.data, clnt_chal->data, sizeof(clnt_chal->data)); /* create a server challenge for the client */ /* PAXX: set these to random values. */ @@ -1197,6 +1193,10 @@ static BOOL update_dcinfo(int cnum, uint16 vuid, dc->srv_chal.data[i] = 0xA5; } + /* from client / server challenges and md4 password, generate sess key */ + cred_session_key(&(dc->clnt_chal), &(dc->srv_chal), + dc->md4pw, dc->sess_key); + DEBUG(6,("update_dcinfo: %d\n", __LINE__)); return True; @@ -1218,9 +1218,10 @@ static void api_lsa_req_chal( int cnum, uint16 vuid, strcat(mach_acct, "$"); - update_dcinfo(cnum, vuid, &(vuser->dc), &(q_r.clnt_chal), mach_acct); + DEBUG(6,("q_r.clnt_chal.data(%d) :", sizeof(q_r.clnt_chal.data))); + dump_data(6, q_r.clnt_chal.data, 8); - DEBUG(6,("api_lsa_req_chal: %d\n", __LINE__)); + update_dcinfo(cnum, vuid, &(vuser->dc), &(q_r.clnt_chal), mach_acct); /* construct reply. return status is always 0x0 */ *rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata, -- cgit From 1035aa9c73bd26e0b01781e6b9b8af51b2013a25 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 13 Oct 1997 15:55:54 +0000 Subject: split pipes.c down into util, netlog and ntlsa. (This used to be commit 8fe02c239d70497af449ed0cdf1a32de10021ba1) --- source3/smbd/pipes.c | 1136 +------------------------------------------------- 1 file changed, 1 insertion(+), 1135 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 74bde7493d..91ca69c022 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -28,7 +28,6 @@ #include "includes.h" #include "trans2.h" -#include "nterr.h" #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) @@ -216,7 +215,7 @@ BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data, TransactNamedPipe on \PIPE\lsarpc. ****************************************************************************/ -static void LsarpcTNP1(char *data,char **rdata, int *rdata_len) +void LsarpcTNP1(char *data,char **rdata, int *rdata_len) { uint32 dword1, dword2; char pname[] = "\\PIPE\\lsass"; @@ -363,1136 +362,3 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, } return(True); } - - -#ifdef NTDOMAIN -/* - PAXX: Someone fix above. - The above API is indexing RPC calls based on RPC flags and - fragment length. I've decided to do it based on operation number :-) -*/ - -/* this function is due to be replaced */ -static void initrpcreply(char *inbuf, char *q) -{ - uint32 callid; - - SCVAL(q, 0, 5); q++; /* RPC version 5 */ - SCVAL(q, 0, 0); q++; /* minor version 0 */ - SCVAL(q, 0, 2); q++; /* RPC response packet */ - SCVAL(q, 0, 3); q++; /* first frag + last frag */ - RSIVAL(q, 0, 0x10000000); q += 4; /* packed data representation */ - RSSVAL(q, 0, 0); q += 2; /* fragment length, fill in later */ - SSVAL(q, 0, 0); q += 2; /* authentication length */ - callid = RIVAL(inbuf, 12); - RSIVAL(q, 0, callid); q += 4; /* call identifier - match incoming RPC */ - SIVAL(q, 0, 0x18); q += 4; /* allocation hint (no idea) */ - SSVAL(q, 0, 0); q += 2; /* presentation context identifier */ - SCVAL(q, 0, 0); q++; /* cancel count */ - SCVAL(q, 0, 0); q++; /* reserved */ -} - -/* this function is due to be replaced */ -static void endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen) -{ - SSVAL(q, 8, datalen + 4); - SIVAL(q,0x10,datalen+4-0x18); /* allocation hint */ - SIVAL(q, datalen, rtnval); - *rlen = datalen + 4; - { int fd; fd = open("/tmp/rpc", O_RDWR); write(fd, q, datalen + 4); } -} - -/* RID username mapping function. just for fun, it maps to the unix uid */ -static uint32 name_to_rid(char *user_name) -{ - struct passwd *pw = Get_Pwnam(user_name, False); - if (!pw) - { - DEBUG(1,("Username %s is invalid on this system\n", user_name)); - return (uint32)(-1); - } - - return (uint32)(pw->pw_uid); -} - - -/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ -char *dom_sid_to_string(DOM_SID *sid) -{ - static pstring sidstr; - char subauth[16]; - int i; - uint32 ia = (sid->id_auth[0]) + - (sid->id_auth[1] << 8 ) + - (sid->id_auth[2] << 16) + - (sid->id_auth[3] << 24); - - sprintf(sidstr, "S-%d-%d", sid->sid_no, ia); - - for (i = 0; i < sid->num_auths; i++) - { - sprintf(subauth, "-%d", sid->sub_auths[i]); - strcat(sidstr, subauth); - } - - DEBUG(5,("dom_sid_to_string returning %s\n", sidstr)); - return sidstr; -} - -/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ -/* identauth >= 2^32 can be detected because it will be specified in hex */ -static void make_dom_sid(DOM_SID *sid, char *domsid) -{ - int identauth; - char *p; - - DEBUG(4,("netlogon domain SID: %s\n", domsid)); - - /* assume, but should check, that domsid starts "S-" */ - p = strtok(domsid+2,"-"); - sid->sid_no = atoi(p); - - /* identauth in decimal should be < 2^32 */ - /* identauth in hex should be >= 2^32 */ - identauth = atoi(strtok(0,"-")); - - DEBUG(4,("netlogon rev %d\n", sid->sid_no)); - DEBUG(4,("netlogon %s ia %d\n", p, identauth)); - - sid->id_auth[0] = 0; - sid->id_auth[1] = 0; - sid->id_auth[2] = (identauth & 0xff000000) >> 24; - sid->id_auth[3] = (identauth & 0x00ff0000) >> 16; - sid->id_auth[4] = (identauth & 0x0000ff00) >> 8; - sid->id_auth[5] = (identauth & 0x000000ff); - - sid->num_auths = 0; - - while ((p = strtok(0, "-")) != NULL) - { - sid->sub_auths[sid->num_auths++] = atoi(p); - } -} - -static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) -{ - if (hdr == NULL) return; - - hdr->major = 5; /* RPC version 5 */ - hdr->minor = 0; /* minor version 0 */ - hdr->pkt_type = 2; /* RPC response packet */ - hdr->frag = 3; /* first frag + last frag */ - hdr->pack_type = 1; /* packed data representation */ - hdr->frag_len = data_len; /* fragment length, fill in later */ - hdr->auth_len = 0; /* authentication length */ - hdr->call_id = call_id; /* call identifier - match incoming RPC */ - hdr->alloc_hint = data_len - 0x18; /* allocation hint (no idea) */ - hdr->context_id = 0; /* presentation context identifier */ - hdr->cancel_count = 0; /* cancel count */ - hdr->reserved = 0; /* reserved */ -} - -static int make_rpc_reply(char *inbuf, char *q, int data_len) -{ - uint32 callid = RIVAL(inbuf, 12); - RPC_HDR hdr; - - create_rpc_reply(&hdr, callid, data_len); - return smb_io_rpc_hdr(False, &hdr, q, q, 4, 0) - q; -} - -static int lsa_reply_open_policy(char *q, char *base) -{ - int i; - LSA_R_OPEN_POL r_o; - - /* set up the LSA QUERY INFO response */ - /* bzero(&(r_o.pol.data), POL_HND_SIZE); */ - for (i = 0; i < POL_HND_SIZE; i++) - { - r_o.pol.data[i] = i; - } - r_o.status = 0x0; - - /* store the response in the SMB stream */ - q = lsa_io_r_open_pol(False, &r_o, q, base, 4, 0); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - -static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate) -{ - hdr->uni_max_len = max_len; - hdr->uni_str_len = len; - hdr->undoc = terminate; -} - -static void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate) -{ - make_uni_hdr(&(hdr->unihdr), max_len, len, terminate); - hdr->undoc_buffer = len > 0 ? 1 : 0; -} - -static void make_unistr(UNISTR *str, char *buf) -{ - /* store the string (null-terminated copy) */ - PutUniCode((char *)(str->buffer), buf); -} - -static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate) -{ - /* set up string lengths. add one if string is not null-terminated */ - str->uni_max_len = len + (terminate != 0 ? 1 : 0); - str->undoc = 0; - str->uni_str_len = len; - - /* store the string (null-terminated copy) */ - PutUniCode((char *)str->buffer, buf); - - /* overwrite the last character: some strings are terminated with 4 not 0 */ - str->buffer[len] = (uint16)terminate; -} - -static void make_dom_rid2(DOM_RID2 *rid2, uint32 rid) -{ - rid2->type = 0x5; - rid2->undoc = 0x5; - rid2->rid = rid; - rid2->rid_idx = 0; -} - -static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str) -{ - int len_sid_str = strlen(sid_str); - - sid2->type = 0x5; - sid2->undoc = 0; - make_uni_hdr2(&(sid2->hdr), len_sid_str, len_sid_str, 0); - make_unistr (&(sid2->str), sid_str); -} - -static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) -{ - int domlen = strlen(dom_name); - - d_q->uni_dom_max_len = domlen * 2; - d_q->padding = 0; - d_q->uni_dom_str_len = domlen * 2; - - d_q->buffer_dom_name = 0; /* domain buffer pointer */ - d_q->buffer_dom_sid = 0; /* domain sid pointer */ - - /* NOT null-terminated: 4-terminated instead! */ - make_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4); - - make_dom_sid(&(d_q->dom_sid), dom_sid); -} - -static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, - char *dom_name, char *dom_sid) -{ - LSA_R_QUERY_INFO r_q; - - /* set up the LSA QUERY INFO response */ - - r_q.undoc_buffer = 1; /* not null */ - r_q.info_class = q_q->info_class; - - make_dom_query(&r_q.dom.id5, dom_name, dom_sid); - - r_q.status = 0x0; - - /* store the response in the SMB stream */ - q = lsa_io_r_query(False, &r_q, q, base, 4, 0); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - -/* pretty much hard-coded choice of "other" sids, unfortunately... */ -static void make_dom_ref(DOM_R_REF *ref, - char *dom_name, char *dom_sid, - char *other_sid1, char *other_sid2, char *other_sid3) -{ - int len_dom_name = strlen(dom_name); - int len_other_sid1 = strlen(other_sid1); - int len_other_sid2 = strlen(other_sid2); - int len_other_sid3 = strlen(other_sid3); - - ref->undoc_buffer = 1; - ref->num_ref_doms_1 = 4; - ref->buffer_dom_name = 1; - ref->max_entries = 32; - ref->num_ref_doms_2 = 4; - - make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0); - make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0); - make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0); - make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0); - - if (dom_name != NULL) - { - make_unistr(&(ref->uni_dom_name), dom_name); - } - - make_dom_sid(&(ref->ref_dom[0]), dom_sid ); - make_dom_sid(&(ref->ref_dom[1]), other_sid1); - make_dom_sid(&(ref->ref_dom[2]), other_sid2); - make_dom_sid(&(ref->ref_dom[3]), other_sid3); -} - -static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l, - int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS], - char *dom_name, char *dom_sid, - char *other_sid1, char *other_sid2, char *other_sid3) -{ - int i; - - make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid, - other_sid1, other_sid2, other_sid3); - - r_l->num_entries = num_entries; - r_l->undoc_buffer = 1; - r_l->num_entries2 = num_entries; - - for (i = 0; i < num_entries; i++) - { - make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]); - } - - r_l->num_entries3 = num_entries; -} - -static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, - int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS], - char *dom_name, char *dom_sid, - char *other_sid1, char *other_sid2, char *other_sid3) -{ - int i; - - make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid, - other_sid1, other_sid2, other_sid3); - - r_l->num_entries = num_entries; - r_l->undoc_buffer = 1; - r_l->num_entries2 = num_entries; - - for (i = 0; i < num_entries; i++) - { - make_dom_sid2(&(r_l->dom_sid[i]), dom_sids[i]); - } - - r_l->num_entries3 = num_entries; -} - -static int lsa_reply_lookup_sids(char *q, char *base, - int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS], - char *dom_name, char *dom_sid, - char *other_sid1, char *other_sid2, char *other_sid3) -{ - LSA_R_LOOKUP_SIDS r_l; - - /* set up the LSA Lookup SIDs response */ - make_reply_lookup_sids(&r_l, num_entries, dom_sids, - dom_name, dom_sid, other_sid1, other_sid2, other_sid3); - r_l.status = 0x0; - - /* store the response in the SMB stream */ - q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4, 0); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - -static int lsa_reply_lookup_rids(char *q, char *base, - int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS], - char *dom_name, char *dom_sid, - char *other_sid1, char *other_sid2, char *other_sid3) -{ - LSA_R_LOOKUP_RIDS r_l; - - /* set up the LSA Lookup RIDs response */ - make_reply_lookup_rids(&r_l, num_entries, dom_rids, - dom_name, dom_sid, other_sid1, other_sid2, other_sid3); - r_l.status = 0x0; - - /* store the response in the SMB stream */ - q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4, 0); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - -static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, - DOM_CHAL *srv_chal, int status) -{ - DEBUG(6,("make_lsa_r_req_chal: %d\n", __LINE__)); - memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data)); - r_c->status = status; -} - -static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, - DOM_CHAL *srv_chal) -{ - LSA_R_REQ_CHAL r_c; - - DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__)); - - /* set up the LSA REQUEST CHALLENGE response */ - make_lsa_r_req_chal(&r_c, srv_chal, 0); - - /* store the response in the SMB stream */ - q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0); - - DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__)); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - -static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a, - DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status) -{ - memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); - memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs)); - r_a->status = status; -} - -static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, - DOM_CHAL *resp_cred, int status) -{ - LSA_R_AUTH_2 r_a; - - /* set up the LSA AUTH 2 response */ - - make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status); - - /* store the response in the SMB stream */ - q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - -static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, - DOM_CRED *srv_cred, int status) -{ - memcpy(&(r_a->srv_cred), srv_cred, sizeof(r_a->srv_cred)); - r_a->status = status; -} - -static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, - DOM_CRED *srv_cred, int status) -{ - LSA_R_SRV_PWSET r_s; - - /* set up the LSA Server Password Set response */ - make_lsa_r_srv_pwset(&r_s, srv_cred, status); - - /* store the response in the SMB stream */ - q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - -static void make_lsa_user_info(LSA_USER_INFO *usr, - - NTTIME *logon_time, - NTTIME *logoff_time, - NTTIME *kickoff_time, - NTTIME *pass_last_set_time, - NTTIME *pass_can_change_time, - NTTIME *pass_must_change_time, - - char *user_name, - char *full_name, - char *logon_script, - char *profile_path, - char *home_dir, - char *dir_drive, - - uint16 logon_count, - uint16 bad_pw_count, - - uint32 user_id, - uint32 group_id, - uint32 num_groups, - DOM_GID *gids, - uint32 user_flgs, - - char sess_key[16], - - char *logon_srv, - char *logon_dom, - - char *dom_sid, - char *other_sids) /* space-delimited set of SIDs */ -{ - /* only cope with one "other" sid, right now. */ - /* need to count the number of space-delimited sids */ - int i; - int num_other_sids = other_sids != NULL ? 1 : 0; - - int len_user_name = strlen(user_name ); - int len_full_name = strlen(full_name ); - int len_logon_script = strlen(logon_script); - int len_profile_path = strlen(profile_path); - int len_home_dir = strlen(home_dir ); - int len_dir_drive = strlen(dir_drive ); - - int len_logon_srv = strlen(logon_srv); - int len_logon_dom = strlen(logon_dom); - - usr->undoc_buffer = 1; /* yes, we're bothering to put USER_INFO data here */ - - usr->logon_time = *logon_time; - usr->logoff_time = *logoff_time; - usr->kickoff_time = *kickoff_time; - usr->pass_last_set_time = *pass_last_set_time; - usr->pass_can_change_time = *pass_can_change_time; - usr->pass_must_change_time = *pass_must_change_time; - - make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 4); - make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4); - make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4); - make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4); - make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4); - make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4); - - usr->logon_count = logon_count; - usr->bad_pw_count = bad_pw_count; - - usr->user_id = user_id; - usr->group_id = group_id; - usr->num_groups = num_groups; - usr->buffer_groups = num_groups ? 1 : 0; /* yes, we're bothering to put group info in */ - usr->user_flgs = user_flgs; - - if (sess_key != NULL) - { - memcpy(usr->sess_key, sess_key, sizeof(usr->sess_key)); - } - else - { - bzero(usr->sess_key, sizeof(usr->sess_key)); - } - - make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4); - make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4); - - usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */ - - bzero(usr->padding, sizeof(usr->padding)); - - usr->num_other_sids = num_other_sids; - usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0; - - make_unistr2(&(usr->uni_user_name ), user_name , len_user_name , 0); - make_unistr2(&(usr->uni_full_name ), full_name , len_full_name , 0); - make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script, 0); - make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path, 0); - make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir , 0); - make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive , 0); - - usr->num_groups2 = num_groups; - for (i = 0; i < num_groups; i++) - { - usr->gids[i] = gids[i]; - } - - make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv, 0); - make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom, 0); - - make_dom_sid(&(usr->dom_sid), dom_sid); - make_dom_sid(&(usr->other_sids[0]), other_sids); -} - - -static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base, - DOM_CRED *srv_cred, LSA_USER_INFO *user_info) -{ - LSA_R_SAM_LOGON r_s; - - /* XXXX maybe we want to say 'no', reject the client's credentials */ - r_s.buffer_creds = 1; /* yes, we have valid server credentials */ - memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds)); - - /* store the user information, if there is any. */ - r_s.user = user_info; - r_s.buffer_user = user_info != NULL ? 1 : 0; - r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER); - - /* store the response in the SMB stream */ - q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - - -static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, - DOM_CRED *srv_cred, - uint32 status) -{ - LSA_R_SAM_LOGOFF r_s; - - /* XXXX maybe we want to say 'no', reject the client's credentials */ - r_s.buffer_creds = 1; /* yes, we have valid server credentials */ - memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds)); - - r_s.status = status; - - /* store the response in the SMB stream */ - q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0); - - /* return length of SMB data stored */ - return PTR_DIFF(q, base); -} - - -static void api_lsa_open_policy( char *param, char *data, - char **rdata, int *rdata_len ) -{ - /* we might actually want to decode the query, but it's not necessary */ - /* lsa_io_q_open_policy(...); */ - - /* return a 20 byte policy handle */ - *rdata_len = lsa_reply_open_policy(*rdata + 0x18, *rdata); -} - -static void api_lsa_query_info( char *param, char *data, - char **rdata, int *rdata_len ) -{ - LSA_Q_QUERY_INFO q_i; - pstring dom_name; - pstring dom_sid; - - /* grab the info class and policy handle */ - lsa_io_q_query(True, &q_i, data + 0x18, data, 4, 0); - - pstrcpy(dom_name, lp_workgroup()); - pstrcpy(dom_sid , lp_domainsid()); - - /* construct reply. return status is always 0x0 */ - *rdata_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata, - dom_name, dom_sid); -} - -static void api_lsa_lookup_sids( char *param, char *data, - char **rdata, int *rdata_len ) -{ - int i; - LSA_Q_LOOKUP_SIDS q_l; - pstring dom_name; - pstring dom_sid; - fstring dom_sids[MAX_LOOKUP_SIDS]; - - /* grab the info class and policy handle */ - lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data, 4, 0); - - pstrcpy(dom_name, lp_workgroup()); - pstrcpy(dom_sid , lp_domainsid()); - - /* convert received SIDs to strings, so we can do them. */ - for (i = 0; i < q_l.num_entries; i++) - { - fstrcpy(dom_sids[i], dom_sid_to_string(&(q_l.dom_sids[i]))); - } - - /* construct reply. return status is always 0x0 */ - *rdata_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata, - q_l.num_entries, dom_sids, /* text-converted SIDs */ - dom_name, dom_sid, /* domain name, domain SID */ - "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ -} - -static void api_lsa_lookup_names( char *param, char *data, - char **rdata, int *rdata_len ) -{ - int i; - LSA_Q_LOOKUP_RIDS q_l; - pstring dom_name; - pstring dom_sid; - uint32 dom_rids[MAX_LOOKUP_SIDS]; - - /* grab the info class and policy handle */ - lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data, 4, 0); - - pstrcpy(dom_name, lp_workgroup()); - pstrcpy(dom_sid , lp_domainsid()); - - /* convert received RIDs to strings, so we can do them. */ - for (i = 0; i < q_l.num_entries; i++) - { - char *user_name = unistr2(q_l.lookup_name[i].str.buffer); - dom_rids[i] = name_to_rid(user_name); - } - - /* construct reply. return status is always 0x0 */ - *rdata_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata, - q_l.num_entries, dom_rids, /* text-converted SIDs */ - dom_name, dom_sid, /* domain name, domain SID */ - "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ -} - -BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - uint16 opnum = SVAL(data,22); - - int pkttype = CVAL(data, 2); - if (pkttype == 0x0b) /* RPC BIND */ - { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } - - DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum)); - switch (opnum) - { - case LSA_OPENPOLICY: - { - DEBUG(3,("LSA_OPENPOLICY\n")); - api_lsa_open_policy(param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; - } - - case LSA_QUERYINFOPOLICY: - { - DEBUG(3,("LSA_QUERYINFOPOLICY\n")); - - api_lsa_query_info(param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; - } - - case LSA_ENUMTRUSTDOM: - { - char *q = *rdata + 0x18; - - DEBUG(3,("LSA_ENUMTRUSTDOM\n")); - - initrpcreply(data, *rdata); - - SIVAL(q, 0, 0); /* enumeration context */ - SIVAL(q, 0, 4); /* entries read */ - SIVAL(q, 0, 8); /* trust information */ - - endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len); - - break; - } - - case LSA_CLOSE: - { - char *q = *rdata + 0x18; - - DEBUG(3,("LSA_CLOSE\n")); - - initrpcreply(data, *rdata); - - SIVAL(q, 0, 0); - SIVAL(q, 0, 4); - SIVAL(q, 0, 8); - SIVAL(q, 0, 12); - SIVAL(q, 0, 16); - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - - break; - } - - case LSA_OPENSECRET: - { - char *q = *rdata + 0x18; - DEBUG(3,("LSA_OPENSECRET\n")); - - initrpcreply(data, *rdata); - - SIVAL(q, 0, 0); - SIVAL(q, 0, 4); - SIVAL(q, 0, 8); - SIVAL(q, 0, 12); - SIVAL(q, 0, 16); - - endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len); - - break; - } - - case LSA_LOOKUPSIDS: - { - DEBUG(3,("LSA_OPENSECRET\n")); - api_lsa_lookup_sids(param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; - } - - case LSA_LOOKUPNAMES: - { - DEBUG(3,("LSA_LOOKUPNAMES\n")); - api_lsa_lookup_names(param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; - } - - default: - { - DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum)); - break; - } - } - return True; -} - -static BOOL update_dcinfo(int cnum, uint16 vuid, - struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct) -{ - struct smb_passwd *smb_pass; - int i; - - unbecome_user(); - smb_pass = get_smbpwnam(mach_acct); - become_user(cnum, vuid); - - if (smb_pass != NULL) - { - memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw)); - DEBUG(5,("dc->md4pw(%d) :", sizeof(dc->md4pw))); - dump_data(5, dc->md4pw, 16); - } - else - { - /* No such machine account. Should error out here, but we'll - print and carry on */ - DEBUG(1,("No account in domain for %s\n", mach_acct)); - return False; - } - - { - char foo[16]; - for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", dc->md4pw[i]); - DEBUG(4,("pass %s %s\n", mach_acct, foo)); - } - - /* copy the client credentials */ - memcpy(dc->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); - memcpy(dc->clnt_cred.data, clnt_chal->data, sizeof(clnt_chal->data)); - - /* create a server challenge for the client */ - /* PAXX: set these to random values. */ - /* lkcl: paul, you mentioned that it doesn't really matter much */ - for (i = 0; i < 8; i++) - { - dc->srv_chal.data[i] = 0xA5; - } - - /* from client / server challenges and md4 password, generate sess key */ - cred_session_key(&(dc->clnt_chal), &(dc->srv_chal), - dc->md4pw, dc->sess_key); - - DEBUG(6,("update_dcinfo: %d\n", __LINE__)); - - return True; -} - -static void api_lsa_req_chal( int cnum, uint16 vuid, - user_struct *vuser, - char *param, char *data, - char **rdata, int *rdata_len ) -{ - LSA_Q_REQ_CHAL q_r; - - fstring mach_acct; - - /* grab the challenge... */ - lsa_io_q_req_chal(True, &q_r, data + 0x18, data, 4, 0); - - fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer)); - - strcat(mach_acct, "$"); - - DEBUG(6,("q_r.clnt_chal.data(%d) :", sizeof(q_r.clnt_chal.data))); - dump_data(6, q_r.clnt_chal.data, 8); - - update_dcinfo(cnum, vuid, &(vuser->dc), &(q_r.clnt_chal), mach_acct); - - /* construct reply. return status is always 0x0 */ - *rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata, - &(vuser->dc.srv_chal)); - -} - -static void api_lsa_auth_2( user_struct *vuser, - char *param, char *data, - char **rdata, int *rdata_len ) -{ - LSA_Q_AUTH_2 q_a; - - DOM_CHAL srv_chal; - UTIME srv_time; - - srv_time.time = 0; - - /* grab the challenge... */ - lsa_io_q_auth_2(True, &q_a, data + 0x18, data, 4, 0); - - /* check that the client credentials are valid */ - cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key, - &(vuser->dc.srv_cred), srv_time); - - /* create server credentials for inclusion in the reply */ - cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), srv_time, &srv_chal); - - /* construct reply. */ - *rdata_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata, - &srv_chal, 0x0); -} - - -static BOOL deal_with_credentials(user_struct *vuser, - DOM_CRED *clnt_cred, DOM_CRED *srv_cred) -{ - UTIME new_clnt_time; - - /* doesn't matter that server time is 0 */ - srv_cred->timestamp.time = 0; - - /* check that the client credentials are valid */ - if (cred_assert(&(clnt_cred->challenge), vuser->dc.sess_key, - &(vuser->dc.srv_cred), clnt_cred->timestamp)) - { - return False; - } - - /* increment client time by one second */ - new_clnt_time.time = clnt_cred->timestamp.time + 1; - - /* create server credentials for inclusion in the reply */ - cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time, - &(srv_cred->challenge)); - - /* update the client and server credentials, for use next time... */ - *(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time ); - - return True; -} - -static void api_lsa_srv_pwset( user_struct *vuser, - char *param, char *data, - char **rdata, int *rdata_len ) -{ - LSA_Q_SRV_PWSET q_a; - - DOM_CRED srv_cred; - - /* grab the challenge and encrypted password ... */ - lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data, 4, 0); - - /* checks and updates credentials. creates reply credentials */ - deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred); - - /* construct reply. always indicate failure. nt keeps going... */ - *rdata_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata, - &srv_cred, - NT_STATUS_WRONG_PASSWORD|0xC000000); -} - - -static void api_lsa_sam_logoff( user_struct *vuser, - char *param, char *data, - char **rdata, int *rdata_len ) -{ - LSA_Q_SAM_LOGOFF q_l; - - DOM_CRED srv_cred; - - /* grab the challenge... */ - lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data, 4, 0); - - /* checks and updates credentials. creates reply credentials */ - deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred); - - /* construct reply. always indicate success */ - *rdata_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata, - &srv_cred, - 0x0); -} - - -static void api_lsa_sam_logon( user_struct *vuser, - char *param, char *data, - char **rdata, int *rdata_len ) -{ - LSA_Q_SAM_LOGON q_l; - LSA_USER_INFO usr_info; - LSA_USER_INFO *p_usr_info = NULL; - - DOM_CRED srv_creds; - - lsa_io_q_sam_logon(True, &q_l, data + 0x18, data, 4, 0); - - /* checks and updates credentials. creates reply credentials */ - deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds); - - if (vuser != NULL) - { - NTTIME dummy_time; - pstring logon_script; - pstring profile_path; - pstring home_dir; - pstring home_drive; - pstring my_name; - pstring my_workgroup; - pstring dom_sid; - pstring username; - extern pstring myname; - - dummy_time.low = 0xffffffff; - dummy_time.high = 0x7fffffff; - - get_myname(myname, NULL); - - pstrcpy(logon_script, lp_logon_script()); - pstrcpy(profile_path, lp_logon_path ()); - pstrcpy(dom_sid , lp_domainsid ()); - pstrcpy(my_workgroup, lp_workgroup ()); - - pstrcpy(username, unistr2(q_l.sam_id.client.login.uni_acct_name.buffer)); - pstrcpy(my_name , myname ); - strupper(my_name); - - pstrcpy(home_drive , "a:" ); - -#if (defined(NETGROUP) && defined(AUTOMOUNT)) - pstrcpy(home_dir , vuser->home_share); -#else - pstrcpy(home_dir , "\\\\%L\\%U"); - standard_sub_basic(home_dir); -#endif - - p_usr_info = &usr_info; - - make_lsa_user_info(p_usr_info, - - &dummy_time, /* logon_time */ - &dummy_time, /* logoff_time */ - &dummy_time, /* kickoff_time */ - &dummy_time, /* pass_last_set_time */ - &dummy_time, /* pass_can_change_time */ - &dummy_time, /* pass_must_change_time */ - - username, /* user_name */ - vuser->real_name, /* full_name */ - logon_script, /* logon_script */ - profile_path, /* profile_path */ - home_dir, /* home_dir */ - home_drive, /* dir_drive */ - - 0, /* logon_count */ - 0, /* bad_pw_count */ - - vuser->uid, /* uint32 user_id */ - vuser->gid, /* uint32 group_id */ - 0, /* uint32 num_groups */ - NULL, /* DOM_GID *gids */ - 0x20, /* uint32 user_flgs */ - - NULL, /* char sess_key[16] */ - - my_name, /* char *logon_srv */ - my_workgroup, /* char *logon_dom */ - - dom_sid, /* char *dom_sid */ - NULL); /* char *other_sids */ - } - - *rdata_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata, - &srv_creds, p_usr_info); -} - - -BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - uint16 opnum = SVAL(data,22); - int pkttype = CVAL(data, 2); - - user_struct *vuser; - - if (pkttype == 0x0b) /* RPC BIND */ - { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } - - DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); - - if ((vuser = get_valid_user_struct(uid)) == NULL) return False; - - DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); -#if defined(NETGROUP) && defined(AUTOMOUNT) - DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share)); -#endif - - switch (opnum) - { - case LSA_REQCHAL: - { - DEBUG(3,("LSA_REQCHAL\n")); - api_lsa_req_chal(cnum, uid, vuser, param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; - } - - case LSA_AUTH2: - { - DEBUG(3,("LSA_AUTH2\n")); - api_lsa_auth_2(vuser, param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; - } - - case LSA_SRVPWSET: - { - DEBUG(3,("LSA_SRVPWSET\n")); - api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; - } - - case LSA_SAMLOGON: - { - DEBUG(3,("LSA_SAMLOGON\n")); - api_lsa_sam_logon(vuser, param, data, rdata, rdata_len); - make_rpc_reply(data, *rdata, *rdata_len); - break; - } - - case LSA_SAMLOGOFF: - { - DEBUG(3,("LSA_SAMLOGOFF\n")); - api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len); - break; - } - - default: - { - DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); - break; - } - } - - return True; -} - -#endif /* NTDOMAIN */ -- cgit From df4afea583a8b53aca46e15dcc75bba1af731f9f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 15 Oct 1997 16:51:03 +0000 Subject: added srvsvc basic pipe, straight from paul's code. does NETSHAREENUM and NETSERVERGETINFO. (This used to be commit 96b17b829fc787c15cd366eca604c09d68b5b900) --- source3/smbd/pipes.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 91ca69c022..bf53fa84bc 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -55,6 +55,7 @@ char * known_pipes [] = "lsarpc", #if NTDOMAIN "NETLOGON", + "srvsvc", #endif NULL }; @@ -362,3 +363,84 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, } return(True); } + +BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + uint16 opnum; + char *q; + int pkttype; + extern pstring myname; + char *servername; + uint32 level; + + opnum = SVAL(data,22); + + pkttype = CVAL(data, 2); + if (pkttype == 0x0b) /* RPC BIND */ + { + DEBUG(4,("srvsvc rpc bind %x\n",pkttype)); + LsarpcTNP1(data,rdata,rdata_len); + return True; + } + + DEBUG(4,("srvsvc TransactNamedPipe op %x\n",opnum)); + initrpcreply(data, *rdata); + DEBUG(4,("srvsvc LINE %d\n",__LINE__)); + get_myname(myname,NULL); + switch (opnum) + { + case NETSHAREENUM: + q = data + 0x18; + servername = q + 16; + q = skip_unicode_string(servername,1); + if (strlen(unistr(servername)) % 2 == 0) + q += 2; + level = IVAL(q, 0); q += 4; + /* ignore the rest for the moment */ + q = *rdata + 0x18; + SIVAL(q, 0, level); q += 4; + SIVAL(q, 0, 1); q += 4; /* switch value */ + SIVAL(q, 0, 2); q += 4; + SIVAL(q, 0, 2); q += 4; /* number of entries */ + SIVAL(q, 0, 2); q += 4; + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + case NETSERVERGETINFO: + { + UNISTR2 uni_str; + q = data + 0x18; + servername = q + 16; + q = skip_unicode_string(servername,1); + if (strlen(unistr(servername)) % 2 == 0) + q += 2; + level = IVAL(q, 0); q += 4; + /* ignore the rest for the moment */ + q = *rdata + 0x18; + SIVAL(q, 0, 101); q += 4; /* switch value */ + SIVAL(q, 0, 2); q += 4; /* bufptr */ + SIVAL(q, 0, 0x1f4); q += 4; /* platform id */ + SIVAL(q, 0, 2); q += 4; /* bufptr for name */ + SIVAL(q, 0, 5); q += 4; /* major version */ + SIVAL(q, 0, 4); q += 4; /* minor version == 5.4 */ + SIVAL(q, 0, 0x4100B); q += 4; /* type */ + SIVAL(q, 0, 2); q += 4; /* comment */ + make_unistr2(&uni_str, myname, strlen(myname)); + q = smb_io_unistr2(False, &uni_str, q, *rdata, 4, 0); + + make_unistr2(&uni_str, lp_serverstring(), strlen(lp_serverstring())); + q = smb_io_unistr2(False, &uni_str, q, *rdata, 4, 0); + + q = align_offset(q, *rdata, 4); + + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + } + default: + DEBUG(4, ("srvsvc, unknown code: %lx\n", opnum)); + } + return(True); +} + -- cgit From 359d42c08d012b3e1c1bc6ac1071f8add706ba35 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Oct 1997 21:53:59 +0000 Subject: ipc.c: Adding Andrews become_root code to the main branch. locking.c: Adding Andrews become_root code to the main branch. pipes.c: Fixing the close_file issue. proto.h: The usual. reply.c: Move smb_pass into NTDOMAIN defined code. Fixing the close_file issue. server.c: Fixing the close_file issue. trans2.c: Fixing the close_file issue. uid.c: Adding Andrews become_root code to the main branch. Jeremy (jallison@whistle.com) (This used to be commit 16fd4337f79ce33f91050c96c4a566221c5d9126) --- source3/smbd/pipes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index bf53fa84bc..8c7e6c69c5 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -147,7 +147,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) } if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { - close_file(fnum); + close_file(fnum,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -155,7 +155,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) fmode = dos_mode(cnum,fname,&sbuf); mtime = sbuf.st_mtime; if (fmode & aDIR) { - close_file(fnum); + close_file(fnum,False); return(ERROR(ERRDOS,ERRnoaccess)); } -- cgit From 30ed3b5c77505a835eea9e8d2ff9c6df4395b11e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 19 Oct 1997 12:24:23 +0000 Subject: pipes.c pipesrvsvc.c : moved stub srvsvc pipe function into separate file, in preparation for further work. (This used to be commit 2f2d18cc9474e1b40765a67242659be7c63a9936) --- source3/smbd/pipes.c | 80 ---------------------------------------------------- 1 file changed, 80 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 8c7e6c69c5..12e54d2bca 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -364,83 +364,3 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, return(True); } -BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - uint16 opnum; - char *q; - int pkttype; - extern pstring myname; - char *servername; - uint32 level; - - opnum = SVAL(data,22); - - pkttype = CVAL(data, 2); - if (pkttype == 0x0b) /* RPC BIND */ - { - DEBUG(4,("srvsvc rpc bind %x\n",pkttype)); - LsarpcTNP1(data,rdata,rdata_len); - return True; - } - - DEBUG(4,("srvsvc TransactNamedPipe op %x\n",opnum)); - initrpcreply(data, *rdata); - DEBUG(4,("srvsvc LINE %d\n",__LINE__)); - get_myname(myname,NULL); - switch (opnum) - { - case NETSHAREENUM: - q = data + 0x18; - servername = q + 16; - q = skip_unicode_string(servername,1); - if (strlen(unistr(servername)) % 2 == 0) - q += 2; - level = IVAL(q, 0); q += 4; - /* ignore the rest for the moment */ - q = *rdata + 0x18; - SIVAL(q, 0, level); q += 4; - SIVAL(q, 0, 1); q += 4; /* switch value */ - SIVAL(q, 0, 2); q += 4; - SIVAL(q, 0, 2); q += 4; /* number of entries */ - SIVAL(q, 0, 2); q += 4; - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - case NETSERVERGETINFO: - { - UNISTR2 uni_str; - q = data + 0x18; - servername = q + 16; - q = skip_unicode_string(servername,1); - if (strlen(unistr(servername)) % 2 == 0) - q += 2; - level = IVAL(q, 0); q += 4; - /* ignore the rest for the moment */ - q = *rdata + 0x18; - SIVAL(q, 0, 101); q += 4; /* switch value */ - SIVAL(q, 0, 2); q += 4; /* bufptr */ - SIVAL(q, 0, 0x1f4); q += 4; /* platform id */ - SIVAL(q, 0, 2); q += 4; /* bufptr for name */ - SIVAL(q, 0, 5); q += 4; /* major version */ - SIVAL(q, 0, 4); q += 4; /* minor version == 5.4 */ - SIVAL(q, 0, 0x4100B); q += 4; /* type */ - SIVAL(q, 0, 2); q += 4; /* comment */ - make_unistr2(&uni_str, myname, strlen(myname)); - q = smb_io_unistr2(False, &uni_str, q, *rdata, 4, 0); - - make_unistr2(&uni_str, lp_serverstring(), strlen(lp_serverstring())); - q = smb_io_unistr2(False, &uni_str, q, *rdata, 4, 0); - - q = align_offset(q, *rdata, 4); - - endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); - break; - } - default: - DEBUG(4, ("srvsvc, unknown code: %lx\n", opnum)); - } - return(True); -} - -- cgit From fe0a702322bdf3c76a517e2fd7e92a05219c49dd Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 29 Oct 1997 00:04:14 +0000 Subject: byteorder.h : added mode for printing debug array data as chars not uint8/16/32s. only really useful for (uint8) strings or (uint16) unicode strings lsaparse.c smbparse.c smb.h : rpc bind and rpc bind ack structures and parsing and creation functions. ipc.c pipes.c pipenetlog.c pipentlsa.c pipesrvsvc.c : using rpc bind / bind ack parsing routines instead of incorrect use of api_LsarpcTNP1 function. ntclient.c : creation of do_rpc_bind() function. THAT'S IT, FOLKS! (This used to be commit 21c89e2f17c51939fd6b53dddbe3072419eb0db2) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 12e54d2bca..901d7e682a 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -216,7 +216,7 @@ BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data, TransactNamedPipe on \PIPE\lsarpc. ****************************************************************************/ -void LsarpcTNP1(char *data,char **rdata, int *rdata_len) +static void LsarpcTNP1(char *data,char **rdata, int *rdata_len) { uint32 dword1, dword2; char pname[] = "\\PIPE\\lsass"; -- cgit From a275e5d4e16142a9924f8b97980f364a80df3b64 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 30 Oct 1997 01:05:13 +0000 Subject: removed mechanism that created actual files NETLOGON, lsarpc and the like, which are pipes on the IPC$ connection. created mechanism to record pipe names in a separate pipes_struct. it is planned to expand this, to return sensible things like interface structures, and policy handles (RPC_IFACE and LSA_POL_HND). and the like. (This used to be commit 33cce5fac0e2f818a19a6c4e6a797ef44f3b5c75) --- source3/smbd/pipes.c | 171 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 71 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 901d7e682a..990b25cb0a 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -37,18 +37,34 @@ /* look in server.c for some explanation of these variables */ extern int Protocol; extern int DEBUGLEVEL; -extern int chain_fnum; extern char magic_char; -extern connection_struct Connections[]; -extern files_struct Files[]; +static int chain_pnum = -1; extern BOOL case_sensitive; extern pstring sesssetup_user; extern int Client; extern fstring myworkgroup; -/* this macro should always be used to extract an fnum (smb_fid) from -a packet to ensure chaining works correctly */ -#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where)) +#ifndef MAX_OPEN_PIPES +#define MAX_OPEN_PIPES 50 +#endif + +static struct +{ + int cnum; + BOOL open; + fstring name; + +} Pipes[MAX_OPEN_PIPES]; + +#define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES)) +#define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open) +#define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum) + +#define CHECK_PNUM(pnum,c) if (!PNUM_OK(pnum,c)) \ + return(ERROR(ERRDOS,ERRbadfid)) +/* this macro should always be used to extract an pnum (smb_fid) from + a packet to ensure chaining works correctly */ +#define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where)) char * known_pipes [] = { @@ -61,13 +77,50 @@ char * known_pipes [] = }; /**************************************************************************** - reply to an open and X on a named pipe + find first available file slot +****************************************************************************/ +static int find_free_pipe(void ) +{ + int i; + /* we start at 1 here for an obscure reason I can't now remember, + but I think is important :-) */ + for (i = 1; i < MAX_OPEN_PIPES; i++) + if (!Pipes[i].open) + return(i); - In fact what we do is to open a regular file with the same name in - /tmp. This can then be closed as normal. Reading and writing won't - make much sense, but will do *something*. The real reason for this - support is to be able to do transactions on them (well, on lsarpc - for domain login purposes...). + DEBUG(1,("ERROR! Out of pipe structures - perhaps increase MAX_OPEN_PIPES?\n")); + + return(-1); +} + +/**************************************************************************** + gets the name of a pipe +****************************************************************************/ +char *get_pipe_name(int pnum) +{ + DEBUG(6,("get_pipe_name: ")); + + if (VALID_PNUM(pnum - 0x800)) + { + DEBUG(6,("name: %s cnum: %d open: %s ", + Pipes[pnum - 0x800].name, + Pipes[pnum - 0x800].cnum, + BOOLSTR(Pipes[pnum - 0x800].open))); + } + if (OPEN_PNUM(pnum - 0x800)) + { + DEBUG(6,("OK\n")); + return Pipes[pnum - 0x800].name; + } + else + { + DEBUG(6,("NOT\n")); + return NULL; + } +} + +/**************************************************************************** + reply to an open and X on a named pipe This code is basically stolen from reply_open_and_X with some wrinkles to handle pipes. @@ -76,21 +129,10 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; int cnum = SVAL(inbuf,smb_tid); - int fnum = -1; - int smb_mode = SVAL(inbuf,smb_vwv3); - int smb_attr = SVAL(inbuf,smb_vwv5); -#if 0 - int open_flags = SVAL(inbuf,smb_vwv2); - int smb_sattr = SVAL(inbuf,smb_vwv4); - uint32 smb_time = make_unix_date3(inbuf+smb_vwv6); -#endif + int pnum = -1; int smb_ofun = SVAL(inbuf,smb_vwv8); - int unixmode; int size=0,fmode=0,mtime=0,rmode=0; - struct stat sbuf; - int smb_action = 0; int i; - BOOL bad_path = False; /* XXXX we need to handle passed times, sattr and flags */ pstrcpy(fname,smb_buf(inbuf)); @@ -117,79 +159,66 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* 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_attr &= ~aDIR; - Connections[cnum].read_only = 0; smb_ofun |= 0x10; /* Add Create it not exists flag */ - unix_convert(fname,cnum,0,&bad_path); - - fnum = find_free_file(); - if (fnum < 0) - return(ERROR(ERRSRV,ERRnofids)); - - if (!check_name(fname,cnum)) - return(UNIXERROR(ERRDOS,ERRnoaccess)); - - unixmode = unix_mode(cnum,smb_attr); - - open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode, - 0, &rmode,&smb_action); - - if (!Files[fnum].open) - { - /* Change the error code if bad_path was set. */ - if((errno == ENOENT) && bad_path) - { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadpath; - } - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - - if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { - close_file(fnum,False); - return(ERROR(ERRDOS,ERRnoaccess)); - } + pnum = find_free_pipe(); + if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); - size = sbuf.st_size; - fmode = dos_mode(cnum,fname,&sbuf); - mtime = sbuf.st_mtime; - if (fmode & aDIR) { - close_file(fnum,False); - return(ERROR(ERRDOS,ERRnoaccess)); - } + Pipes[pnum].open = True; + Pipes[pnum].cnum = cnum; + fstrcpy(Pipes[pnum].name, fname); /* Prepare the reply */ set_message(outbuf,15,0,True); - /* Put things back the way they were. */ - Connections[cnum].read_only = 1; - /* Mark the opened file as an existing named pipe in message mode. */ SSVAL(outbuf,smb_vwv9,2); SSVAL(outbuf,smb_vwv10,0xc700); + if (rmode == 2) { DEBUG(4,("Resetting open result to open from create.\n")); rmode = 1; } - SSVAL(outbuf,smb_vwv2,fnum); + SSVAL(outbuf,smb_vwv2, pnum + 0x800); /* mark file handle up into high range */ SSVAL(outbuf,smb_vwv3,fmode); put_dos_date3(outbuf,smb_vwv4,mtime); SIVAL(outbuf,smb_vwv6,size); SSVAL(outbuf,smb_vwv8,rmode); - SSVAL(outbuf,smb_vwv11,smb_action); - - chain_fnum = fnum; + SSVAL(outbuf,smb_vwv11,0); - DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n", - fname, fnum, Files[fnum].name)); + DEBUG(4,("Opened pipe %s with handle %x name %s.\n", + fname, pnum + 0x800, Pipes[pnum].name)); + chain_pnum = pnum; + return chain_reply(inbuf,outbuf,length,bufsize); } +/**************************************************************************** + reply to a close +****************************************************************************/ +int reply_pipe_close(char *inbuf,char *outbuf) +{ + int pnum = GETPNUM(inbuf,smb_vwv0); + int cnum = SVAL(inbuf,smb_tid); + int outsize = set_message(outbuf,0,0,True); + + /* mapping is 0x800 up... */ + + CHECK_PNUM(pnum-0x800,cnum); + + DEBUG(3,("%s Closed pipe name %s pnum=%d cnum=%d\n", + timestring(),Pipes[pnum-0x800].name, pnum,cnum)); + + Pipes[pnum-0x800].open = False; + + return(outsize); +} + + /**************************************************************************** api_LsarpcSNPHS -- cgit From 739a730637b8320dce85c12686a4d4647990824d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 30 Oct 1997 17:08:42 +0000 Subject: Makefile: simply adding pipes.o to SMBDOBJ3. rpc_pipes/pipe_hnd.c : created pipe handles module. pipes.c server.c : use of pipe_hnd functions in SMBopenX and SMBclose, on the IPC$ pipe. (This used to be commit ada256b5e3b9fb0db988e3be7d47943e7c19b3fb) --- source3/smbd/pipes.c | 80 ++-------------------------------------------------- 1 file changed, 3 insertions(+), 77 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 990b25cb0a..ff93041fbc 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -38,30 +38,15 @@ extern int Protocol; extern int DEBUGLEVEL; extern char magic_char; -static int chain_pnum = -1; extern BOOL case_sensitive; extern pstring sesssetup_user; extern int Client; extern fstring myworkgroup; -#ifndef MAX_OPEN_PIPES -#define MAX_OPEN_PIPES 50 -#endif - -static struct -{ - int cnum; - BOOL open; - fstring name; - -} Pipes[MAX_OPEN_PIPES]; - #define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES)) #define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open) #define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum) -#define CHECK_PNUM(pnum,c) if (!PNUM_OK(pnum,c)) \ - return(ERROR(ERRDOS,ERRbadfid)) /* this macro should always be used to extract an pnum (smb_fid) from a packet to ensure chaining works correctly */ #define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where)) @@ -76,49 +61,6 @@ char * known_pipes [] = NULL }; -/**************************************************************************** - find first available file slot -****************************************************************************/ -static int find_free_pipe(void ) -{ - int i; - /* we start at 1 here for an obscure reason I can't now remember, - but I think is important :-) */ - for (i = 1; i < MAX_OPEN_PIPES; i++) - if (!Pipes[i].open) - return(i); - - DEBUG(1,("ERROR! Out of pipe structures - perhaps increase MAX_OPEN_PIPES?\n")); - - return(-1); -} - -/**************************************************************************** - gets the name of a pipe -****************************************************************************/ -char *get_pipe_name(int pnum) -{ - DEBUG(6,("get_pipe_name: ")); - - if (VALID_PNUM(pnum - 0x800)) - { - DEBUG(6,("name: %s cnum: %d open: %s ", - Pipes[pnum - 0x800].name, - Pipes[pnum - 0x800].cnum, - BOOLSTR(Pipes[pnum - 0x800].open))); - } - if (OPEN_PNUM(pnum - 0x800)) - { - DEBUG(6,("OK\n")); - return Pipes[pnum - 0x800].name; - } - else - { - DEBUG(6,("NOT\n")); - return NULL; - } -} - /**************************************************************************** reply to an open and X on a named pipe @@ -161,13 +103,9 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(3,("Known pipe %s opening.\n",fname)); smb_ofun |= 0x10; /* Add Create it not exists flag */ - pnum = find_free_pipe(); + pnum = open_rpc_pipe_hnd(fname, cnum); if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); - Pipes[pnum].open = True; - Pipes[pnum].cnum = cnum; - fstrcpy(Pipes[pnum].name, fname); - /* Prepare the reply */ set_message(outbuf,15,0,True); @@ -188,11 +126,6 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) SSVAL(outbuf,smb_vwv8,rmode); SSVAL(outbuf,smb_vwv11,0); - DEBUG(4,("Opened pipe %s with handle %x name %s.\n", - fname, pnum + 0x800, Pipes[pnum].name)); - - chain_pnum = pnum; - return chain_reply(inbuf,outbuf,length,bufsize); } @@ -202,18 +135,11 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) ****************************************************************************/ int reply_pipe_close(char *inbuf,char *outbuf) { - int pnum = GETPNUM(inbuf,smb_vwv0); + int pnum = get_rpc_pipe_num(inbuf,smb_vwv0); int cnum = SVAL(inbuf,smb_tid); int outsize = set_message(outbuf,0,0,True); - /* mapping is 0x800 up... */ - - CHECK_PNUM(pnum-0x800,cnum); - - DEBUG(3,("%s Closed pipe name %s pnum=%d cnum=%d\n", - timestring(),Pipes[pnum-0x800].name, pnum,cnum)); - - Pipes[pnum-0x800].open = False; + if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid)); return(outsize); } -- cgit From 55e2dc7c6f4378adfdcbd166b2680096a3e4a5a4 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 30 Oct 1997 21:51:15 +0000 Subject: storing pipe name state (from set named pipe handle state call) in the pipes array. (This used to be commit 5335d5cdc4659f4676958f0399e2de29a117c133) --- source3/smbd/pipes.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index ff93041fbc..4a2e185cb4 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -148,21 +148,18 @@ int reply_pipe_close(char *inbuf,char *outbuf) /**************************************************************************** api_LsarpcSNPHS - SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here, - so just blithely return True. This is really only for NT domain stuff, - we we're only handling that - don't assume Samba now does complete - named pipe handling. + SetNamedPipeHandleState on \PIPE\lsarpc. ****************************************************************************/ -BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) +BOOL api_LsarpcSNPHS(int pnum, int cnum, char *param) { uint16 id; + if (!param) return False; + id = param[0] + (param[1] << 8); DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id)); - return(True); + + return set_rpc_pipe_hnd_state(pnum, cnum, id); } -- cgit From bd529d7a83c35be233baca09bc79aa911ad443ce Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 6 Nov 1997 23:03:58 +0000 Subject: following a cvs error, i am rewriting this monster-commit. with bad grace. Modified Files: --------------- Makefile: adding extra files ipc.c : send_trans_reply() - alignment issue. this makes the alignment the same as that in NT. this should be looked at by people who understand the SMB stuff better than i. api_fd_commands[] - added samr and wkssvc pipes. loadparm.c : lp_domain_controller() changed to mean "samba is a domain controller". it's a "yes/no" parameter, now. no, it isn't used _anywhere_. namedbwork.c nameelect.c : if "domain controller = yes" then add SV_TYPE_DOMAIN_CTRL to the host _and_ workgroup announcements. yes, you must do both: nt does. namelogon.c : important NETLOGON bug in SAMLOGON request parsing, which may be the source of some people's problems with logging on to the Samba PDC. password.c : get_smbpwnam() renamed to get_smbpwd_entry(). pipes.c : added samr and wkssvc pipes. proto.h : usual. can we actually _remove_ proto.h from the cvs tree, and have it as one of the Makefile dependencies, or something? reply.c : get_smbpwnam() renamed to get_smbpwd_entry() - also changed response error code when logging in from a WORKSTATION$ account. yes, paul is right: we need to know when to return the right error code, and why. server.c : added call to reset_chain_pnum(). #ifdef NTDOMAIN added call to init_lsa_policy_hnd() #endif. jeremy, you'd be proud: i did a compile without NTDOMAIN, and caught a link error for this function. smb.h : defines and structures for samr and wkssvc pipes. smbpass.c : modified get_smbpwnam() to get_smbpwd_entry() and it now takes two arguments. one for the name; if this is null, it looks up by smb_userid instead. oh, by the way, smb_userids are actually domain relative ids (RIDs). concatenate a RID with the domain SID, and you have an internet globally unique way of identifying a user. we're using RIDs in the wrong way.... added mod_smbpwnam() function. this was based on code in smbpasswd.c rpc_pipes/lsaparse.c : added enum trusted domain parsing. this is incomplete: i need a packet trace to write it properly. rpc_pipes/pipe_hnd.c : added reset_chain_pnum() function. rpc_pipes/pipenetlog.c : get_smbpwnam() function renamed to get_smbpwd_entry(). arcfour() issues. removed capability of get_md4pw() function to automatically add workstation accounts. this should either be done using smbpasswd -add MACHINE$, or by using \PIPE\samr. rpc_pipes/pipe_util.c : create_pol_hnd() - creates a unique LSA Policy Handle. overkill function: uses a 64 bit sequence number; current unix time and the smbd pid. rpc_pipes/smbparse.c : arcfour() issues. smb_io_unistr2() should advance by uni_str_len not uni_max_len. smb_io_smb_hdr_rb() - request bind uses uint16 for the context id, and uint8 for the num_syntaxes. oops, i put these both as uint32s. Added Files: ------------ rpc_pipes/lsa_hnd.c : on the samr pipe, allocate and associate an LSA Policy Handle with a SID. you receive queries with the LSA Policy Handle, and have to turn this back into a SID in order to answer the query... rpc_pipes/pipesamr.c rpc_pipes/samrparse.c \PIPE\samr processing. samr i presume is the SAM Replication pipe. rpc_pipes/pipewkssvc.c rpc_pipes/wksparse.c \PIPE\wkssvc processing. the Workstation Service pipe? holy cow. (This used to be commit 1bd084b3e690eb26a1006d616075e53d711ecd2f) --- source3/smbd/pipes.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 4a2e185cb4..e2f704e6af 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -57,6 +57,8 @@ char * known_pipes [] = #if NTDOMAIN "NETLOGON", "srvsvc", + "wkssvc", + "samr", #endif NULL }; @@ -139,6 +141,8 @@ int reply_pipe_close(char *inbuf,char *outbuf) 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); -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/smbd/pipes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index e2f704e6af..b5f9700f33 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -2,9 +2,9 @@ Unix SMB/Netbios implementation. Version 1.9. Pipe SMB reply routines - Copyright (C) Andrew Tridgell 1992-1997, - Copyright (C) Luke Kenneth Casson Leighton 1996-1997. - Copyright (C) Paul Ashton 1997. + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Luke Kenneth Casson Leighton 1996-1998 + Copyright (C) Paul Ashton 1997-1998. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From fdeea341ed1bae670382e45eb731db1b5838ad21 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Mar 1998 21:11:04 +0000 Subject: "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) --- source3/smbd/pipes.c | 242 ++++++++++++--------------------------------------- 1 file changed, 54 insertions(+), 188 deletions(-) (limited to 'source3/smbd/pipes.c') 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); } -- cgit From e7ac86607c80912e55ac7179b100cea22749c16f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 25 Apr 1998 01:12:08 +0000 Subject: This looks like a big change but really isn't. It is changing the global variables "myname" and "myworkgroup" to "global_myname" and "global_myworkgroup" respectively. This is to make it very explicit when we are messing with a global (don't ask - it makes the domain client code much clearer :-). Jeremy. (This used to be commit 866406bfe399cf757c8275093dacd5ce4843afa0) --- source3/smbd/pipes.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 4d425cc2c0..fa11060ade 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -41,7 +41,6 @@ extern char magic_char; extern BOOL case_sensitive; extern pstring sesssetup_user; extern int Client; -extern fstring myworkgroup; #define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES)) #define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open) -- cgit From dc44d77c7fd3427b1313e8ee2d7929fb7778148f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 1998 22:46:06 +0000 Subject: Makefile: Added nttrans.o includes.h: Added termios.h for AIX. nttrans.c: Working NT SMB calls ! pipes.c: Use strequal instead of strcmp. server.c: Use #defines rather than numbers. smb.h: Updated NT SMB #defines. Jeremy. (This used to be commit 3e5cada9885059e9926eb6a56d350c4b1b53d245) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index fa11060ade..f0c5c3ba7f 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -81,7 +81,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* See if it is one we want to handle. */ for( i = 0; pipe_names[i].client_pipe ; i++ ) - if( strcmp(fname,pipe_names[i].client_pipe) == 0 ) + if( strequal(fname,pipe_names[i].client_pipe) ) break; if ( pipe_names[i].client_pipe == NULL ) -- cgit From 28900ea26ff1c8d41328bba30206db7fe91e2184 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 31 Jul 1998 22:39:15 +0000 Subject: As per a Andrew's message, I went through and removed the timestring() timestamps from several DEBUG messages. The timestamps are redundant now that DEBUG() provides them automatically. There are still a few more files to do, but I've got to get home for dinner. Chris -)----- (This used to be commit 60286ccecaa6028d687e6406755016455e3b3a26) --- source3/smbd/pipes.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index f0c5c3ba7f..34884aa6d3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -161,9 +161,8 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) 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)); + DEBUG( 3, ( "readX pnum=%04x cnum=%d min=%d max=%d nread=%d\n", + pnum, cnum, smb_mincnt, smb_maxcnt, nread ) ); set_chain_pnum(pnum); -- cgit From b9623ab59e813131b1ed3f51616a46e719d59c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Aug 1998 17:38:29 +0000 Subject: this is the bug change to using connection_struct* instead of cnum. Connections[] is now a local array in server.c I might have broken something with this change. In particular the oplock code is suspect and some .dll files aren't being oplocked when I expected them to be. I'll look at it after I've got some sleep. (This used to be commit c7ee025ead4a85b6fa44a832047b878451845fb6) --- source3/smbd/pipes.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 34884aa6d3..2a51e83946 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -58,10 +58,10 @@ extern struct pipe_id_info pipe_names[]; This code is basically stolen from reply_open_and_X with some wrinkles to handle pipes. ****************************************************************************/ -int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) +int reply_open_pipe_and_X(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; - uint16 cnum = SVAL(inbuf, smb_tid); uint16 vuid = SVAL(inbuf, smb_uid); int pnum = -1; int smb_ofun = SVAL(inbuf,smb_vwv8); @@ -95,7 +95,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(3,("Known pipe %s opening.\n",fname)); smb_ofun |= 0x10; /* Add Create it not exists flag */ - pnum = open_rpc_pipe_hnd(fname, cnum, vuid); + pnum = open_rpc_pipe_hnd(fname, conn, vuid); if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); /* Prepare the reply */ @@ -134,13 +134,10 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) 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; - cnum = SVAL(inbuf,smb_tid); - /* CHECK_FNUM(fnum,cnum); CHECK_READ(fnum); @@ -161,8 +158,8 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); SSVAL(smb_buf(outbuf),-2,nread); - DEBUG( 3, ( "readX pnum=%04x cnum=%d min=%d max=%d nread=%d\n", - pnum, cnum, smb_mincnt, smb_maxcnt, nread ) ); + DEBUG(3,("readX pnum=%04x min=%d max=%d nread=%d\n", + pnum, smb_mincnt, smb_maxcnt, nread)); set_chain_pnum(pnum); @@ -171,15 +168,14 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** reply to a close ****************************************************************************/ -int reply_pipe_close(char *inbuf,char *outbuf) +int reply_pipe_close(connection_struct *conn, 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)); + DEBUG(5,("reply_pipe_close: pnum:%x\n", pnum)); - if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid)); + if (!close_rpc_pipe_hnd(pnum, conn)) return(ERROR(ERRDOS,ERRbadfid)); return(outsize); } -- cgit From 127655cc888ac40332d4e8e5b94aab03f5120aae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Aug 1998 07:27:34 +0000 Subject: this checkin gets rid of the global Files[] array and makes it local in files.c it should now be faily easy to expand the default MAX_OPEN_FILES to many thousands. (This used to be commit b088c804f98908eb02f05ab2f2e8a61691a0a582) --- source3/smbd/pipes.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2a51e83946..9ec77c08ca 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -44,7 +44,6 @@ extern int Client; #define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES)) #define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open) -#define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum) /* this macro should always be used to extract an pnum (smb_fid) from a packet to ensure chaining works correctly */ @@ -84,7 +83,7 @@ int reply_open_pipe_and_X(connection_struct *conn, if( strequal(fname,pipe_names[i].client_pipe) ) break; - if ( pipe_names[i].client_pipe == NULL ) + if (pipe_names[i].client_pipe == NULL) return(ERROR(ERRSRV,ERRaccess)); /* Strip \PIPE\ off the name. */ @@ -111,7 +110,9 @@ int reply_open_pipe_and_X(connection_struct *conn, rmode = 1; } - SSVAL(outbuf,smb_vwv2, pnum + 0x800); /* mark file handle up into high range */ + SSVAL(outbuf,smb_vwv2, pnum + PIPE_HANDLE_OFFSET); /* mark file + handle up into + high range */ SSVAL(outbuf,smb_vwv3,fmode); put_dos_date3(outbuf,smb_vwv4,mtime); SIVAL(outbuf,smb_vwv6,size); @@ -138,12 +139,6 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) char *data; BOOL ok = False; -/* - CHECK_FNUM(fnum,cnum); - CHECK_READ(fnum); - CHECK_ERROR(fnum); -*/ - set_message(outbuf,12,0,True); data = smb_buf(outbuf); -- cgit From f2d538a105a61ce6d2852700fc328e15ac158827 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 03:06:20 +0000 Subject: some cleanups from the conversion of Pipes[] to a linked list. I also removed most cases where a pnum is used and substituted a pipes_struct*. in files.c I added a offset of 0x1000 to all file handles on the wire. This makes it much less likely that bad parsing will give us the wrong field. (This used to be commit 8bc2627ff28d340db65bfa017daca2dc291d5ef7) --- source3/smbd/pipes.c | 182 +++++++++++++++++++++++---------------------------- 1 file changed, 82 insertions(+), 100 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 9ec77c08ca..84e31894a3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -32,22 +32,7 @@ #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) -#define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024)) - -/* look in server.c for some explanation of these variables */ -extern int Protocol; extern int DEBUGLEVEL; -extern char magic_char; -extern BOOL case_sensitive; -extern pstring sesssetup_user; -extern int Client; - -#define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES)) -#define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open) - -/* this macro should always be used to extract an pnum (smb_fid) from - a packet to ensure chaining works correctly */ -#define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where)) extern struct pipe_id_info pipe_names[]; @@ -60,66 +45,63 @@ extern struct pipe_id_info pipe_names[]; int reply_open_pipe_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - pstring fname; - 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; - int i; - - /* XXXX we need to handle passed times, sattr and flags */ - pstrcpy(fname,smb_buf(inbuf)); - - /* If the name doesn't start \PIPE\ then this is directed */ - /* at a mailslot or something we really, really don't understand, */ - /* not just something we really don't understand. */ - if ( strncmp(fname,PIPE,PIPELEN) != 0 ) - return(ERROR(ERRSRV,ERRaccess)); - - DEBUG(4,("Opening pipe %s.\n", fname)); - - /* See if it is one we want to handle. */ - for( i = 0; pipe_names[i].client_pipe ; i++ ) - if( strequal(fname,pipe_names[i].client_pipe) ) - break; - - 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, conn, vuid); - if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); - - /* Prepare the reply */ - set_message(outbuf,15,0,True); - - /* Mark the opened file as an existing named pipe in message mode. */ - SSVAL(outbuf,smb_vwv9,2); - SSVAL(outbuf,smb_vwv10,0xc700); - - if (rmode == 2) - { - DEBUG(4,("Resetting open result to open from create.\n")); - rmode = 1; - } - - SSVAL(outbuf,smb_vwv2, pnum + PIPE_HANDLE_OFFSET); /* mark file - handle up into - high range */ - SSVAL(outbuf,smb_vwv3,fmode); - put_dos_date3(outbuf,smb_vwv4,mtime); - SIVAL(outbuf,smb_vwv6,size); - SSVAL(outbuf,smb_vwv8,rmode); - SSVAL(outbuf,smb_vwv11,0); - - return chain_reply(inbuf,outbuf,length,bufsize); + pstring fname; + uint16 vuid = SVAL(inbuf, smb_uid); + pipes_struct *p; + int smb_ofun = SVAL(inbuf,smb_vwv8); + int size=0,fmode=0,mtime=0,rmode=0; + int i; + + /* XXXX we need to handle passed times, sattr and flags */ + pstrcpy(fname,smb_buf(inbuf)); + + /* If the name doesn't start \PIPE\ then this is directed */ + /* at a mailslot or something we really, really don't understand, */ + /* not just something we really don't understand. */ + if ( strncmp(fname,PIPE,PIPELEN) != 0 ) + return(ERROR(ERRSRV,ERRaccess)); + + DEBUG(4,("Opening pipe %s.\n", fname)); + + /* See if it is one we want to handle. */ + for( i = 0; pipe_names[i].client_pipe ; i++ ) + if( strequal(fname,pipe_names[i].client_pipe) ) + break; + + 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 */ + + p = open_rpc_pipe_p(fname, conn, vuid); + if (!p) return(ERROR(ERRSRV,ERRnofids)); + + /* Prepare the reply */ + set_message(outbuf,15,0,True); + + /* Mark the opened file as an existing named pipe in message mode. */ + SSVAL(outbuf,smb_vwv9,2); + SSVAL(outbuf,smb_vwv10,0xc700); + + if (rmode == 2) { + DEBUG(4,("Resetting open result to open from create.\n")); + rmode = 1; + } + + SSVAL(outbuf,smb_vwv2, p->pnum); + SSVAL(outbuf,smb_vwv3,fmode); + put_dos_date3(outbuf,smb_vwv4,mtime); + SIVAL(outbuf,smb_vwv6,size); + SSVAL(outbuf,smb_vwv8,rmode); + SSVAL(outbuf,smb_vwv11,0); + + return chain_reply(inbuf,outbuf,length,bufsize); } @@ -131,47 +113,47 @@ int reply_open_pipe_and_X(connection_struct *conn, ****************************************************************************/ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) { - 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 nread = -1; - char *data; - BOOL ok = False; + pipes_struct *p = get_rpc_pipe_p(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 nread = -1; + char *data; + BOOL ok = False; - set_message(outbuf,12,0,True); - data = smb_buf(outbuf); + set_message(outbuf,12,0,True); + data = smb_buf(outbuf); - nread = read_pipe(pnum, data, smb_offs, smb_maxcnt); + nread = read_pipe(p, data, smb_offs, smb_maxcnt); - ok = True; + ok = True; - if (nread < 0) - return(UNIXERROR(ERRDOS,ERRnoaccess)); + 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); + SSVAL(outbuf,smb_vwv5,nread); + SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); + SSVAL(smb_buf(outbuf),-2,nread); - DEBUG(3,("readX pnum=%04x min=%d max=%d nread=%d\n", - pnum, smb_mincnt, smb_maxcnt, nread)); + DEBUG(3,("readX pnum=%04x min=%d max=%d nread=%d\n", + p->pnum, smb_mincnt, smb_maxcnt, nread)); - set_chain_pnum(pnum); + set_chain_p(p); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,outbuf,length,bufsize); } /**************************************************************************** reply to a close ****************************************************************************/ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) { - int pnum = get_rpc_pipe_num(inbuf,smb_vwv0); - int outsize = set_message(outbuf,0,0,True); + pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); + int outsize = set_message(outbuf,0,0,True); - DEBUG(5,("reply_pipe_close: pnum:%x\n", pnum)); + DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); - if (!close_rpc_pipe_hnd(pnum, conn)) return(ERROR(ERRDOS,ERRbadfid)); + if (!close_rpc_pipe_hnd(p, conn)) return(ERROR(ERRDOS,ERRbadfid)); - return(outsize); + return(outsize); } -- cgit From 8978aae69699ccab76fdf95037948b1cc7e7c286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 03:52:05 +0000 Subject: much cleaner chain pointer handling for both files and pipes. the chain pointer is now stored as a static and is set whenever a handle is created or extracted. This also makes the code less error prone. (This used to be commit 068a862982bea726e8d7b1b4065d510b9840a272) --- source3/smbd/pipes.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 84e31894a3..fed5c2bd17 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -138,8 +138,6 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(3,("readX pnum=%04x min=%d max=%d nread=%d\n", p->pnum, smb_mincnt, smb_maxcnt, nread)); - set_chain_p(p); - return chain_reply(inbuf,outbuf,length,bufsize); } /**************************************************************************** -- cgit From a5f8955ccb875f8467a83c241abf2e58c2bb96f4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 1 Sep 1998 01:10:01 +0000 Subject: check that a valid pipe is passed before doing a pipe close. I made this change after getting a segv in reply_pipe_close(). The funny thing was that pipes_open was 1 and Pipes was NULL. That "can't happen" and suggests that we have a wild pointer somewhere. I suspect the rpc code, as I was playing with long share names (a share called "averylongusername") at the time and the logs show lots of srvsvc operations. I bet there is a buffer in the rpc code somewhere that is overflowing and trashing bits of the data segment. (This used to be commit 9fee8c2eb7bd05431cd9bcfbed3804c8ca1ee593) --- source3/smbd/pipes.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index fed5c2bd17..97df3abfc3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -121,6 +121,8 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) char *data; BOOL ok = False; + if (!p) return(ERROR(ERRDOS,ERRbadfid)); + set_message(outbuf,12,0,True); data = smb_buf(outbuf); @@ -148,6 +150,8 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); int outsize = set_message(outbuf,0,0,True); + if (!p) return(ERROR(ERRDOS,ERRbadfid)); + DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); if (!close_rpc_pipe_hnd(p, conn)) return(ERROR(ERRDOS,ERRbadfid)); -- cgit From ac9b687cc2496409e1c8d86393812faf94ec7550 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Sep 1998 19:16:12 +0000 Subject: configure configure.in: Added tests for fseek64 and ftell64. config.h.in: Added fseek64 and ftell64. includes.h: Added definition of SMB_BIG_INTEGER. smb.h: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER. access.c: Tidyup of dbug statement. system.c: Added sys_fseek and sys_ftell. Changed mode calls to use mode_t. asyncdns.c: Tidyup of comment. loadparm.c: Tidyup of set_default_server_announce_type() function definition. ldap.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER. nispass.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER. smbpass.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER. smbpassfile.c: Use sys_fseek(). chgpasswd.c: Tidyup of debug statement. dosmode.c: Changed mode calls to use mode_t. ipc.c: Removal of dead code. nttrans.c: Changed mode calls to use mode_t. open.c: Changed mode calls to use mode_t. pipes.c: Removal of dead code. reply.c: Removal of dead code. trans2.c: Removal of dead code. Changed mode calls to use mode_t. Jeremy. (This used to be commit c381d32e3dc23fe887408016cae821aceb30da2c) --- source3/smbd/pipes.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 97df3abfc3..15d395b29a 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -119,7 +119,6 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) int smb_mincnt = SVAL(inbuf,smb_vwv6); int nread = -1; char *data; - BOOL ok = False; if (!p) return(ERROR(ERRDOS,ERRbadfid)); @@ -128,8 +127,6 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) nread = read_pipe(p, data, smb_offs, smb_maxcnt); - ok = True; - if (nread < 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); -- cgit From 2fef8f2e87f61043e3f1a2cf7d1f2a4ff9f119ff Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 7 Oct 1998 15:22:49 +0000 Subject: dce/rpc (This used to be commit 34afa638f6f7bb145ec094510ac58f7a22dfc3aa) --- source3/smbd/pipes.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 15d395b29a..00eec4e0e3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -105,6 +105,50 @@ int reply_open_pipe_and_X(connection_struct *conn, } +/**************************************************************************** + reply to a write and X + + This code is basically stolen from reply_write_and_X with some + wrinkles to handle pipes. +****************************************************************************/ +int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) +{ + pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); + uint32 smb_offs = IVAL(inbuf,smb_vwv3); + size_t numtowrite = SVAL(inbuf,smb_vwv10); + BOOL write_through = BITSETW(inbuf+smb_vwv7, 0); + int nwritten = -1; + int smb_doff = SVAL(inbuf, smb_vwv11); + char *data; + + if (!p) return(ERROR(ERRDOS,ERRbadfid)); + + data = smb_buf(inbuf) + smb_doff; + + if (numtowrite == 0) + { + nwritten = 0; + } + else + { + nwritten = write_pipe(p, data, numtowrite); + } + + if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) + { + return (UNIXERROR(ERRDOS,ERRnoaccess)); + } + + set_message(outbuf,6,0,True); + + SSVAL(outbuf,smb_vwv2,nwritten); + + DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", + p->pnum, nwritten)); + + return chain_reply(inbuf,outbuf,length,bufsize); +} + /**************************************************************************** reply to a read and X @@ -134,11 +178,12 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); SSVAL(smb_buf(outbuf),-2,nread); - DEBUG(3,("readX pnum=%04x min=%d max=%d nread=%d\n", + DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n", p->pnum, smb_mincnt, smb_maxcnt, nread)); return chain_reply(inbuf,outbuf,length,bufsize); } + /**************************************************************************** reply to a close ****************************************************************************/ -- cgit From 48b31ae44fb2a1961bd738b0b3e7a986259168a2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 7 Oct 1998 21:42:24 +0000 Subject: dce/rpc (This used to be commit 6677b888bdb45df00646eb7cc13005b9465ff971) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 00eec4e0e3..65da9337b2 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -123,7 +123,7 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (!p) return(ERROR(ERRDOS,ERRbadfid)); - data = smb_buf(inbuf) + smb_doff; + data = smb_base(inbuf) + smb_doff; if (numtowrite == 0) { -- cgit From 788263ba2f749c5bb1546ca6c9363fd508e94280 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 06:21:33 +0000 Subject: - fixed a bunch of warnings and minor errors - got smbtorture to compile - removed %D from some of lukes code - Luke, what is %D? it ain't portable anyway (This used to be commit 91597c12fb593f49b23c7cea5b64dbb89a0428b3) --- source3/smbd/pipes.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 65da9337b2..3e10065711 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -116,7 +116,6 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); uint32 smb_offs = IVAL(inbuf,smb_vwv3); size_t numtowrite = SVAL(inbuf,smb_vwv10); - BOOL write_through = BITSETW(inbuf+smb_vwv7, 0); int nwritten = -1; int smb_doff = SVAL(inbuf, smb_vwv11); char *data; -- cgit From 755986764f5a6b0ec25c7f20fde0a80eb4d121ba Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 19:05:19 +0000 Subject: dce/rpc (This used to be commit 32d0f5e4a564686ad6b270dd24423ee49a81f223) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 3e10065711..7cf7fd8ea3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -99,7 +99,7 @@ int reply_open_pipe_and_X(connection_struct *conn, put_dos_date3(outbuf,smb_vwv4,mtime); SIVAL(outbuf,smb_vwv6,size); SSVAL(outbuf,smb_vwv8,rmode); - SSVAL(outbuf,smb_vwv11,0); + SSVAL(outbuf,smb_vwv11,0x0001); return chain_reply(inbuf,outbuf,length,bufsize); } -- cgit From 1cdfdd4f0e1dc8610992786ce946db71f493c746 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 14 Oct 1998 07:02:12 +0000 Subject: unused variable in pipe_smb_write_X (This used to be commit cbc6ab6bb94dad7d71cfb71df3ee283831638e11) --- source3/smbd/pipes.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 7cf7fd8ea3..374aa70d0f 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -114,7 +114,6 @@ int reply_open_pipe_and_X(connection_struct *conn, int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) { pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); - uint32 smb_offs = IVAL(inbuf,smb_vwv3); size_t numtowrite = SVAL(inbuf,smb_vwv10); int nwritten = -1; int smb_doff = SVAL(inbuf, smb_vwv11); -- cgit From b231d2fafaff8dc67ef2dbaec778f716524d4f6a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 15 Nov 1999 22:11:10 +0000 Subject: - added DCE/RPC "fault" PDU support. - disabled (AGAIN) the GETDC "if (MAILSLOT\NTLOGON)" code that will get NT5rc2 to work but WILL break win95 (AGAIN). this needs _not_ to be re-enabled but to be replaced with a better mechanism. - added SMBwrite support (note: SMBwriteX already existed) as NT5rc2 is sending DCE/RPC over SMBwrite not SMBwriteX. (This used to be commit 25c70e3c984c4fed19763ed405741e83fe14f87e) --- source3/smbd/pipes.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 374aa70d0f..e20d049834 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -104,6 +104,47 @@ int reply_open_pipe_and_X(connection_struct *conn, return chain_reply(inbuf,outbuf,length,bufsize); } +/**************************************************************************** + reply to a write + + This code is basically stolen from reply_write with some + wrinkles to handle pipes. +****************************************************************************/ +int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize) +{ + pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); + size_t numtowrite = SVAL(inbuf,smb_vwv1); + int nwritten = -1; + char *data; + size_t outsize; + + if (!p) return(ERROR(ERRDOS,ERRbadfid)); + + data = smb_buf(inbuf) + 3; + + if (numtowrite == 0) + { + nwritten = 0; + } + else + { + nwritten = write_pipe(p, data, numtowrite); + } + + if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) + { + return (UNIXERROR(ERRDOS,ERRnoaccess)); + } + + outsize = set_message(outbuf,1,0,True); + + SSVAL(outbuf,smb_vwv0,nwritten); + + DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", + p->pnum, nwritten)); + + return outsize; +} /**************************************************************************** reply to a write and X -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/smbd/pipes.c | 64 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index e20d049834..15f52c0af6 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -74,10 +74,16 @@ int reply_open_pipe_and_X(connection_struct *conn, /* Strip \PIPE\ off the name. */ pstrcpy(fname,smb_buf(inbuf) + PIPELEN); + /* + * Hack for NT printers... JRA. + */ + if(should_fail_next_srvsvc_open(fname)) + return(ERROR(ERRSRV,ERRaccess)); + /* 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 */ + smb_ofun |= FILE_CREATE_IF_NOT_EXIST; p = open_rpc_pipe_p(fname, conn, vuid); if (!p) return(ERROR(ERRSRV,ERRnofids)); @@ -105,45 +111,37 @@ int reply_open_pipe_and_X(connection_struct *conn, } /**************************************************************************** - reply to a write - - This code is basically stolen from reply_write with some - wrinkles to handle pipes. + reply to a write on a pipe ****************************************************************************/ -int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize) +int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) { pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); size_t numtowrite = SVAL(inbuf,smb_vwv1); - int nwritten = -1; + int nwritten; + int outsize; char *data; - size_t outsize; - if (!p) return(ERROR(ERRDOS,ERRbadfid)); + if (!p) + return(ERROR(ERRDOS,ERRbadfid)); data = smb_buf(inbuf) + 3; if (numtowrite == 0) - { nwritten = 0; - } else - { - nwritten = write_pipe(p, data, numtowrite); - } + nwritten = write_to_pipe(p, data, numtowrite); if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) - { return (UNIXERROR(ERRDOS,ERRnoaccess)); - } outsize = set_message(outbuf,1,0,True); SSVAL(outbuf,smb_vwv0,nwritten); - + DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); - return outsize; + return(outsize); } /**************************************************************************** @@ -160,23 +158,18 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) int smb_doff = SVAL(inbuf, smb_vwv11); char *data; - if (!p) return(ERROR(ERRDOS,ERRbadfid)); + if (!p) + return(ERROR(ERRDOS,ERRbadfid)); data = smb_base(inbuf) + smb_doff; if (numtowrite == 0) - { nwritten = 0; - } else - { - nwritten = write_pipe(p, data, numtowrite); - } + nwritten = write_to_pipe(p, data, numtowrite); if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) - { return (UNIXERROR(ERRDOS,ERRnoaccess)); - } set_message(outbuf,6,0,True); @@ -197,18 +190,24 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) { pipes_struct *p = get_rpc_pipe_p(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 nread = -1; char *data; + /* we don't use the offset given to use for pipe reads. This + is deliberate, instead we always return the next lump of + data on the pipe */ +#if 0 + uint32 smb_offs = IVAL(inbuf,smb_vwv3); +#endif - if (!p) return(ERROR(ERRDOS,ERRbadfid)); + if (!p) + return(ERROR(ERRDOS,ERRbadfid)); set_message(outbuf,12,0,True); data = smb_buf(outbuf); - nread = read_pipe(p, data, smb_offs, smb_maxcnt); + nread = read_from_pipe(p, data, smb_maxcnt); if (nread < 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -231,12 +230,13 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); int outsize = set_message(outbuf,0,0,True); - if (!p) return(ERROR(ERRDOS,ERRbadfid)); + if (!p) + return(ERROR(ERRDOS,ERRbadfid)); DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); - if (!close_rpc_pipe_hnd(p, conn)) return(ERROR(ERRDOS,ERRbadfid)); + if (!close_rpc_pipe_hnd(p, conn)) + return(ERROR(ERRDOS,ERRbadfid)); return(outsize); } - -- cgit From fbd17c8dafeefac788f4bc1c41045726825f513f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 3 Jan 2000 19:19:48 +0000 Subject: simple mods to add msrpc pipe redirection. default behaviour: fall back to using internal msrpc code in smbd. (This used to be commit 8976e26d46cb991710bc77463f7f928ac00dd4d8) --- source3/smbd/pipes.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 15f52c0af6..1a9ac1d7a4 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -129,7 +129,16 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) if (numtowrite == 0) nwritten = 0; else - nwritten = write_to_pipe(p, data, numtowrite); + { + if (p->m != NULL) + { + nwritten = write_pipe(p, data, numtowrite); + } + else + { + nwritten = write_to_pipe(p, data, numtowrite); + } + } if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) return (UNIXERROR(ERRDOS,ERRnoaccess)); @@ -207,7 +216,14 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) set_message(outbuf,12,0,True); data = smb_buf(outbuf); - nread = read_from_pipe(p, data, smb_maxcnt); + if (p->m != NULL) + { + nread = read_pipe(p, data, smb_maxcnt); + } + else + { + nread = read_from_pipe(p, data, smb_maxcnt); + } if (nread < 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); -- cgit From 6bb92a6d38db41a11e80c4369623d137763f0f52 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Mar 2000 21:45:16 +0000 Subject: Big update moving the multi-pdu support from 2.0.x into HEAD for JF and the printer functions. Also tidied up some header includes and got the order right so you can now do a : make proto make clean make Jeremy. (This used to be commit 833cd9fba92e4ad5297b235d108dd2be8c17079b) --- source3/smbd/pipes.c | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 1a9ac1d7a4..65a71e1c00 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -129,16 +129,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) if (numtowrite == 0) nwritten = 0; else - { - if (p->m != NULL) - { - nwritten = write_pipe(p, data, numtowrite); - } - else - { - nwritten = write_to_pipe(p, data, numtowrite); - } - } + nwritten = write_to_pipe(p, data, numtowrite); if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) return (UNIXERROR(ERRDOS,ERRnoaccess)); @@ -154,17 +145,19 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) } /**************************************************************************** - reply to a write and X + Reply to a write and X. - This code is basically stolen from reply_write_and_X with some - wrinkles to handle pipes. + This code is basically stolen from reply_write_and_X with some + wrinkles to handle pipes. ****************************************************************************/ + int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) { pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); size_t numtowrite = SVAL(inbuf,smb_vwv10); int nwritten = -1; int smb_doff = SVAL(inbuf, smb_vwv11); + BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) != 0); char *data; if (!p) @@ -174,14 +167,31 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (numtowrite == 0) nwritten = 0; - else + else { + if(pipe_start_message_raw) { + /* + * For the start of a message in named pipe byte mode, + * the first two bytes are a length-of-pdu field. Ignore + * them (we don't trust the client. JRA. + */ + if(numtowrite < 2) { + DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n", + (unsigned int)numtowrite )); + return (UNIXERROR(ERRDOS,ERRnoaccess)); + } + + data += 2; + numtowrite -= 2; + } nwritten = write_to_pipe(p, data, numtowrite); + } if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) return (UNIXERROR(ERRDOS,ERRnoaccess)); set_message(outbuf,6,0,True); + nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten); SSVAL(outbuf,smb_vwv2,nwritten); DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", @@ -216,14 +226,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) set_message(outbuf,12,0,True); data = smb_buf(outbuf); - if (p->m != NULL) - { - nread = read_pipe(p, data, smb_maxcnt); - } - else - { - nread = read_from_pipe(p, data, smb_maxcnt); - } + nread = read_from_pipe(p, data, smb_maxcnt); if (nread < 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); -- cgit From 741dfefd565dbcd9ec8a861ebe3a7e6c0e80eac1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 11 Mar 2000 01:28:57 +0000 Subject: Fix stupid logic bug in detecting start-of-pdu in writeX on pipe. Found by JF. Jeremy. (This used to be commit 8315583694249278c57948406c1f48e2128f2b08) --- source3/smbd/pipes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 65a71e1c00..5d5c6a653a 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -157,7 +157,8 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) size_t numtowrite = SVAL(inbuf,smb_vwv10); int nwritten = -1; int smb_doff = SVAL(inbuf, smb_vwv11); - BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) != 0); + BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) == + (PIPE_START_MESSAGE|PIPE_RAW_MODE)); char *data; if (!p) -- cgit From 00e3fe132476fcaed0f4b9bbe74b0a6559c39df0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Apr 2000 14:06:57 +0000 Subject: moved trans2.h and nterr.h into includes.h with all our other includes (This used to be commit d7cd7c88fdabb01d9e40ae8a657737907a21ac37) --- source3/smbd/pipes.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 5d5c6a653a..0cfe653d30 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -27,7 +27,6 @@ #include "includes.h" -#include "trans2.h" #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) -- cgit From 49a0e6d5989656c1b3c9c063a20308ca4ee5d73b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 10:41:59 +0000 Subject: more merging voodoo this adds "#define OLD_NTDOMAIN 1" in lots of places. Don't panic - this isn't permanent, it should go after another few merge steps have been done (This used to be commit 92109d7b3c06f240452d39f669ecb8c9c86ab610) --- source3/smbd/pipes.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 0cfe653d30..c1d5c261fe 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -1,3 +1,4 @@ +#define OLD_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 1.9. @@ -259,3 +260,5 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) return(outsize); } + +#undef OLD_NTDOMAIN -- cgit From 0164047afbd082b0003147845a72ca08b4781b81 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Jun 2000 01:49:23 +0000 Subject: Fixing get/set of security descriptors. Removed ugly hack for NT printing. Fixed up tdb parse stuff memory leaks. Jeremy. (This used to be commit 8ef41f31c53e14ad057d883810a1cd2301fede2a) --- source3/smbd/pipes.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index c1d5c261fe..df7141764c 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -74,11 +74,13 @@ int reply_open_pipe_and_X(connection_struct *conn, /* Strip \PIPE\ off the name. */ pstrcpy(fname,smb_buf(inbuf) + PIPELEN); +#if 0 /* * Hack for NT printers... JRA. */ if(should_fail_next_srvsvc_open(fname)) return(ERROR(ERRSRV,ERRaccess)); +#endif /* Known pipes arrive with DIR attribs. Remove it so a regular file */ /* can be opened and add it in after the open. */ -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/smbd/pipes.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index df7141764c..366707cd58 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -1,4 +1,3 @@ -#define OLD_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 1.9. @@ -262,5 +261,3 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) return(outsize); } - -#undef OLD_NTDOMAIN -- cgit From 6e4b0088298c926e4eb09b1c97f750e5c3feb295 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Wed, 18 Apr 2001 17:57:53 +0000 Subject: a missing string conversion. J.F. (This used to be commit 9513eb87c2d113fe27bcea2add05226495c33cb8) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 366707cd58..7a3c1fe20e 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -52,7 +52,7 @@ int reply_open_pipe_and_X(connection_struct *conn, int i; /* XXXX we need to handle passed times, sattr and flags */ - pstrcpy(fname,smb_buf(inbuf)); + srvstr_pull(inbuf, fname, smb_buf(inbuf), sizeof(fname), -1, STR_TERMINATE); /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ -- cgit From 6b97f76be844a333502c1f17c65fb9e909599915 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Wed, 4 Jul 2001 21:57:03 +0000 Subject: allow to use usrmgr/svrmgr tools in win95 pretty cool (This used to be commit 04575ff17b9b5fe802e66bb8dd1948317ab35485) --- source3/smbd/pipes.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 7a3c1fe20e..c7e0c3a5e5 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -45,6 +45,7 @@ int reply_open_pipe_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; + pstring pipe_name; uint16 vuid = SVAL(inbuf, smb_uid); pipes_struct *p; int smb_ofun = SVAL(inbuf,smb_vwv8); @@ -52,26 +53,27 @@ int reply_open_pipe_and_X(connection_struct *conn, int i; /* XXXX we need to handle passed times, sattr and flags */ - srvstr_pull(inbuf, fname, smb_buf(inbuf), sizeof(fname), -1, STR_TERMINATE); + srvstr_pull(inbuf, pipe_name, smb_buf(inbuf), sizeof(pipe_name), -1, STR_TERMINATE); /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ /* not just something we really don't understand. */ - if ( strncmp(fname,PIPE,PIPELEN) != 0 ) + if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) return(ERROR(ERRSRV,ERRaccess)); - DEBUG(4,("Opening pipe %s.\n", fname)); + DEBUG(4,("Opening pipe %s.\n", pipe_name)); /* See if it is one we want to handle. */ for( i = 0; pipe_names[i].client_pipe ; i++ ) - if( strequal(fname,pipe_names[i].client_pipe) ) + if( strequal(pipe_name,pipe_names[i].client_pipe) ) break; if (pipe_names[i].client_pipe == NULL) return(ERROR(ERRSRV,ERRaccess)); /* Strip \PIPE\ off the name. */ - pstrcpy(fname,smb_buf(inbuf) + PIPELEN); + pstrcpy(fname, pipe_name + PIPELEN); + #if 0 /* -- cgit From e8e98c9ea0690e3acf1126b50882e59e1056c7b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 08:19:43 +0000 Subject: converted smbd to use NTSTATUS by default major changes include: - added NSTATUS type - added automatic mapping between dos and nt error codes - changed all ERROR() calls to ERROR_DOS() and many to ERROR_NT() these calls auto-translate to the client error code system - got rid of the cached error code and the writebmpx code We eventually will need to also: - get rid of BOOL, so we don't lose error info - replace all ERROR_DOS() calls with ERROR_NT() calls but that is too much for one night (This used to be commit 83d9896c1ea8be796192b51a4678c2a3b87f7518) --- source3/smbd/pipes.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index c7e0c3a5e5..162ad1603d 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -59,7 +59,7 @@ int reply_open_pipe_and_X(connection_struct *conn, /* at a mailslot or something we really, really don't understand, */ /* not just something we really don't understand. */ if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); DEBUG(4,("Opening pipe %s.\n", pipe_name)); @@ -69,7 +69,7 @@ int reply_open_pipe_and_X(connection_struct *conn, break; if (pipe_names[i].client_pipe == NULL) - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); /* Strip \PIPE\ off the name. */ pstrcpy(fname, pipe_name + PIPELEN); @@ -89,7 +89,7 @@ int reply_open_pipe_and_X(connection_struct *conn, smb_ofun |= FILE_CREATE_IF_NOT_EXIST; p = open_rpc_pipe_p(fname, conn, vuid); - if (!p) return(ERROR(ERRSRV,ERRnofids)); + if (!p) return(ERROR_DOS(ERRSRV,ERRnofids)); /* Prepare the reply */ set_message(outbuf,15,0,True); @@ -125,7 +125,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) char *data; if (!p) - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); data = smb_buf(inbuf) + 3; @@ -165,7 +165,7 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) char *data; if (!p) - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); data = smb_base(inbuf) + smb_doff; @@ -225,7 +225,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) #endif if (!p) - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); set_message(outbuf,12,0,True); data = smb_buf(outbuf); @@ -254,12 +254,12 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) int outsize = set_message(outbuf,0,0,True); if (!p) - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); if (!close_rpc_pipe_hnd(p, conn)) - return(ERROR(ERRDOS,ERRbadfid)); + return ERROR_DOS(ERRDOS,ERRbadfid); return(outsize); } -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/smbd/pipes.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 162ad1603d..9a911ed014 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -31,8 +31,6 @@ #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) -extern int DEBUGLEVEL; - extern struct pipe_id_info pipe_names[]; /**************************************************************************** -- cgit From 2a6eeff2a7a7c8c2ada79a3d1270998287d726e9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Dec 2001 02:09:57 +0000 Subject: Return NT_STATUS_OBJECT_NOT_FOUND or ERRbadpipe if pipe name not found. Jeremy. (This used to be commit d5fdb1f096e8db3e9cf7a65ddb75f7cafd1958c0) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 9a911ed014..cd8a56a5d2 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -67,7 +67,7 @@ int reply_open_pipe_and_X(connection_struct *conn, break; if (pipe_names[i].client_pipe == NULL) - return(ERROR_DOS(ERRSRV,ERRaccess)); + return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe)); /* Strip \PIPE\ off the name. */ pstrcpy(fname, pipe_name + PIPELEN); -- cgit From bb6af711b8f9a525b74198abbe7f1c37014ca6f7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Jan 2002 02:40:05 +0000 Subject: This is the current patch from Luke Leighton to add a degree of seperation betwen reading/writing the raw NamedPipe SMB packets and the matching operations inside smbd's RPC components. This patch is designed for no change in behaviour, and my tests hold that to be true. This patch does however allow for the future loadable modules interface to specify function pointers in replacement of the fixed state. The pipes_struct has been split into two peices, with smb_np_struct taking the information that should be generic to where the data ends up. Some other minor changes are made: we get another small helper function in util_sock.c and some of the original code has better failure debugs and variable use. (As per on-list comments). Andrew Bartlett (This used to be commit 8ef13cabdddf58b741886782297fb64b2fb7e489) --- source3/smbd/pipes.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index cd8a56a5d2..8f6f6f39c4 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -45,7 +45,7 @@ int reply_open_pipe_and_X(connection_struct *conn, pstring fname; pstring pipe_name; uint16 vuid = SVAL(inbuf, smb_uid); - pipes_struct *p; + smb_np_struct *p; int smb_ofun = SVAL(inbuf,smb_vwv8); int size=0,fmode=0,mtime=0,rmode=0; int i; @@ -116,7 +116,7 @@ int reply_open_pipe_and_X(connection_struct *conn, ****************************************************************************/ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) { - pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); + smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); size_t numtowrite = SVAL(inbuf,smb_vwv1); int nwritten; int outsize; @@ -154,7 +154,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) { - pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); + smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); size_t numtowrite = SVAL(inbuf,smb_vwv10); int nwritten = -1; int smb_doff = SVAL(inbuf, smb_vwv11); @@ -210,11 +210,13 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) ****************************************************************************/ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) { - pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); + smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); int smb_maxcnt = SVAL(inbuf,smb_vwv5); int smb_mincnt = SVAL(inbuf,smb_vwv6); int nread = -1; char *data; + BOOL unused; + /* we don't use the offset given to use for pipe reads. This is deliberate, instead we always return the next lump of data on the pipe */ @@ -228,7 +230,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) set_message(outbuf,12,0,True); data = smb_buf(outbuf); - nread = read_from_pipe(p, data, smb_maxcnt); + nread = read_from_pipe(p, data, smb_maxcnt, &unused); if (nread < 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -248,7 +250,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) ****************************************************************************/ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) { - pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); + smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); int outsize = set_message(outbuf,0,0,True); if (!p) @@ -256,7 +258,7 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); - if (!close_rpc_pipe_hnd(p, conn)) + if (!close_rpc_pipe_hnd(p)) return ERROR_DOS(ERRDOS,ERRbadfid); return(outsize); -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/smbd/pipes.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 8f6f6f39c4..6c1e6efa73 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. Pipe SMB reply routines Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Luke Kenneth Casson Leighton 1996-1998 -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 6c1e6efa73..f7e9c595c1 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -50,7 +50,7 @@ int reply_open_pipe_and_X(connection_struct *conn, int i; /* XXXX we need to handle passed times, sattr and flags */ - srvstr_pull(inbuf, pipe_name, smb_buf(inbuf), sizeof(pipe_name), -1, STR_TERMINATE); + srvstr_pull_buf(inbuf, pipe_name, smb_buf(inbuf), sizeof(pipe_name), STR_TERMINATE); /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ -- cgit From 3312191867e97a7cf3d485c050c1e689ea574f6d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Dec 2004 23:14:20 +0000 Subject: r4330: Fix for bug found by Rob Foehl . Remember to add in the bcc length for readX on named pipes. Jeremy. (This used to be commit 1168395e6a543c51f684280b00fb8c9b8bbc6ec0) --- source3/smbd/pipes.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index f7e9c595c1..6c7faa4c05 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -241,6 +241,8 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n", p->pnum, smb_mincnt, smb_maxcnt, nread)); + /* Ensure we set up the message length to include the data length read. */ + set_message_bcc(outbuf,nread); return chain_reply(inbuf,outbuf,length,bufsize); } -- cgit From af8a691db11a5072865f8b03fd1cbd3aab5cb6d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Jul 2005 04:51:27 +0000 Subject: r8219: Merge the new open code from HEAD to 3.0. Haven't yet run the torture tests on this as it's very late NY time (just wanted to get this work into the tree). I'll test this over the weekend.... Jerry - in looking at the difference between the two trees there seem to be some printing/ntprinting.c and registry changes we might want to examine to try keep in sync. Jeremy. (This used to be commit c7fe18761e2c753afbffd3a78abff46472a9b8eb) --- source3/smbd/pipes.c | 89 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 38 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 6c7faa4c05..951c192e39 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Luke Kenneth Casson Leighton 1996-1998 Copyright (C) Paul Ashton 1997-1998. + Copyright (C) Jeremy Allison 2005. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,11 +34,11 @@ extern struct pipe_id_info pipe_names[]; /**************************************************************************** - reply to an open and X on a named pipe - - This code is basically stolen from reply_open_and_X with some - wrinkles to handle pipes. + Reply to an open and X on a named pipe. + This code is basically stolen from reply_open_and_X with some + wrinkles to handle pipes. ****************************************************************************/ + int reply_open_pipe_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { @@ -45,7 +46,6 @@ int reply_open_pipe_and_X(connection_struct *conn, pstring pipe_name; uint16 vuid = SVAL(inbuf, smb_uid); smb_np_struct *p; - int smb_ofun = SVAL(inbuf,smb_vwv8); int size=0,fmode=0,mtime=0,rmode=0; int i; @@ -55,23 +55,26 @@ int reply_open_pipe_and_X(connection_struct *conn, /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ /* not just something we really don't understand. */ - if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) + if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) { return(ERROR_DOS(ERRSRV,ERRaccess)); + } DEBUG(4,("Opening pipe %s.\n", pipe_name)); /* See if it is one we want to handle. */ - for( i = 0; pipe_names[i].client_pipe ; i++ ) - if( strequal(pipe_name,pipe_names[i].client_pipe) ) + for( i = 0; pipe_names[i].client_pipe ; i++ ) { + if( strequal(pipe_name,pipe_names[i].client_pipe)) { break; + } + } - if (pipe_names[i].client_pipe == NULL) + if (pipe_names[i].client_pipe == NULL) { return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe)); + } /* Strip \PIPE\ off the name. */ pstrcpy(fname, pipe_name + PIPELEN); - #if 0 /* * Hack for NT printers... JRA. @@ -83,10 +86,11 @@ int reply_open_pipe_and_X(connection_struct *conn, /* 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 |= FILE_CREATE_IF_NOT_EXIST; p = open_rpc_pipe_p(fname, conn, vuid); - if (!p) return(ERROR_DOS(ERRSRV,ERRnofids)); + if (!p) { + return(ERROR_DOS(ERRSRV,ERRnofids)); + } /* Prepare the reply */ set_message(outbuf,15,0,True); @@ -111,8 +115,9 @@ int reply_open_pipe_and_X(connection_struct *conn, } /**************************************************************************** - reply to a write on a pipe + Reply to a write on a pipe. ****************************************************************************/ + int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); @@ -121,25 +126,27 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) int outsize; char *data; - if (!p) + if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); + } data = smb_buf(inbuf) + 3; - if (numtowrite == 0) + if (numtowrite == 0) { nwritten = 0; - else + } else { nwritten = write_to_pipe(p, data, numtowrite); + } - if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) + if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { return (UNIXERROR(ERRDOS,ERRnoaccess)); + } outsize = set_message(outbuf,1,0,True); SSVAL(outbuf,smb_vwv0,nwritten); - DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", - p->pnum, nwritten)); + DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); return(outsize); } @@ -158,24 +165,25 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) int nwritten = -1; int smb_doff = SVAL(inbuf, smb_vwv11); BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) == - (PIPE_START_MESSAGE|PIPE_RAW_MODE)); + (PIPE_START_MESSAGE|PIPE_RAW_MODE)); char *data; - if (!p) + if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); + } data = smb_base(inbuf) + smb_doff; - if (numtowrite == 0) + if (numtowrite == 0) { nwritten = 0; - else { + } else { if(pipe_start_message_raw) { /* * For the start of a message in named pipe byte mode, * the first two bytes are a length-of-pdu field. Ignore - * them (we don't trust the client. JRA. + * them (we don't trust the client). JRA. */ - if(numtowrite < 2) { + if(numtowrite < 2) { DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n", (unsigned int)numtowrite )); return (UNIXERROR(ERRDOS,ERRnoaccess)); @@ -183,30 +191,30 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) data += 2; numtowrite -= 2; - } + } nwritten = write_to_pipe(p, data, numtowrite); } - if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) + if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { return (UNIXERROR(ERRDOS,ERRnoaccess)); + } set_message(outbuf,6,0,True); nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten); SSVAL(outbuf,smb_vwv2,nwritten); - DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", - p->pnum, nwritten)); + DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); return chain_reply(inbuf,outbuf,length,bufsize); } /**************************************************************************** - reply to a read and X - - This code is basically stolen from reply_read_and_X with some - wrinkles to handle pipes. + Reply to a read and X. + This code is basically stolen from reply_read_and_X with some + wrinkles to handle pipes. ****************************************************************************/ + int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); @@ -223,16 +231,18 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) uint32 smb_offs = IVAL(inbuf,smb_vwv3); #endif - if (!p) + if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); + } set_message(outbuf,12,0,True); data = smb_buf(outbuf); nread = read_from_pipe(p, data, smb_maxcnt, &unused); - if (nread < 0) + if (nread < 0) { return(UNIXERROR(ERRDOS,ERRnoaccess)); + } SSVAL(outbuf,smb_vwv5,nread); SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); @@ -247,20 +257,23 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) } /**************************************************************************** - reply to a close + Reply to a close. ****************************************************************************/ + int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); int outsize = set_message(outbuf,0,0,True); - if (!p) + if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); + } DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); - if (!close_rpc_pipe_hnd(p)) + if (!close_rpc_pipe_hnd(p)) { return ERROR_DOS(ERRDOS,ERRbadfid); + } return(outsize); } -- cgit From 6d5757395a0e54245543794d0d6d6d6a32cd857a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Nov 2005 04:21:55 +0000 Subject: r11511: A classic "friday night check-in" :-). This moves much of the Samba4 timezone handling code back into Samba3. Gets rid of "kludge-gmt" and removes the effectiveness of the parameter "time offset" (I can add this back in very easily if needed) - it's no longer being looked at. I'm hoping this will fix the problems people have been having with DST transitions. I'll start comprehensive testing tomorrow, but for now all modifications are done. Splits time get/set functions into srv_XXX and cli_XXX as they need to look at different timezone offsets. Get rid of much of the "efficiency" cruft that was added to Samba back in the day when the C library timezone handling functions were slow. Jeremy. (This used to be commit 414303bc0272f207046b471a0364fa296b67c1f8) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 951c192e39..12f3d180b1 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -106,7 +106,7 @@ int reply_open_pipe_and_X(connection_struct *conn, SSVAL(outbuf,smb_vwv2, p->pnum); SSVAL(outbuf,smb_vwv3,fmode); - put_dos_date3(outbuf,smb_vwv4,mtime); + srv_put_dos_date3(outbuf,smb_vwv4,mtime); SIVAL(outbuf,smb_vwv6,size); SSVAL(outbuf,smb_vwv8,rmode); SSVAL(outbuf,smb_vwv11,0x0001); -- cgit From 263b01ecb9a09c80c3b519c5ec4e52437ace9da0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 27 May 2006 21:38:54 +0000 Subject: r15911: Make us survive rpc-authcontext committed next (This used to be commit c24bfdce625782637b5f4d11a5117ef795ddfc2f) --- source3/smbd/pipes.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 12f3d180b1..2d90383706 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -121,6 +121,7 @@ int reply_open_pipe_and_X(connection_struct *conn, int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); + uint16 vuid = SVAL(inbuf,smb_uid); size_t numtowrite = SVAL(inbuf,smb_vwv1); int nwritten; int outsize; @@ -130,6 +131,10 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) return(ERROR_DOS(ERRDOS,ERRbadfid)); } + if (p->vuid != vuid) { + return ERROR_NT(NT_STATUS_INVALID_HANDLE); + } + data = smb_buf(inbuf) + 3; if (numtowrite == 0) { @@ -161,6 +166,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); + uint16 vuid = SVAL(inbuf,smb_uid); size_t numtowrite = SVAL(inbuf,smb_vwv10); int nwritten = -1; int smb_doff = SVAL(inbuf, smb_vwv11); @@ -172,6 +178,10 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) return(ERROR_DOS(ERRDOS,ERRbadfid)); } + if (p->vuid != vuid) { + return ERROR_NT(NT_STATUS_INVALID_HANDLE); + } + data = smb_base(inbuf) + smb_doff; if (numtowrite == 0) { -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/smbd/pipes.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2d90383706..52660da2ff 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -31,6 +31,21 @@ #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) +#define MAX_PIPE_NAME_LEN 24 + +/* PIPE/// */ +#define PIPEDB_KEY_FORMAT "PIPE/%s/%u/%d" + +struct pipe_dbrec { + struct process_id pid; + int pnum; + uid_t uid; + + char name[MAX_PIPE_NAME_LEN]; + fstring user; +}; + + extern struct pipe_id_info pipe_names[]; /**************************************************************************** @@ -284,6 +299,8 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) if (!close_rpc_pipe_hnd(p)) { return ERROR_DOS(ERRDOS,ERRbadfid); } + + /* TODO: REMOVE PIPE FROM DB */ return(outsize); } -- cgit From 0829e1ad1c3646efecf50729f493b9ee72ef0517 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 22:40:32 +0000 Subject: r22391: Looks bigger than it is. Make "inbuf" available to all callers of smb_setlen (via set_message() calls). This will allow the server to reflect back the correct encryption context. Jeremy. (This used to be commit 2d80a96120a5fe2fe726f00746d36d85044c4bdb) --- source3/smbd/pipes.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 52660da2ff..bec2f19f86 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -108,7 +108,7 @@ int reply_open_pipe_and_X(connection_struct *conn, } /* Prepare the reply */ - set_message(outbuf,15,0,True); + set_message(inbuf,outbuf,15,0,True); /* Mark the opened file as an existing named pipe in message mode. */ SSVAL(outbuf,smb_vwv9,2); @@ -162,7 +162,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) return (UNIXERROR(ERRDOS,ERRnoaccess)); } - outsize = set_message(outbuf,1,0,True); + outsize = set_message(inbuf,outbuf,1,0,True); SSVAL(outbuf,smb_vwv0,nwritten); @@ -224,7 +224,7 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) return (UNIXERROR(ERRDOS,ERRnoaccess)); } - set_message(outbuf,6,0,True); + set_message(inbuf,outbuf,6,0,True); nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten); SSVAL(outbuf,smb_vwv2,nwritten); @@ -260,7 +260,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) return(ERROR_DOS(ERRDOS,ERRbadfid)); } - set_message(outbuf,12,0,True); + set_message(inbuf,outbuf,12,0,True); data = smb_buf(outbuf); nread = read_from_pipe(p, data, smb_maxcnt, &unused); @@ -277,7 +277,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) p->pnum, smb_mincnt, smb_maxcnt, nread)); /* Ensure we set up the message length to include the data length read. */ - set_message_bcc(outbuf,nread); + set_message_bcc(inbuf,outbuf,nread); return chain_reply(inbuf,outbuf,length,bufsize); } @@ -288,7 +288,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) { smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); - int outsize = set_message(outbuf,0,0,True); + int outsize = set_message(inbuf,outbuf,0,0,True); if (!p) { return(ERROR_DOS(ERRDOS,ERRbadfid)); -- cgit From e6383f47629368d9dd4e803f17566a24e9d7359e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 09:35:35 +0000 Subject: r22736: Start to merge the low-hanging fruit from the now 7000-line cluster patch. This changes "struct process_id" to "struct server_id", keeping both is just too much hassle. No functional change (I hope ;-)) Volker (This used to be commit 0ad4b1226c9d91b72136310d3bbb640d2c5d67b8) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index bec2f19f86..aba2fe69c5 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -37,7 +37,7 @@ #define PIPEDB_KEY_FORMAT "PIPE/%s/%u/%d" struct pipe_dbrec { - struct process_id pid; + struct server_id pid; int pnum; uid_t uid; -- cgit From fcda5b589633b96415890c569bf23e3e284e0916 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jul 2007 16:33:37 +0000 Subject: r23726: Explicitly pass down the FLAGS2 field to srvstr_pull_buf. The next checkin will pull this up to srvstr_get_path. At that point we can get more independent of the inbuf, the base_ptr in pull_string will only be used to satisfy UCS2 alignment constraints. (This used to be commit 836782b07bf133e9b2598c4a089f1c810e4c7754) --- source3/smbd/pipes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index aba2fe69c5..1da2f0c22f 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -65,7 +65,8 @@ int reply_open_pipe_and_X(connection_struct *conn, int i; /* XXXX we need to handle passed times, sattr and flags */ - srvstr_pull_buf(inbuf, pipe_name, smb_buf(inbuf), sizeof(pipe_name), STR_TERMINATE); + srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), pipe_name, + smb_buf(inbuf), sizeof(pipe_name), STR_TERMINATE); /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 1da2f0c22f..9392d7b2fc 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/smbd/pipes.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 9392d7b2fc..1ea3e052b2 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* This file handles reply_ calls on named pipes that the server -- cgit From cc6a41017c577742af73b4bc60993d8d415ea580 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Jul 2007 09:36:09 +0000 Subject: r23997: Check in the infrastructure for getting rid of the global InBuffer/OutBuffer The complete history of this patch can be found under http://www.samba.org/~vlendec/inbuf-checkin/. Jeremy, Jerry: If possible I would like to see this in 3.2.0. I'm only checking into 3_2 at the moment, as it currently will slow down operations for all non-converted (i.e. all at this moment) operations, as it will copy the talloc'ed inbuf over the global InBuffer. It will need quite a bit of effort to convert everything necessary for the normal operations an XP box does. I have patches for negprot, session setup, tcon_and_X, open_and_X, close. More to come, but I would appreciate some help here. Volker (This used to be commit 5594af2b208c860d3f4b453af6a649d9e4295d1c) --- source3/smbd/pipes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 1ea3e052b2..a6cdc3a989 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -126,7 +126,7 @@ int reply_open_pipe_and_X(connection_struct *conn, SSVAL(outbuf,smb_vwv8,rmode); SSVAL(outbuf,smb_vwv11,0x0001); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,&outbuf,length,bufsize); } /**************************************************************************** @@ -231,7 +231,7 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,&outbuf,length,bufsize); } /**************************************************************************** @@ -278,7 +278,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* Ensure we set up the message length to include the data length read. */ set_message_bcc(inbuf,outbuf,nread); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,&outbuf,length,bufsize); } /**************************************************************************** -- cgit From 47cdfc0413886780f51fb98b7fca18d7c83b7c23 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Jul 2007 09:53:06 +0000 Subject: r23998: Convert reply_close to the new API (This used to be commit dbf74cb747d34dac571d85d6bae9398558086456) --- source3/smbd/pipes.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index a6cdc3a989..cb1461478a 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -285,22 +285,24 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) Reply to a close. ****************************************************************************/ -int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) +void reply_pipe_close(connection_struct *conn, struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); - int outsize = set_message(inbuf,outbuf,0,0,True); + smb_np_struct *p = get_rpc_pipe_p((char *)req->inbuf,smb_vwv0); if (!p) { - return(ERROR_DOS(ERRDOS,ERRbadfid)); + reply_doserror(req, ERRDOS, ERRbadfid); + return; } DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); if (!close_rpc_pipe_hnd(p)) { - return ERROR_DOS(ERRDOS,ERRbadfid); + reply_doserror(req, ERRDOS, ERRbadfid); + return; } /* TODO: REMOVE PIPE FROM DB */ - return(outsize); + reply_outbuf(req, 0, 0); + return; } -- cgit From 9e40557047b32dae012b0b5a3450c2c23b7895e5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Jul 2007 09:54:36 +0000 Subject: r23999: Convert reply_open_and_X This is an example of chained code that is executed in make test (This used to be commit e3a10e9ffb06f429208f8b8e8482bbfd56dace91) --- source3/smbd/pipes.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index cb1461478a..a4ac807377 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -53,25 +53,24 @@ extern struct pipe_id_info pipe_names[]; wrinkles to handle pipes. ****************************************************************************/ -int reply_open_pipe_and_X(connection_struct *conn, - char *inbuf,char *outbuf,int length,int bufsize) +void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) { pstring fname; pstring pipe_name; - uint16 vuid = SVAL(inbuf, smb_uid); smb_np_struct *p; int size=0,fmode=0,mtime=0,rmode=0; int i; /* XXXX we need to handle passed times, sattr and flags */ - srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), pipe_name, - smb_buf(inbuf), sizeof(pipe_name), STR_TERMINATE); + srvstr_pull_buf(req->inbuf, req->flags2, pipe_name, + smb_buf(req->inbuf), sizeof(pipe_name), STR_TERMINATE); /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ /* not just something we really don't understand. */ if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) { - return(ERROR_DOS(ERRSRV,ERRaccess)); + reply_doserror(req, ERRSRV, ERRaccess); + return; } DEBUG(4,("Opening pipe %s.\n", pipe_name)); @@ -84,7 +83,9 @@ int reply_open_pipe_and_X(connection_struct *conn, } if (pipe_names[i].client_pipe == NULL) { - return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe)); + reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, + ERRDOS, ERRbadpipe); + return; } /* Strip \PIPE\ off the name. */ @@ -94,39 +95,43 @@ int reply_open_pipe_and_X(connection_struct *conn, /* * Hack for NT printers... JRA. */ - if(should_fail_next_srvsvc_open(fname)) - return(ERROR(ERRSRV,ERRaccess)); + if(should_fail_next_srvsvc_open(fname)) { + reply_doserror(req, ERRSRV, ERRaccess); + return; + } #endif /* 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)); - p = open_rpc_pipe_p(fname, conn, vuid); + p = open_rpc_pipe_p(fname, conn, req->vuid); if (!p) { - return(ERROR_DOS(ERRSRV,ERRnofids)); + reply_doserror(req, ERRSRV, ERRnofids); + return; } /* Prepare the reply */ - set_message(inbuf,outbuf,15,0,True); + reply_outbuf(req, 15, 0); /* Mark the opened file as an existing named pipe in message mode. */ - SSVAL(outbuf,smb_vwv9,2); - SSVAL(outbuf,smb_vwv10,0xc700); + SSVAL(req->outbuf,smb_vwv9,2); + SSVAL(req->outbuf,smb_vwv10,0xc700); if (rmode == 2) { DEBUG(4,("Resetting open result to open from create.\n")); rmode = 1; } - SSVAL(outbuf,smb_vwv2, p->pnum); - SSVAL(outbuf,smb_vwv3,fmode); - srv_put_dos_date3(outbuf,smb_vwv4,mtime); - SIVAL(outbuf,smb_vwv6,size); - SSVAL(outbuf,smb_vwv8,rmode); - SSVAL(outbuf,smb_vwv11,0x0001); + SSVAL(req->outbuf,smb_vwv2, p->pnum); + SSVAL(req->outbuf,smb_vwv3,fmode); + srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime); + SIVAL(req->outbuf,smb_vwv6,size); + SSVAL(req->outbuf,smb_vwv8,rmode); + SSVAL(req->outbuf,smb_vwv11,0x0001); - return chain_reply(inbuf,&outbuf,length,bufsize); + chain_reply_new(req); + return; } /**************************************************************************** -- cgit From bfbd75653581ab21ce3f26b006c00389b7939bd7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 31 Jul 2007 13:14:07 +0000 Subject: r24106: Pass fnum instead of buf/offset into get_rpc_pipe_p (This used to be commit eb353412c60fc21a31530d9678505470ffbf11ce) --- source3/smbd/pipes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index a4ac807377..24e0f47001 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -140,7 +140,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) { - smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); + smb_np_struct *p = get_rpc_pipe_p(SVAL(inbuf,smb_vwv0)); uint16 vuid = SVAL(inbuf,smb_uid); size_t numtowrite = SVAL(inbuf,smb_vwv1); int nwritten; @@ -185,7 +185,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) { - smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); + smb_np_struct *p = get_rpc_pipe_p(SVAL(inbuf,smb_vwv2)); uint16 vuid = SVAL(inbuf,smb_uid); size_t numtowrite = SVAL(inbuf,smb_vwv10); int nwritten = -1; @@ -247,7 +247,7 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) { - smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); + smb_np_struct *p = get_rpc_pipe_p(SVAL(inbuf,smb_vwv2)); int smb_maxcnt = SVAL(inbuf,smb_vwv5); int smb_mincnt = SVAL(inbuf,smb_vwv6); int nread = -1; @@ -292,7 +292,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) void reply_pipe_close(connection_struct *conn, struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p((char *)req->inbuf,smb_vwv0); + smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv0)); if (!p) { reply_doserror(req, ERRDOS, ERRbadfid); -- cgit From a6810cb9a303d31dfedfb4bdc52f4d4df7e4eb90 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 8 Aug 2007 18:40:26 +0000 Subject: r24278: Push down reply_prep_legacy in reply_write_and_X Remove the need for reply_prep_legacy for reply_pipe_write_and_X (This used to be commit de143d5fa61aa487613dda729a43dc3d59a72899) --- source3/smbd/pipes.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 24e0f47001..cf12b4be4d 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -183,26 +183,29 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) wrinkles to handle pipes. ****************************************************************************/ -int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) +void reply_pipe_write_and_X(struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p(SVAL(inbuf,smb_vwv2)); - uint16 vuid = SVAL(inbuf,smb_uid); - size_t numtowrite = SVAL(inbuf,smb_vwv10); + smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv2)); + size_t numtowrite = SVAL(req->inbuf,smb_vwv10); int nwritten = -1; - int smb_doff = SVAL(inbuf, smb_vwv11); - BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) == - (PIPE_START_MESSAGE|PIPE_RAW_MODE)); + int smb_doff = SVAL(req->inbuf, smb_vwv11); + BOOL pipe_start_message_raw = + ((SVAL(req->inbuf, smb_vwv7) + & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) + == (PIPE_START_MESSAGE|PIPE_RAW_MODE)); char *data; if (!p) { - return(ERROR_DOS(ERRDOS,ERRbadfid)); + reply_doserror(req, ERRDOS, ERRbadfid); + return; } - if (p->vuid != vuid) { - return ERROR_NT(NT_STATUS_INVALID_HANDLE); + if (p->vuid != req->vuid) { + reply_nterror(req, NT_STATUS_INVALID_HANDLE); + return; } - data = smb_base(inbuf) + smb_doff; + data = smb_base(req->inbuf) + smb_doff; if (numtowrite == 0) { nwritten = 0; @@ -214,9 +217,12 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) * them (we don't trust the client). JRA. */ if(numtowrite < 2) { - DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n", - (unsigned int)numtowrite )); - return (UNIXERROR(ERRDOS,ERRnoaccess)); + DEBUG(0,("reply_pipe_write_and_X: start of " + "message set and not enough data " + "sent.(%u)\n", + (unsigned int)numtowrite )); + reply_unixerror(req, ERRDOS, ERRnoaccess); + return; } data += 2; @@ -226,17 +232,18 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) } if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { - return (UNIXERROR(ERRDOS,ERRnoaccess)); + reply_unixerror(req, ERRDOS,ERRnoaccess); + return; } - - set_message(inbuf,outbuf,6,0,True); + + reply_outbuf(req, 6, 0); nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten); - SSVAL(outbuf,smb_vwv2,nwritten); + SSVAL(req->outbuf,smb_vwv2,nwritten); DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); - return chain_reply(inbuf,&outbuf,length,bufsize); + chain_reply_new(req); } /**************************************************************************** -- cgit From 8e146e4b7b284a4e89eea11272407c57090af395 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 11 Aug 2007 10:53:36 +0000 Subject: r24324: No reply_prep_legacy() in reply_pipe_read_and_X (This used to be commit 304843315c5457ff0288d66d31f1ddb1ef2796f4) --- source3/smbd/pipes.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index cf12b4be4d..7a221fa37e 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -252,11 +252,11 @@ void reply_pipe_write_and_X(struct smb_request *req) wrinkles to handle pipes. ****************************************************************************/ -int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) +void reply_pipe_read_and_X(struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p(SVAL(inbuf,smb_vwv2)); - int smb_maxcnt = SVAL(inbuf,smb_vwv5); - int smb_mincnt = SVAL(inbuf,smb_vwv6); + smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv2)); + int smb_maxcnt = SVAL(req->inbuf,smb_vwv5); + int smb_mincnt = SVAL(req->inbuf,smb_vwv6); int nread = -1; char *data; BOOL unused; @@ -265,32 +265,35 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) is deliberate, instead we always return the next lump of data on the pipe */ #if 0 - uint32 smb_offs = IVAL(inbuf,smb_vwv3); + uint32 smb_offs = IVAL(req->inbuf,smb_vwv3); #endif if (!p) { - return(ERROR_DOS(ERRDOS,ERRbadfid)); + reply_doserror(req, ERRDOS, ERRbadfid); + return; } - set_message(inbuf,outbuf,12,0,True); - data = smb_buf(outbuf); + reply_outbuf(req, 12, smb_maxcnt); + + data = smb_buf(req->outbuf); nread = read_from_pipe(p, data, smb_maxcnt, &unused); if (nread < 0) { - return(UNIXERROR(ERRDOS,ERRnoaccess)); + reply_doserror(req, ERRDOS, ERRnoaccess); + return; } + + set_message(NULL, (char *)req->outbuf, 12, nread, False); - SSVAL(outbuf,smb_vwv5,nread); - SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); - SSVAL(smb_buf(outbuf),-2,nread); + SSVAL(req->outbuf,smb_vwv5,nread); + SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf)); + SSVAL(smb_buf(req->outbuf),-2,nread); DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n", p->pnum, smb_mincnt, smb_maxcnt, nread)); - /* Ensure we set up the message length to include the data length read. */ - set_message_bcc(inbuf,outbuf,nread); - return chain_reply(inbuf,&outbuf,length,bufsize); + return chain_reply_new(req); } /**************************************************************************** -- cgit From bf47a89c98aaf05d083e67bc02dc8efd3827c9cc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 11 Aug 2007 11:50:53 +0000 Subject: r24326: Fix the build for Solaris CC (This used to be commit 7af4c1f547accc973f8b3ed88958bdeaf941754a) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 7a221fa37e..bf4567ddb9 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -293,7 +293,7 @@ void reply_pipe_read_and_X(struct smb_request *req) DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n", p->pnum, smb_mincnt, smb_maxcnt, nread)); - return chain_reply_new(req); + chain_reply_new(req); } /**************************************************************************** -- cgit From 7c25bf4511161cb7d3da8c27ca74b73c02b8841f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Aug 2007 18:16:04 +0000 Subject: r24425: Convert reply_write to the new API (This used to be commit 244965f7b67becb85774311e6ce84318d554384d) --- source3/smbd/pipes.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index bf4567ddb9..e8a496ffa7 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -138,24 +138,24 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) Reply to a write on a pipe. ****************************************************************************/ -int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) +void reply_pipe_write(struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p(SVAL(inbuf,smb_vwv0)); - uint16 vuid = SVAL(inbuf,smb_uid); - size_t numtowrite = SVAL(inbuf,smb_vwv1); + smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv0)); + size_t numtowrite = SVAL(req->inbuf,smb_vwv1); int nwritten; - int outsize; char *data; if (!p) { - return(ERROR_DOS(ERRDOS,ERRbadfid)); + reply_doserror(req, ERRDOS, ERRbadfid); + return; } - if (p->vuid != vuid) { - return ERROR_NT(NT_STATUS_INVALID_HANDLE); + if (p->vuid != req->vuid) { + reply_nterror(req, NT_STATUS_INVALID_HANDLE); + return; } - data = smb_buf(inbuf) + 3; + data = smb_buf(req->inbuf) + 3; if (numtowrite == 0) { nwritten = 0; @@ -164,16 +164,17 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) } if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { - return (UNIXERROR(ERRDOS,ERRnoaccess)); + reply_unixerror(req, ERRDOS, ERRnoaccess); + return; } - - outsize = set_message(inbuf,outbuf,1,0,True); - SSVAL(outbuf,smb_vwv0,nwritten); + reply_outbuf(req, 1, 0); + + SSVAL(req->outbuf,smb_vwv0,nwritten); DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); - return(outsize); + return; } /**************************************************************************** -- cgit From b578db69e91a088f158c1cd78a71d00045fc1da6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 27 Aug 2007 12:04:09 +0000 Subject: r24702: Remove the old API pointers (This used to be commit 17df313db42199e26d7d2044f6a1d845aacd1a90) --- source3/smbd/pipes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index e8a496ffa7..f43e243453 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -130,7 +130,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) SSVAL(req->outbuf,smb_vwv8,rmode); SSVAL(req->outbuf,smb_vwv11,0x0001); - chain_reply_new(req); + chain_reply(req); return; } @@ -244,7 +244,7 @@ void reply_pipe_write_and_X(struct smb_request *req) DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); - chain_reply_new(req); + chain_reply(req); } /**************************************************************************** @@ -294,7 +294,7 @@ void reply_pipe_read_and_X(struct smb_request *req) DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n", p->pnum, smb_mincnt, smb_maxcnt, nread)); - chain_reply_new(req); + chain_reply(req); } /**************************************************************************** -- cgit From d5c9d87946263b5f3e3c072aa99e8ac6a6c728b9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Sep 2007 23:50:21 +0000 Subject: r25118: More pstring elimination. Jeremy. (This used to be commit 7632f8fb4003657591778d2b55f546d1737859d1) --- source3/smbd/pipes.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index f43e243453..9906bfb45b 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -55,15 +55,21 @@ extern struct pipe_id_info pipe_names[]; void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) { - pstring fname; - pstring pipe_name; + const char *fname = NULL; + char *pipe_name = NULL; smb_np_struct *p; int size=0,fmode=0,mtime=0,rmode=0; int i; + TALLOC_CTX *ctx = talloc_tos(); /* XXXX we need to handle passed times, sattr and flags */ - srvstr_pull_buf(req->inbuf, req->flags2, pipe_name, - smb_buf(req->inbuf), sizeof(pipe_name), STR_TERMINATE); + srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &pipe_name, + smb_buf(req->inbuf), STR_TERMINATE); + if (!pipe_name) { + reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, + ERRDOS, ERRbadpipe); + return; + } /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ @@ -89,7 +95,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) } /* Strip \PIPE\ off the name. */ - pstrcpy(fname, pipe_name + PIPELEN); + fname = pipe_name + PIPELEN; #if 0 /* -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/smbd/pipes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 9906bfb45b..da43a29767 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -291,7 +291,7 @@ void reply_pipe_read_and_X(struct smb_request *req) return; } - set_message(NULL, (char *)req->outbuf, 12, nread, False); + set_message((char *)req->outbuf, 12, nread, False); SSVAL(req->outbuf,smb_vwv5,nread); SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf)); -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/smbd/pipes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index da43a29767..0ddc00c767 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -196,7 +196,7 @@ void reply_pipe_write_and_X(struct smb_request *req) size_t numtowrite = SVAL(req->inbuf,smb_vwv10); int nwritten = -1; int smb_doff = SVAL(req->inbuf, smb_vwv11); - BOOL pipe_start_message_raw = + bool pipe_start_message_raw = ((SVAL(req->inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) == (PIPE_START_MESSAGE|PIPE_RAW_MODE)); @@ -266,7 +266,7 @@ void reply_pipe_read_and_X(struct smb_request *req) int smb_mincnt = SVAL(req->inbuf,smb_vwv6); int nread = -1; char *data; - BOOL unused; + bool unused; /* we don't use the offset given to use for pipe reads. This is deliberate, instead we always return the next lump of -- cgit From afc93255d183eefb68e45b8ec6275f6a62cf9795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/smbd/pipes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 0ddc00c767..88b67c03e5 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -291,7 +291,8 @@ void reply_pipe_read_and_X(struct smb_request *req) return; } - set_message((char *)req->outbuf, 12, nread, False); + srv_set_message((const char *)req->inbuf, + (char *)req->outbuf, 12, nread, False); SSVAL(req->outbuf,smb_vwv5,nread); SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf)); -- cgit From 9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 12:56:23 -0800 Subject: Refactor the crypto code after a very helpful conversation with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8) --- source3/smbd/pipes.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 88b67c03e5..6b4b83d97d 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -291,8 +291,7 @@ void reply_pipe_read_and_X(struct smb_request *req) return; } - srv_set_message((const char *)req->inbuf, - (char *)req->outbuf, 12, nread, False); + srv_set_message((char *)req->outbuf, 12, nread, False); SSVAL(req->outbuf,smb_vwv5,nread); SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf)); -- cgit From 2e7cb1a5ccf8ae513a432cef9ccebfcebe4241ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jul 2008 20:27:56 +0200 Subject: Introduce is_known_pipename This scans the list of pipes registered via rpc_pipe_register_commands instead of using static tables. (This used to be commit 283e6039989adea1c8921b3600b410cb67b6492a) --- source3/smbd/pipes.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'source3/smbd/pipes.c') diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 6b4b83d97d..4fdcdcc557 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -44,9 +44,6 @@ struct pipe_dbrec { fstring user; }; - -extern struct pipe_id_info pipe_names[]; - /**************************************************************************** Reply to an open and X on a named pipe. This code is basically stolen from reply_open_and_X with some @@ -59,7 +56,6 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) char *pipe_name = NULL; smb_np_struct *p; int size=0,fmode=0,mtime=0,rmode=0; - int i; TALLOC_CTX *ctx = talloc_tos(); /* XXXX we need to handle passed times, sattr and flags */ @@ -82,13 +78,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) DEBUG(4,("Opening pipe %s.\n", pipe_name)); /* See if it is one we want to handle. */ - for( i = 0; pipe_names[i].client_pipe ; i++ ) { - if( strequal(pipe_name,pipe_names[i].client_pipe)) { - break; - } - } - - if (pipe_names[i].client_pipe == NULL) { + if (!is_known_pipename(pipe_name)) { reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, ERRDOS, ERRbadpipe); return; -- cgit