BOOL is_in_path(char *name, name_compare_entry *namelist);
void set_namearray(name_compare_entry **ppname_array, char *namelist);
void free_namearray(name_compare_entry *name_array);
+uint32 map_lock_offset(uint32 high, uint32 low);
BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
BOOL is_myname(char *s);
void set_remote_arch(enum remote_arch_types type);
BOOL lp_dos_filetime_resolution(int );
BOOL lp_fake_dir_create_times(int );
BOOL lp_blocking_locks(int );
-BOOL lp_mangle_locks(int );
int lp_create_mask(int );
int lp_force_create_mode(int );
int _lp_security_mask(int );
int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL mangle_locks, BOOL *err);
-uint32 map_lock_offset(uint32 high, uint32 low);
-SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL mangle_locks, BOOL *err);
+SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL *err);
+SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err);
int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
free((char *)name_array);
}
+/****************************************************************************
+ Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
+****************************************************************************/
+
+uint32 map_lock_offset(uint32 high, uint32 low)
+{
+ unsigned int i;
+ uint32 mask = 0;
+ uint32 highcopy = high;
+
+ /*
+ * Try and find out how many significant bits there are in high.
+ */
+
+ for(i = 0; highcopy; i++)
+ highcopy >>= 1;
+
+ /*
+ * We use 31 bits not 32 here as POSIX
+ * lock offsets may not be negative.
+ */
+
+ mask = (~0) << (31 - i);
+
+ if(low & mask)
+ return 0; /* Fail. */
+
+ high <<= (31 - i);
+
+ return (high|low);
+}
+
/****************************************************************************
routine to do file locking
****************************************************************************/
+
BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
#if HAVE_FCNTL_LOCK
SMB_STRUCT_FLOCK lock;
int ret;
+#if defined(LARGE_SMB_OFF_T)
+ /*
+ * In the 64 bit locking case we store the original
+ * values in case we have to map to a 32 bit lock on
+ * a filesystem that doesn't support 64 bit locks.
+ */
+ SMB_OFF_T orig_offset = offset;
+ SMB_OFF_T orig_count = count;
+#endif /* LARGE_SMB_OFF_T */
if(lp_ole_locking_compat()) {
SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
}
/* 32 bit NFS file system, retry with smaller offset */
errno = 0;
- lock.l_len = count & 0xffffffff;
+ lock.l_len = count & 0x7fffffff;
ret = fcntl(fd,op,&lock);
}
{
DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
(double)offset,(double)count,op,type,strerror(errno)));
+
+ /* perhaps it doesn't support this sort of locking?? */
+ if (errno == EINVAL)
+ {
+
+#if defined(LARGE_SMB_OFF_T)
+ {
+ /*
+ * Ok - if we get here then we have a 64 bit lock request
+ * that has returned EINVAL. Try and map to 31 bits for offset
+ * and length and try again. This may happen if a filesystem
+ * doesn't support 64 bit offsets (efs/ufs) although the underlying
+ * OS does.
+ */
+ uint32 off_low = (orig_offset & 0xFFFFFFFF);
+ uint32 off_high = ((orig_offset >> 32) & 0xFFFFFFFF);
+
+ lock.l_len = (orig_count & 0x7FFFFFFF);
+ lock.l_start = (SMB_OFF_T)map_lock_offset(off_high, off_low);
+ ret = fcntl(fd,op,&lock);
+ if (ret == -1)
+ {
+ if (errno == EINVAL)
+ {
+ DEBUG(3,("locking not supported? returning True\n"));
+ return(True);
+ }
+ return False;
+ }
+ DEBUG(3,("64 -> 32 bit modified lock call successful\n"));
+ return True;
+ }
+#else /* LARGE_SMB_OFF_T */
+ DEBUG(3,("locking not supported? returning True\n"));
+ return(True);
+#endif /* LARGE_SMB_OFF_T */
+ }
+
return(False);
}
BOOL bDosFiletimeResolution;
BOOL bFakeDirCreateTimes;
BOOL bBlockingLocks;
- BOOL bMangleLocks;
char dummy[3]; /* for alignment */
} service;
False, /* bDosFiletimeResolution */
False, /* bFakeDirCreateTimes */
True, /* bBlockingLocks */
- True, /* bMangleLocks */
"" /* dummy */
};
{"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
{"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
{"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"mangle locks", P_BOOL, P_LOCAL, &sDefault.bMangleLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
{"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
{"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
{"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
-FN_LOCAL_BOOL(lp_mangle_locks,bMangleLocks)
FN_LOCAL_INTEGER(lp_create_mask,iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
Get a lock count, dealing with large count requests.
****************************************************************************/
-SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL mangle_locks, BOOL *err)
+SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL *err)
{
SMB_OFF_T count = 0;
* NT4.x seems to be broken in that it sends large file
* lockingX calls even if the CAP_LARGE_FILES was *not*
* negotiated. For boxes without large file locks truncate the
- * lock count by dropping the top 32 bits if mangle_locks is set.
+ * lock count by dropping the top 32 bits.
*/
- if(mangle_locks && (IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0)) {
+ if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
(unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
(unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
return count;
}
-/****************************************************************************
- Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
-****************************************************************************/
-
-uint32 map_lock_offset(uint32 high, uint32 low)
-{
- unsigned int i;
- uint32 mask = 0;
- uint32 highcopy = high;
-
- /*
- * Try and find out how many significant bits there are in high.
- */
-
- for(i = 0; highcopy; i++)
- highcopy >>= 1;
-
- /*
- * We use 31 bits not 32 here as POSIX
- * lock offsets may not be negative.
- */
-
- mask = (~0) << (31 - i);
-
- if(low & mask)
- return 0; /* Fail. */
-
- high <<= (31 - i);
-
- return (high|low);
-}
-
/****************************************************************************
Get a lock offset, dealing with large offset requests.
****************************************************************************/
-SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL mangle_locks, BOOL *err)
+SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
{
SMB_OFF_T offset = 0;
* NT4.x seems to be broken in that it sends large file
* lockingX calls even if the CAP_LARGE_FILES was *not*
* negotiated. For boxes without large file locks mangle the
- * lock offset by mapping the top 32 bits onto the lower 32 if
- * mangle_locks is set.
+ * lock offset by mapping the top 32 bits onto the lower 32.
*/
- if(mangle_locks && (IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0)) {
+ if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
uint32 new_low = 0;
uint32 ecode=0, dummy2;
int eclass=0, dummy1;
BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
- BOOL mangle_locks = False;
BOOL err1, err2;
CHECK_FSP(fsp,conn);
}
}
-#ifndef LARGE_SMB_OFF_T
- /*
- * We only look at this parameter if we're on a small file
- * offset platform. JRA.
- */
- mangle_locks = lp_mangle_locks(SNUM(conn));
-#endif
-
/* Data now points at the beginning of the list
of smb_unlkrng structs */
for(i = 0; i < (int)num_ulocks; i++) {
- count = get_lock_count( data, i, large_file_format, mangle_locks, &err1);
- offset = get_lock_offset( data, i, large_file_format, mangle_locks, &err2);
+ count = get_lock_count( data, i, large_file_format, &err1);
+ offset = get_lock_offset( data, i, large_file_format, &err2);
/*
* There is no error code marked "stupid client bug".... :-).
of smb_lkrng structs */
for(i = 0; i < (int)num_locks; i++) {
- count = get_lock_count( data, i, large_file_format, mangle_locks, &err1);
- offset = get_lock_offset( data, i, large_file_format, mangle_locks, &err2);
+ count = get_lock_count( data, i, large_file_format, &err1);
+ offset = get_lock_offset( data, i, large_file_format, &err2);
/*
* There is no error code marked "stupid client bug".... :-).
all of the previous locks (X/Open spec). */
if(i != num_locks && num_locks != 0) {
for(; i >= 0; i--) {
- count = get_lock_count( data, i, large_file_format, mangle_locks, &err1);
- offset = get_lock_offset( data, i, large_file_format, mangle_locks, &err2);
+ count = get_lock_count( data, i, large_file_format, &err1);
+ offset = get_lock_offset( data, i, large_file_format, &err2);
/*
* There is no error code marked "stupid client bug".... :-).