Unix SMB/Netbios implementation.
Version 1.9.
Main SMB reply routines
- Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Andrew Tridgell 1992-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
extern BOOL case_preserve;
extern BOOL short_case_preserve;
extern pstring sesssetup_user;
-extern fstring myworkgroup;
+extern fstring global_myworkgroup;
extern int Client;
extern int global_oplock_break;
****************************************************************************/
static void overflow_attack(int len)
{
- DEBUG(0,("ERROR: Invalid password length %d\n", len));
+ DEBUG(0,("%s: ERROR: Invalid password length %d\n", timestring(), len));
DEBUG(0,("your machine may be under attack by a user exploiting an old bug\n"));
- DEBUG(0,("Attack was from IP=%s\n", client_addr()));
+ DEBUG(0,("Attack was from IP=%s\n", client_addr(Client)));
exit_server("possible attack");
}
pstring name1,name2;
extern fstring remote_machine;
extern fstring local_machine;
- char *p;
int len;
char name_type = 0;
name1,name2));
fstrcpy(remote_machine,name2);
+ remote_machine[15] = 0;
trim_string(remote_machine," "," ");
- p = strchr(remote_machine,' ');
strlower(remote_machine);
- if (p) *p = 0;
fstrcpy(local_machine,name1);
- trim_string(local_machine," "," ");
len = strlen(local_machine);
if (len == 16) {
name_type = local_machine[15];
local_machine[15] = 0;
}
- p = strchr(local_machine,' ');
+ trim_string(local_machine," "," ");
strlower(local_machine);
- if (p) *p = 0;
if (name_type == 'R') {
/* We are being asked for a pathworks session ---
reload_services(True);
reopen_logs();
+ if (lp_status(-1)) {
+ claim_connection(-1,"STATUS.",MAXSTATUS,True);
+ }
+
break;
case 0x89: /* session keepalive request
/****************************************************************************
reply to a tcon
****************************************************************************/
-int reply_tcon(char *inbuf,char *outbuf)
+int reply_tcon(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring service;
pstring user;
int connection_num;
uint16 vuid = SVAL(inbuf,smb_uid);
int passlen = SVAL(inbuf,smb_vwv3);
- BOOL doencrypt = SMBENCRYPT();
*service = *user = *password = *devicename = 0;
password[passlen]=0;
path = smb_buf(inbuf) + passlen;
- if (!doencrypt || passlen != 24) {
+ if (passlen != 24) {
if (strequal(password," "))
*password = 0;
passlen = strlen(password);
}
else
{
- char *fsname = "SAMBA";
+ char *fsname = FSTYPE_STRING;
char *p;
set_message(outbuf,3,3,True);
/****************************************************************************
reply to an ioctl
****************************************************************************/
-int reply_ioctl(char *inbuf,char *outbuf)
+int reply_ioctl(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
DEBUG(3,("ignoring ioctl\n"));
#if 0
#endif
}
+/****************************************************************************
+ always return an error: it's just a matter of which one...
+ ****************************************************************************/
+static int session_trust_account(char *inbuf, char *outbuf, char *user,
+ char *smb_passwd, int smb_passlen,
+ char *smb_nt_passwd, int smb_nt_passlen)
+{
+ struct smb_passwd *smb_trust_acct = NULL; /* check if trust account exists */
+ if (lp_security() == SEC_USER)
+ {
+ smb_trust_acct = getsmbpwnam(user);
+ }
+ else
+ {
+ DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+ }
+
+ if (smb_trust_acct == NULL)
+ {
+ /* lkclXXXX: workstation entry doesn't exist */
+ DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_NO_SUCH_USER));
+ }
+ else
+ {
+ if ((smb_passlen != 24) || (smb_nt_passlen != 24))
+ {
+ DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+ }
+
+ if (!smb_password_ok(smb_trust_acct, smb_passwd, smb_nt_passwd))
+ {
+ DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+ }
+
+ if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_DOMTRUST))
+ {
+ DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT));
+ }
+
+ if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_SVRTRUST))
+ {
+ DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT));
+ }
+
+ if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_WSTRUST))
+ {
+ DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT));
+ }
+ }
+
+ /* don't know what to do: indicate logon failure */
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+}
+
/****************************************************************************
reply to a session setup command
BOOL valid_nt_password = False;
pstring user;
BOOL guest=False;
- BOOL computer_id=False;
static BOOL done_sesssetup = False;
BOOL doencrypt = SMBENCRYPT();
char *domain = "";
}
memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
+ smb_apasswd[smb_apasslen] = 0;
pstrcpy(user,smb_buf(inbuf)+smb_apasslen);
- if (lp_security() != SEC_SERVER && !doencrypt) {
+ if (!doencrypt && (lp_security() != SEC_SERVER)) {
smb_apasslen = strlen(smb_apasswd);
}
} else {
passlen1 = MIN(passlen1, MAX_PASS_LEN);
passlen2 = MIN(passlen2, MAX_PASS_LEN);
- if(doencrypt) {
+#ifdef DOMAIN_CLIENT
+ if(doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
+#else /* DOMAIN_CLIENT */
+ if(doencrypt || lp_security() == SEC_SERVER) {
+#endif /* DOMAIN_CLIENT */
/* Save the lanman2 password and the NT md4 password. */
smb_apasslen = passlen1;
memcpy(smb_apasswd,p,smb_apasslen);
+ smb_apasswd[smb_apasslen] = 0;
smb_ntpasslen = passlen2;
memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
+ smb_ntpasswd[smb_ntpasslen] = 0;
} else {
/* both Win95 and WinNT stuff up the password lengths for
non-encrypting systems. Uggh.
/* If name ends in $ then I think it's asking about whether a */
/* computer with that name (minus the $) has access. For now */
/* say yes to everything ending in $. */
- if (user[strlen(user) - 1] == '$') {
-#ifdef NTDOMAIN
- struct smb_passwd *smb_pass; /* To check if machine account exists */
-/*
- PAXX: Ack. We don't want to do this. The workstation trust account
- with a $ on the end should exist in the local password database
- or be mapped to something generic, but not modified. For NT
- domain support we must reject this used in certain circumstances
- with a code to indicate to the client that it is an invalid use
- of a workstation trust account. NTWKS needs this error to join
- a domain. This may be the source of future bugs if we cannot
- be sure whether to reject this or not.
-*/
- smb_pass = get_smbpwnam(user);
- if(smb_pass)
- {
- /* PAXX: This is the NO LOGON workstation trust account stuff */
- DEBUG(4,("Rejecting workstation trust account %s",user));
- SSVAL(outbuf, smb_flg2, 0xc003); /* PAXX: Someone please unhack this */
- CVAL(outbuf, smb_reh) = 1; /* PAXX: Someone please unhack this */
- return(ERROR(NT_STATUS_ALLOTTED_SPACE_EXCEEDED, 0xc000)); /* 0x99 NT error, 0xc00 */
- }
- computer_id = True;
-#else /* not NTDOMAIN, leave this in. PAXX: Someone get rid of this */
- user[strlen(user) - 1] = '\0';
-#endif
+ if ((user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24))
+ {
+ return session_trust_account(inbuf, outbuf, user,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen);
}
-
/* If no username is sent use the guest account */
if (!*user)
{
server_validate(user, domain,
smb_apasswd, smb_apasslen,
smb_ntpasswd, smb_ntpasslen)) &&
+#ifdef DOMAIN_CLIENT
+ !(lp_security() == SEC_DOMAIN &&
+ domain_client_validate(user, domain,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen)) &&
+#endif /* DOMAIN_CLIENT */
!check_hosts_equiv(user))
{
}
if (!valid_nt_password && !password_ok(user,smb_apasswd,smb_apasslen,NULL))
{
- if (!computer_id && lp_security() >= SEC_USER) {
+ if (lp_security() >= SEC_USER) {
#if (GUEST_SESSSETUP == 0)
return(ERROR(ERRSRV,ERRbadpw));
#endif
p = smb_buf(outbuf);
strcpy(p,"Unix"); p = skip_string(p,1);
strcpy(p,"Samba "); strcat(p,VERSION); p = skip_string(p,1);
- strcpy(p,myworkgroup); p = skip_string(p,1);
+ strcpy(p,global_myworkgroup); p = skip_string(p,1);
set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
/* perhaps grab OS version here?? */
}
uid = pw->pw_uid;
}
- if (guest && !computer_id)
+ if (guest)
SSVAL(outbuf,smb_vwv2,1);
/* register the name and uid as being validated, so further connections
/****************************************************************************
reply to a chkpth
****************************************************************************/
-int reply_chkpth(char *inbuf,char *outbuf)
+int reply_chkpth(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = 0;
int cnum,mode;
/****************************************************************************
reply to a getatr
****************************************************************************/
-int reply_getatr(char *inbuf,char *outbuf)
+int reply_getatr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring fname;
int cnum;
outsize = set_message(outbuf,10,0,True);
SSVAL(outbuf,smb_vwv0,mode);
- put_dos_date3(outbuf,smb_vwv1,mtime);
+ if(lp_dos_filetime_resolution(SNUM(cnum)) )
+ put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv1,mtime);
SIVAL(outbuf,smb_vwv3,size);
if (Protocol >= PROTOCOL_NT1) {
/****************************************************************************
reply to a setatr
****************************************************************************/
-int reply_setatr(char *inbuf,char *outbuf)
+int reply_setatr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring fname;
int cnum;
/****************************************************************************
reply to a dskattr
****************************************************************************/
-int reply_dskattr(char *inbuf,char *outbuf)
+int reply_dskattr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum;
int outsize = 0;
reply to a search
Can be called from SMBsearch, SMBffirst or SMBfunique.
****************************************************************************/
-int reply_search(char *inbuf,char *outbuf)
+int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring mask;
pstring directory;
if ((dirtype&0x1F) == aVOLID)
{
memcpy(p,status,21);
- mode = aVOLID;
- if(!CAN_WRITE(cnum)) mode |= aRONLY;
- make_dir_struct(p,"???????????",volume_label(SNUM(cnum)),0,mode,0);
+ make_dir_struct(p,"???????????",volume_label(SNUM(cnum)),0,aVOLID,0);
dptr_fill(p+12,dptr_num);
if (dptr_zero(p+12) && (status_len==0))
numentries = 1;
/****************************************************************************
reply to a fclose (stop directory search)
****************************************************************************/
-int reply_fclose(char *inbuf,char *outbuf)
+int reply_fclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum;
int outsize = 0;
/****************************************************************************
reply to an open
****************************************************************************/
-int reply_open(char *inbuf,char *outbuf)
+int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring fname;
int cnum;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
outsize = set_message(outbuf,7,0,True);
SSVAL(outbuf,smb_vwv0,fnum);
SSVAL(outbuf,smb_vwv1,fmode);
- put_dos_date3(outbuf,smb_vwv2,mtime);
+ if(lp_dos_filetime_resolution(SNUM(cnum)) )
+ put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv2,mtime);
SIVAL(outbuf,smb_vwv4,size);
SSVAL(outbuf,smb_vwv6,rmode);
int fnum = -1;
int smb_mode = SVAL(inbuf,smb_vwv3);
int smb_attr = SVAL(inbuf,smb_vwv5);
- BOOL oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
+ /* Breakout the oplock request bits so we can set the
+ reply bits separately. */
+ BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
+ BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ BOOL oplock_request = ex_oplock_request | core_oplock_request;
#if 0
int open_flags = SVAL(inbuf,smb_vwv2);
int smb_sattr = SVAL(inbuf,smb_vwv4);
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
return(ERROR(ERRDOS,ERRnoaccess));
}
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+ /* If the caller set the extended oplock request bit
+ and we granted one (by whatever means) - set the
+ correct bit for extended oplock reply.
+ */
+
+ if (ex_oplock_request && lp_fake_oplocks(SNUM(cnum))) {
smb_action |= EXTENDED_OPLOCK_GRANTED;
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if(fsp->granted_oplock) {
+ if(ex_oplock_request && fsp->granted_oplock) {
smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
+
+ /* If the caller set the core oplock request bit
+ and we granted one (by whatever means) - set the
+ correct bit for core oplock reply.
+ */
+
+ if (core_oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ }
+
+ if(core_oplock_request && fsp->granted_oplock) {
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
set_message(outbuf,15,0,True);
SSVAL(outbuf,smb_vwv2,fnum);
SSVAL(outbuf,smb_vwv3,fmode);
- put_dos_date3(outbuf,smb_vwv4,mtime);
+ if(lp_dos_filetime_resolution(SNUM(cnum)) )
+ put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv4,mtime);
SIVAL(outbuf,smb_vwv6,size);
SSVAL(outbuf,smb_vwv8,rmode);
SSVAL(outbuf,smb_vwv11,smb_action);
if ((vuser != 0) && (lp_security() != SEC_SHARE)) {
int i;
for (i=0;i<MAX_OPEN_FILES;i++)
- if (Files[i].uid == vuser->uid && Files[i].open) {
+ if ((Files[i].vuid == vuid) && Files[i].open) {
close_file(i,False);
}
}
/****************************************************************************
reply to a mknew or a create
****************************************************************************/
-int reply_mknew(char *inbuf,char *outbuf)
+int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring fname;
int cnum,com;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
/****************************************************************************
reply to a create temporary file
****************************************************************************/
-int reply_ctemp(char *inbuf,char *outbuf)
+int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring fname;
pstring fname2;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
}
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
return(False);
- if (!check_file_sharing(cnum,fname)) return(False);
+ if (!check_file_sharing(cnum,fname,False)) return(False);
return(True);
}
/****************************************************************************
reply to a unlink
****************************************************************************/
-int reply_unlink(char *inbuf,char *outbuf)
+int reply_unlink(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = 0;
pstring name;
}
if (is_mangled(mask))
- check_mangled_stack(mask);
+ check_mangled_cache( mask );
has_wild = strchr(mask,'*') || strchr(mask,'?');
/****************************************************************************
reply to a readbraw (core+ protocol)
****************************************************************************/
-int reply_readbraw(char *inbuf, char *outbuf)
+int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,maxcount,mincount,fnum;
int nread = 0;
/****************************************************************************
reply to a lockread (core+ protocol)
****************************************************************************/
-int reply_lockread(char *inbuf,char *outbuf)
+int reply_lockread(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz)
{
int cnum,fnum;
int nread = -1;
/****************************************************************************
reply to a read
****************************************************************************/
-int reply_read(char *inbuf,char *outbuf)
+int reply_read(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,numtoread,fnum;
int nread = 0;
cnum = SVAL(inbuf,smb_tid);
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(cnum))
+ return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
+
CHECK_FNUM(fnum,cnum);
CHECK_READ(fnum);
CHECK_ERROR(fnum);
/****************************************************************************
reply to a writebraw (core+ or LANMAN1.0 protocol)
****************************************************************************/
-int reply_writebraw(char *inbuf,char *outbuf)
+int reply_writebraw(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int nwritten=0;
int total_written=0;
/****************************************************************************
reply to a writeunlock (core+)
****************************************************************************/
-int reply_writeunlock(char *inbuf,char *outbuf)
+int reply_writeunlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,fnum;
int nwritten = -1;
/****************************************************************************
reply to a write
****************************************************************************/
-int reply_write(char *inbuf,char *outbuf,int dum1,int dum2)
+int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize)
{
int cnum,numtowrite,fnum;
int nwritten = -1;
int startpos;
char *data;
- dum1 = dum2 = 0;
-
-
cnum = SVAL(inbuf,smb_tid);
fnum = GETFNUM(inbuf,smb_vwv0);
/****************************************************************************
reply to a lseek
****************************************************************************/
-int reply_lseek(char *inbuf,char *outbuf)
+int reply_lseek(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,fnum;
uint32 startpos;
/****************************************************************************
reply to a flush
****************************************************************************/
-int reply_flush(char *inbuf,char *outbuf)
+int reply_flush(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum, fnum;
int outsize = set_message(outbuf,0,0,True);
/****************************************************************************
reply to a exit
****************************************************************************/
-int reply_exit(char *inbuf,char *outbuf)
+int reply_exit(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = set_message(outbuf,0,0,True);
DEBUG(3,("%s exit\n",timestring()));
/****************************************************************************
reply to a close
****************************************************************************/
-int reply_close(char *inbuf,char *outbuf)
+int reply_close(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int fnum,cnum;
int outsize = 0;
/* try and set the date */
set_filetime(cnum, Files[fnum].name,mtime);
+ DEBUG(3,("%s close fd=%d fnum=%d cnum=%d (numopen=%d)\n",
+ timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,
+ Connections[cnum].num_files_open));
+
close_file(fnum,True);
/* We have a cached error */
if(eclass || err)
return(ERROR(eclass,err));
- DEBUG(3,("%s close fd=%d fnum=%d cnum=%d (numopen=%d)\n",
- timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,
- Connections[cnum].num_files_open));
-
return(outsize);
}
/****************************************************************************
reply to a writeclose (Core+ protocol)
****************************************************************************/
-int reply_writeclose(char *inbuf,char *outbuf)
+int reply_writeclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,numtowrite,fnum;
int nwritten = -1;
/****************************************************************************
reply to a lock
****************************************************************************/
-int reply_lock(char *inbuf,char *outbuf)
+int reply_lock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int fnum,cnum;
int outsize = set_message(outbuf,0,0,True);
/****************************************************************************
reply to a unlock
****************************************************************************/
-int reply_unlock(char *inbuf,char *outbuf)
+int reply_unlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int fnum,cnum;
int outsize = set_message(outbuf,0,0,True);
/****************************************************************************
reply to a tdis
****************************************************************************/
-int reply_tdis(char *inbuf,char *outbuf)
+int reply_tdis(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum;
int outsize = set_message(outbuf,0,0,True);
/****************************************************************************
reply to a echo
****************************************************************************/
-int reply_echo(char *inbuf,char *outbuf)
+int reply_echo(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum;
int smb_reverb = SVAL(inbuf,smb_vwv0);
/****************************************************************************
reply to a printopen
****************************************************************************/
-int reply_printopen(char *inbuf,char *outbuf)
+int reply_printopen(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring fname;
pstring fname2;
strcpy(fname2,(char *)mktemp(fname));
- if (!check_name(fname2,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
+ if (!check_name(fname2,cnum)) {
+ Files[fnum].reserved = False;
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
/* Open for exclusive use, write only. */
open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0),
0, NULL, NULL);
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ if (!Files[fnum].open) {
+ Files[fnum].reserved = False;
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
/* force it to be a print file */
Files[fnum].print_file = True;
/****************************************************************************
reply to a printclose
****************************************************************************/
-int reply_printclose(char *inbuf,char *outbuf)
+int reply_printclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int fnum,cnum;
int outsize = set_message(outbuf,0,0,True);
if (!CAN_PRINT(cnum))
return(ERROR(ERRDOS,ERRnoaccess));
- close_file(fnum,True);
-
DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum));
+ close_file(fnum,True);
+
return(outsize);
}
/****************************************************************************
reply to a printqueue
****************************************************************************/
-int reply_printqueue(char *inbuf,char *outbuf)
+int reply_printqueue(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum;
int outsize = set_message(outbuf,2,3,True);
/****************************************************************************
reply to a printwrite
****************************************************************************/
-int reply_printwrite(char *inbuf,char *outbuf)
+int reply_printwrite(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,numtowrite,fnum;
int outsize = set_message(outbuf,0,0,True);
/****************************************************************************
reply to a mkdir
****************************************************************************/
-int reply_mkdir(char *inbuf,char *outbuf)
+int reply_mkdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring directory;
int cnum;
/****************************************************************************
reply to a rmdir
****************************************************************************/
-int reply_rmdir(char *inbuf,char *outbuf)
+int reply_rmdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring directory;
int cnum;
if (!CAN_WRITE(cnum)) return(False);
if (sys_lstat(fname,&sbuf) != 0) return(False);
- if (!check_file_sharing(cnum,fname)) return(False);
+ if (!check_file_sharing(cnum,fname,True)) return(False);
return(True);
}
/****************************************************************************
reply to a mv
****************************************************************************/
-int reply_mv(char *inbuf,char *outbuf)
+int reply_mv(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = 0;
pstring name;
}
if (is_mangled(mask))
- check_mangled_stack(mask);
+ check_mangled_cache( mask );
has_wild = strchr(mask,'*') || strchr(mask,'?');
error = ERRnoaccess;
sprintf(fname,"%s/%s",directory,dname);
- if (!can_rename(fname,cnum)) continue;
+ if (!can_rename(fname,cnum)) {
+ DEBUG(6,("rename %s refused\n", fname));
+ continue;
+ }
pstrcpy(destname,newname);
- if (!resolve_wildcards(fname,destname)) continue;
+ if (!resolve_wildcards(fname,destname)) {
+ DEBUG(6,("resolve_wildcards %s %s failed\n",
+ fname, destname));
+ continue;
+ }
if (file_exist(destname,NULL)) {
- error = 183;
- continue;
+ DEBUG(6,("file_exist %s\n",
+ destname));
+ error = 183;
+ continue;
}
if (!sys_rename(fname,destname)) count++;
DEBUG(3,("reply_mv : doing rename on %s -> %s\n",fname,destname));
open_file_shared(fnum1,cnum,src,(DENY_NONE<<4),
1,0,0,&Access,&action);
- if (!Files[fnum1].open) return(False);
+ if (!Files[fnum1].open) {
+ Files[fnum1].reserved = False;
+ return(False);
+ }
if (!target_is_directory && count)
ofun = 1;
if (!Files[fnum2].open) {
close_file(fnum1,False);
+ Files[fnum2].reserved = False;
return(False);
}
/****************************************************************************
reply to a file copy.
****************************************************************************/
-int reply_copy(char *inbuf,char *outbuf)
+int reply_copy(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = 0;
pstring name;
}
if (is_mangled(mask))
- check_mangled_stack(mask);
+ check_mangled_cache( mask );
has_wild = strchr(mask,'*') || strchr(mask,'?');
/****************************************************************************
reply to a setdir
****************************************************************************/
-int reply_setdir(char *inbuf,char *outbuf)
+int reply_setdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,snum;
int outsize = 0;
/* if this is a pure oplock break request then don't send a reply */
if (num_locks == 0 && num_ulocks == 0)
- return -1;
+ {
+ /* Sanity check - ensure a pure oplock break is not a
+ chained request. */
+ if(CVAL(inbuf,smb_vwv0) != 0xff)
+ DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
+ (unsigned int)CVAL(inbuf,smb_vwv0) ));
+ return -1;
+ }
}
/* Data now points at the beginning of the list
/****************************************************************************
reply to a SMBwritebmpx (write block multiplex primary) request
****************************************************************************/
-int reply_writebmpx(char *inbuf,char *outbuf)
+int reply_writebmpx(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,numtowrite,fnum;
int nwritten = -1;
/****************************************************************************
reply to a SMBwritebs (write block multiplex secondary) request
****************************************************************************/
-int reply_writebs(char *inbuf,char *outbuf)
+int reply_writebs(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,numtowrite,fnum;
int nwritten = -1;
/****************************************************************************
reply to a SMBsetattrE
****************************************************************************/
-int reply_setattrE(char *inbuf,char *outbuf)
+int reply_setattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,fnum;
struct utimbuf unix_times;
/****************************************************************************
reply to a SMBgetattrE
****************************************************************************/
-int reply_getattrE(char *inbuf,char *outbuf)
+int reply_getattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int cnum,fnum;
struct stat sbuf;
/* Convert the times into dos times. Set create
date to be last modify date as UNIX doesn't save
this */
- put_dos_date2(outbuf,smb_vwv0,sbuf.st_mtime);
+ put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum))));
put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
if (mode & aDIR)