1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

First implementation of ChangeNotify - this version only checks

for changes in the directory modify timestamps. A better version
will look at the requested client flags, and create a hash that
represents the current state of the directory, and check against
this instead.
debug.c: Added lp_timestamp_logs() function.
loadparm.c: Added "change notify timeout" in seconds (default 60)
- this is the scan rate for a directory.
            Added ""timestamp logs" boolean - default True. Turns
off log timestamps (so I can read them :-).
nttrans.c: ChangeNotify implementation.
server.c: ChangeNotify implementation.
shmem_sysv.c: Added exits on shmem errors (without them smbd can
              core dump if some calls fail).
smb.h: Added ChangeNotify flags for future use.
util.c: Tidied up typedef.
Jeremy.
(This used to be commit a0748c3f53974483680ebe2ea4f556ece8d7fa43)
This commit is contained in:
Jeremy Allison 1998-08-03 19:07:55 +00:00
parent 103857e8e3
commit 7448091da6
8 changed files with 344 additions and 38 deletions

View File

@ -1024,6 +1024,7 @@ BOOL lp_strip_dot(void);
BOOL lp_encrypted_passwords(void);
BOOL lp_update_encrypted(void);
BOOL lp_syslog_only(void);
BOOL lp_timestamp_logs(void);
BOOL lp_browse_list(void);
BOOL lp_unix_realname(void);
BOOL lp_nis_home_map(void);
@ -1058,6 +1059,7 @@ int lp_announce_as(void);
int lp_lm_announce(void);
int lp_lm_interval(void);
int lp_machine_password_timeout(void);
int lp_change_notify_timeout(void);
int lp_ldap_port(void);
char *lp_preexec(int );
char *lp_postexec(int );
@ -1603,6 +1605,9 @@ char *get_nt_error_msg(uint32 nt_code);
int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize);
int reply_ntcancel(char *inbuf,char *outbuf,int length,int bufsize);
int reply_nttranss(char *inbuf,char *outbuf,int length,int bufsize);
void remove_pending_change_notify_requests_by_fid(int fnum);
void remove_pending_change_notify_requests_by_mid(int mid);
void process_pending_change_notify_queue(time_t t);
int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize);
/*The following definitions come from params.c */

View File

@ -190,7 +190,7 @@ implemented */
#define STYPE_IPC 3 /* Interprocess communication (IPC) */
#define STYPE_HIDDEN 0x80000000 /* share is a hidden one (ends with $) */
/* SMB X/Open error codes for the ERRdos error class */
/* SMB X/Open error codes for the ERRDOS error class */
#define ERRbadfunc 1 /* Invalid function (or system call) */
#define ERRbadfile 2 /* File not found (pathname error) */
#define ERRbadpath 3 /* Directory not found */
@ -1076,7 +1076,7 @@ struct parm_struct
#define smb_nt_DataOffset (smb_vwv0 + 31)
#define smb_nt_SetupCount (smb_vwv0 + 35)
#define smb_nt_Function (smb_vwv0 + 36)
#define smb_nt_SetupStart (smb_vwv0 + 39)
#define smb_nt_SetupStart (smb_vwv0 + 38)
/* these are for the NT trans secondary request. */
#define smb_nts_TotalParameterCount (smb_vwv0 + 3)
@ -1195,6 +1195,17 @@ struct parm_struct
#define FILE_UNICODE_ON_DISK 0x4
#define FILE_PERISITANT_ACLS 0x8
/* ChangeNotify flags. */
#define FILE_NOTIFY_CHANGE_FILE_NAME 0x001
#define FILE_NOTIFY_CHANGE_DIR_NAME 0x002
#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x004
#define FILE_NOTIFY_CHANGE_SIZE 0x008
#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x010
#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x020
#define FILE_NOTIFY_CHANGE_CREATION 0x040
#define FILE_NOTIFY_CHANGE_EA 0x080
#define FILE_NOTIFY_CHANGE_SECURITY 0x100
/* where to find the base of the SMB packet proper */
#define smb_base(buf) (((char *)(buf))+4)

View File

@ -477,8 +477,9 @@ BOOL dbghdr( int level, char *file, char *func, int line )
return( True );
/* Print it all out at once. */
Debug1( "[%s, %d] %s%s%s(%d)\n",
timestring(), level, file, (*file)?":":"", func, line );
if(lp_timestamp_logs())
Debug1( "[%s, %d] %s%s%s(%d)\n",
timestring(), level, file, (*file)?":":"", func, line );
return( True );
} /* dbghdr */

View File

@ -2334,7 +2334,7 @@ BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
for processing.
****************************************************************************/
typedef struct smb_message_list {
typedef struct {
ubi_slNode msg_next;
char *msg_buf;
int msg_len;

View File

@ -572,7 +572,8 @@ struct shmem_ops *sysv_shm_open(int ronly)
su.val = 1;
for (i=0;i<hash_size+1;i++) {
if (semctl(sem_id, i, SETVAL, su) != 0) {
DEBUG(1,("Failed to init semaphore %d\n", i));
DEBUG(1,("Failed to init semaphore %d. Error was %s\n",
i, strerror(errno)));
}
}
}
@ -581,14 +582,16 @@ struct shmem_ops *sysv_shm_open(int ronly)
sem_id = semget(SEMAPHORE_KEY, 0, 0);
}
if (sem_id == -1) {
DEBUG(0,("Can't create or use semaphore %s\n",
DEBUG(0,("Can't create or use semaphore.Error was %s\n",
strerror(errno)));
return NULL;
}
su.buf = &sem_ds;
if (semctl(sem_id, 0, IPC_STAT, su) != 0) {
DEBUG(0,("ERROR shm_open : can't IPC_STAT\n"));
DEBUG(0,("ERROR semctl: can't IPC_STAT. Error was %s\n",
strerror(errno)));
return NULL;
}
hash_size = sem_ds.sem_nsems-1;
@ -604,18 +607,18 @@ struct shmem_ops *sysv_shm_open(int ronly)
pid));
su.val = 1;
if (semctl(sem_id, 0, SETVAL, su) != 0) {
DEBUG(0,("ERROR: Failed to clear global lock\n"));
DEBUG(0,("ERROR: Failed to clear global lock. Error was %s\n",
strerror(errno)));
}
}
sem_ds.sem_perm.mode = SEMAPHORE_PERMS;
if (semctl(sem_id, 0, IPC_SET, su) != 0) {
DEBUG(0,("ERROR shm_open : can't IPC_SET\n"));
DEBUG(0,("ERROR shmctl : can't IPC_SET. Error was %s\n",
strerror(errno)));
}
}
if (!global_lock())
return NULL;
@ -627,7 +630,8 @@ struct shmem_ops *sysv_shm_open(int ronly)
i, pid));
su.val = 1;
if (semctl(sem_id, i, SETVAL, su) != 0) {
DEBUG(0,("ERROR: Failed to clear IPC lock %d\n", i));
DEBUG(0,("ERROR: Failed to clear IPC lock %d. Error was %s\n",
i, strerror(errno)));
}
}
}
@ -674,7 +678,7 @@ struct shmem_ops *sysv_shm_open(int ronly)
we use a registration file containing the processids of the file
mapping processes */
if (shmctl(shm_id, IPC_STAT, &shm_ds) != 0) {
DEBUG(0,("ERROR shm_open : can't IPC_STAT. Error was %s\n", strerror(errno)));
DEBUG(0,("ERROR shmctl : can't IPC_STAT. Error was %s\n", strerror(errno)));
}
if (!read_only) {

View File

@ -176,6 +176,7 @@ typedef struct
int client_code_page;
int announce_as; /* This is initialised in init_globals */
int machine_password_timeout;
int change_notify_timeout;
#ifdef WITH_LDAP
int ldap_port;
#endif /* WITH_LDAP */
@ -223,6 +224,7 @@ typedef struct
BOOL bUnixPasswdSync;
BOOL bPasswdChatDebug;
BOOL bOleLockingCompat;
BOOL bTimestampLogs;
} global;
static global Globals;
@ -552,6 +554,7 @@ static struct parm_struct parm_table[] =
{"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
{"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
{"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
{"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
{"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
{"Protocol Options", P_SEP, P_SEPARATOR},
@ -573,6 +576,7 @@ static struct parm_struct parm_table[] =
{"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
{"Tuning Options", P_SEP, P_SEPARATOR},
{"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0},
{"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
{"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
{"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
@ -808,11 +812,13 @@ static void init_globals(void)
Globals.bStripDot = False;
Globals.syslog = 1;
Globals.bSyslogOnly = False;
Globals.bTimestampLogs = True;
Globals.os_level = 0;
Globals.max_ttl = 60*60*24*3; /* 3 days default */
Globals.max_wins_ttl = 60*60*24*6; /* 6 days default */
Globals.min_wins_ttl = 60*60*6; /* 6 hours default */
Globals.machine_password_timeout = 60*60*24*7; /* 7 days default */
Globals.max_ttl = 60*60*24*3; /* 3 days default. */
Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */
Globals.machine_password_timeout = 60*60*24*7; /* 7 days default. */
Globals.change_notify_timeout = 60; /* 1 minute default. */
Globals.ReadSize = 16*1024;
Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
Globals.lm_interval = 60;
@ -1115,6 +1121,7 @@ FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt)
FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
@ -1150,6 +1157,7 @@ FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout)
FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout)
#ifdef WITH_LDAP
FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)

View File

@ -657,6 +657,9 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize)
chain_fnum = fnum;
DEBUG(5,("reply_ntcreate_and_X: open fnum = %d, name = %s\n",
fnum, fsp->name ));
return chain_reply(inbuf,outbuf,length,bufsize);
}
@ -737,12 +740,14 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length,
return(ERROR(ERRSRV,ERRnofids));
}
fsp = &Files[fnum];
if (!check_name(fname,cnum)) {
if((errno == ENOENT) && bad_path) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
Files[fnum].reserved = False;
fsp->reserved = False;
restore_case_semantics(file_attributes);
@ -783,14 +788,12 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length,
open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
oplock_request,&rmode,&smb_action);
fsp = &Files[fnum];
if (!fsp->open) {
if((errno == ENOENT) && bad_path) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
Files[fnum].reserved = False;
fsp->reserved = False;
restore_case_semantics(file_attributes);
@ -887,12 +890,22 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length,
}
/****************************************************************************
Reply to a NT CANCEL request - just ignore it.
Reply to a NT CANCEL request.
****************************************************************************/
int reply_ntcancel(char *inbuf,char *outbuf,int length,int bufsize)
{
DEBUG(4,("Ignoring ntcancel of length %d\n",length));
/*
* Go through and cancel any pending change notifies.
* TODO: When we add blocking locks we will add cancel
* for them here too.
*/
int mid = SVAL(inbuf,smb_mid);
remove_pending_change_notify_requests_by_mid(mid);
DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
return(-1);
}
@ -933,6 +946,10 @@ static int call_nt_transact_rename(char *inbuf, char *outbuf, int length,
* Rename was successful.
*/
send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0);
DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
Files[fnum].name, new_name));
outsize = -1;
}
@ -940,7 +957,175 @@ static int call_nt_transact_rename(char *inbuf, char *outbuf, int length,
}
/****************************************************************************
Reply to a notify change - we should never get this (for now) as we
This is the structure to queue to implement NT change
notify. It consists of smb_size bytes stored from the
transact command (to keep the mid, tid etc around).
Plus the fid to examine and the time to check next.
*****************************************************************************/
typedef struct {
ubi_slNode msg_next;
int fnum;
int cnum;
time_t next_check_time;
char request_buf[smb_size];
} change_notify_buf;
static ubi_slList change_notify_queue = { NULL, (ubi_slNodePtr)&change_notify_queue, 0};
/****************************************************************************
Setup the common parts of the return packet and send it.
Code stolen from construct_reply() in server.c
*****************************************************************************/
static void change_notify_reply_packet(char *inbuf, int error_class, uint32 error_code)
{
extern int Client;
char outbuf[smb_size];
bzero(outbuf,smb_size);
CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
set_message(outbuf,0,0,True);
memcpy(outbuf+4,inbuf+4,4);
CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
CVAL(outbuf,smb_reh) = 0;
CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
means a reply */
SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
SSVAL(outbuf,smb_err,SMB_SUCCESS);
SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
ERROR(error_class,error_code);
send_smb(Client,outbuf);
}
/****************************************************************************
Delete entries by fnum from the change notify pending queue.
*****************************************************************************/
void remove_pending_change_notify_requests_by_fid(int fnum)
{
change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
change_notify_buf *prev = NULL;
while(cnbp != NULL) {
if(cnbp->fnum == fnum) {
ubi_slRemNext( &change_notify_queue, prev);
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
continue;
}
prev = cnbp;
cnbp = (change_notify_buf *)ubi_slNext(cnbp);
}
}
/****************************************************************************
Delete entries by mid from the change notify pending queue. Always send reply.
*****************************************************************************/
void remove_pending_change_notify_requests_by_mid(int mid)
{
change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
change_notify_buf *prev = NULL;
while(cnbp != NULL) {
if(SVAL(cnbp->request_buf,smb_mid) == mid) {
change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
ubi_slRemNext( &change_notify_queue, prev);
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
continue;
}
prev = cnbp;
cnbp = (change_notify_buf *)ubi_slNext(cnbp);
}
}
/****************************************************************************
Process the change notify queue. Note that this is only called as root.
*****************************************************************************/
void process_pending_change_notify_queue(time_t t)
{
change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
change_notify_buf *prev = NULL;
if(cnbp == NULL)
return;
if(cnbp->next_check_time >= t)
return;
/*
* It's time to check. Go through the queue and see if
* the timestamps changed.
*/
while((cnbp != NULL) && (cnbp->next_check_time <= t)) {
struct stat st;
int fnum = cnbp->fnum;
int cnum = cnbp->cnum;
files_struct *fsp = &Files[fnum];
uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
SVAL(cnbp->request_buf,smb_uid);
if(!become_user(&Connections[cnum],cnum,vuid)) {
DEBUG(0,("process_pending_change_notify_queue: Unable to become user vuid=%d.\n",
vuid ));
/*
* Remove the entry and return an error to the client.
*/
change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
ubi_slRemNext( &change_notify_queue, prev);
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
continue;
}
if(sys_stat(fsp->name, &st) < 0) {
DEBUG(0,("process_pending_change_notify_queue: Unable to stat directory %s. \
Error was %s.\n", fsp->name, strerror(errno) ));
/*
* Remove the entry and return an error to the client.
*/
change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
ubi_slRemNext( &change_notify_queue, prev);
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
unbecome_user();
continue;
}
if(fsp->f_u.dir_ptr->modify_time != st.st_mtime ||
fsp->f_u.dir_ptr->status_time != st.st_ctime) {
/*
* Remove the entry and return a change notify to the client.
*/
DEBUG(5,("process_pending_change_notify_queue: directory fnum = %d, name = %s changed\n",
fnum, fsp->name ));
change_notify_reply_packet(cnbp->request_buf,ERRDOS,ERROR_NOTIFY_ENUM_DIR);
ubi_slRemNext( &change_notify_queue, prev);
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
unbecome_user();
continue;
}
unbecome_user();
/*
* Move to the next in the list.
*/
prev = cnbp;
cnbp = (change_notify_buf *)ubi_slNext(cnbp);
}
}
/****************************************************************************
Reply to a notify change - queue the request and
don't allow a directory to be opened.
****************************************************************************/
@ -948,10 +1133,83 @@ static int call_nt_transact_notify_change(char *inbuf, char *outbuf, int length,
int bufsize, int cnum,
char **ppsetup, char **ppparams, char **ppdata)
{
#if 0
DEBUG(0,("call_nt_transact_notify_change: Should not be called !\n"));
return(ERROR(ERRSRV,ERRnosupport));
#else /* Under development. */
char *setup = *ppsetup;
files_struct *fsp;
int fnum = -1;
change_notify_buf *cnbp;
struct stat st;
fnum = SVAL(setup,4);
DEBUG(0,("call_nt_transact_notify_change: fnum = %d.\n", fnum));
if(!VALID_FNUM(fnum))
return(ERROR(ERRDOS,ERRbadfid));
fsp = &Files[fnum];
if((!fsp->open) || (!fsp->is_directory) || (cnum != fsp->cnum))
return(ERROR(ERRDOS,ERRbadfid));
/*
* Setup the current directory information in the
* directory entry in the files_struct. We will use
* this to check against when the timer expires.
*/
if(sys_stat(fsp->name, &st) < 0) {
DEBUG(0,("call_nt_transact_notify_change: Unable to stat fnum = %d, name = %s. \
Error was %s\n", fnum, fsp->name, strerror(errno) ));
return -1;
}
if(fsp->f_u.dir_ptr == NULL) {
if((fsp->f_u.dir_ptr = (dir_status_struct *)malloc(sizeof(dir_status_struct))) == NULL) {
DEBUG(0,("call_nt_transact_notify_change: Malloc fail !\n" ));
return -1;
}
}
fsp->f_u.dir_ptr->modify_time = st.st_mtime;
fsp->f_u.dir_ptr->status_time = st.st_ctime;
/*
* Now queue an entry on the notify change stack. We timestamp
* the entry we are adding so that we know when to scan next.
* We only need to save smb_size bytes from this incoming packet
* as we will always by returning a 'read the directory yourself'
* error.
*/
if((cnbp = (change_notify_buf *)malloc(sizeof(change_notify_buf))) == NULL) {
DEBUG(0,("call_nt_transact_notify_change: Malloc fail (2) !\n" ));
return -1;
}
memcpy(cnbp->request_buf, inbuf, smb_size);
cnbp->fnum = fnum;
cnbp->cnum = cnum;
cnbp->next_check_time = time(NULL) + lp_change_notify_timeout();
/*
* Adding to the tail enables us to check only
* the head when scanning for change, as this entry
* is forced to have the first timeout expiration.
*/
ubi_slAddTail(&change_notify_queue, cnbp);
DEBUG(3,("call_nt_transact_notify_change: notify change called on directory fid=%d, name = %s\n",
fnum, fsp->name ));
return -1;
#endif
}
/****************************************************************************
Reply to query a security descriptor - currently this is not implemented (it
is planned to be though).
@ -996,7 +1254,7 @@ static int call_nt_transact_ioctl(char *inbuf, char *outbuf, int length,
int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
int outsize = 0;
int cnum = SVAL(inbuf,smb_tid);
#if 0 /* Not used. */
uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
@ -1009,7 +1267,7 @@ int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
uint16 setup_count = CVAL(inbuf,smb_nt_SetupCount);
uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
uint16 function_code = SVAL( inbuf, smb_nt_Function);
char *params = NULL, *data = NULL, *setup = NULL;
uint32 num_params_sofar, num_data_sofar;
@ -1019,8 +1277,8 @@ int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
* Queue this open message as we are the process of an oplock break.
*/
DEBUG( 2, ( "reply_nttrans: queueing message NT_TRANSACT_CREATE " ) );
DEBUGADD( 2, ( "due to being in oplock break state.\n" ) );
DEBUG(2,("reply_nttrans: queueing message NT_TRANSACT_CREATE \
due to being in oplock break state.\n" ));
push_oplock_pending_smb_message( inbuf, length);
return -1;
@ -1033,9 +1291,9 @@ int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
* Ensure this is so as a sanity check.
*/
if(CVAL(inbuf, smb_wct) != 19 + setup_count) {
if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
CVAL(inbuf, smb_wct), 19 + setup_count));
CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
return(ERROR(ERRSRV,ERRerror));
}
@ -1062,12 +1320,21 @@ int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
if (parameter_count > total_parameter_count || data_count > total_data_count)
exit_server("reply_nttrans: invalid sizes in packet.\n");
if(setup)
if(setup) {
memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
if(params)
DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
dump_data(10, setup, setup_count);
}
if(params) {
memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
if(data)
DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
dump_data(10, params, parameter_count);
}
if(data) {
memcpy( data, smb_base(inbuf) + data_offset, data_count);
DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
dump_data(10, data, data_count);
}
if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
/* We need to send an interim response then receive the rest
@ -1145,8 +1412,7 @@ int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
break;
default:
/* Error in request */
DEBUG( 0, ( "reply_nttrans: Unknown request %d in nttrans call\n",
function_code ) );
DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
if(setup)
free(setup);
if(params)

View File

@ -1475,6 +1475,8 @@ void close_directory(int fnum)
change notify requests and free
any pertaining to this fnum. */
remove_pending_change_notify_requests_by_fid(fnum);
/*
* Do the code common to files and directories.
*/
@ -1532,6 +1534,9 @@ int open_directory(int fnum,int cnum,char *fname, int smb_ofun, int unixmode, in
*action = FILE_WAS_OPENED;
}
DEBUG(5,("open_directory: opening directory %s, fnum = %d\n",
fname, fnum ));
/*
* Setup the files_struct for it.
*/
@ -4029,7 +4034,7 @@ int reply_nt1(char *outbuf)
/*
other valid capabilities which we may support at some time...
CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
CAP_LARGE_FILES|
CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
*/
@ -5116,6 +5121,12 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup ));
trust_password_unlock();
global_machine_pasword_needs_changing = False;
}
/*
* Check to see if we have any change notifies
* outstanding on the queue.
*/
process_pending_change_notify_queue(t);
}
if(got_smb)