summaryrefslogtreecommitdiff
path: root/source/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd')
-rw-r--r--source/smbd/chgpasswd.c7
-rw-r--r--source/smbd/close.c26
-rw-r--r--source/smbd/dosmode.c4
-rw-r--r--source/smbd/fileio.c4
-rw-r--r--source/smbd/files.c46
-rw-r--r--source/smbd/lanman.c31
-rw-r--r--source/smbd/nttrans.c8
-rw-r--r--source/smbd/open.c16
-rw-r--r--source/smbd/password.c2
-rw-r--r--source/smbd/posix_acls.c9
-rw-r--r--source/smbd/reply.c7
-rw-r--r--source/smbd/trans2.c128
12 files changed, 174 insertions, 114 deletions
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index af363d75a3f..c91f8599c96 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -456,7 +456,7 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
DEBUG(3, ("chgpasswd: Password change (as_root=%s) for user: %s\n", BOOLSTR(as_root), name));
-#if DEBUG_PASSWORD
+#ifdef DEBUG_PASSWORD
DEBUG(100, ("chgpasswd: Passwords: old=%s new=%s\n", oldpass, newpass));
#endif
@@ -1018,7 +1018,8 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
return NT_STATUS_ACCOUNT_RESTRICTION;
}
- if (account_policy_get(AP_MIN_PASSWORD_LEN, &min_len) && (strlen(new_passwd) < min_len)) {
+ /* FIXME: AP_MIN_PASSWORD_LEN and lp_min_passwd_length() need to be merged - gd */
+ if (account_policy_get(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
DEBUG(1, ("user %s cannot change password - password too short\n",
username));
DEBUGADD(1, (" account policy min password len = %d\n", min_len));
@@ -1028,7 +1029,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
/* Take the passed information and test it for minimum criteria */
/* Minimum password length */
- if (strlen(new_passwd) < lp_min_passwd_length()) {
+ if (str_charnum(new_passwd) < lp_min_passwd_length()) {
/* too short, must be at least MINPASSWDLENGTH */
DEBUG(1, ("Password Change: user %s, New password is shorter than minimum password length = %d\n",
username, lp_min_passwd_length()));
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 6de27746442..4445f2516bc 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -150,6 +150,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
size_t share_entry_count = 0;
BOOL delete_on_close = False;
connection_struct *conn = fsp->conn;
+ int saved_errno = 0;
int err = 0;
int err1 = 0;
@@ -160,8 +161,10 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
* error here, we must remember this.
*/
- if (close_filestruct(fsp) == -1)
+ if (close_filestruct(fsp) == -1) {
+ saved_errno = errno;
err1 = -1;
+ }
if (fsp->print_file) {
print_fsp_end(fsp, normal_close);
@@ -242,6 +245,12 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
err = fd_close(conn, fsp);
+ /* Only save errno if fd_close failed and we don't already
+ have an errno saved from a flush call. */
+ if ((err1 != -1) && (err == -1)) {
+ saved_errno = errno;
+ }
+
/* check for magic scripts */
if (normal_close) {
check_magic(fsp,conn);
@@ -252,24 +261,25 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
*/
if(fsp->pending_modtime) {
- int saved_errno = errno;
set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
- errno = saved_errno;
}
DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
- conn->user,fsp->fsp_name,
- conn->num_files_open, err ? strerror(err) : ""));
+ conn->user,fsp->fsp_name,
+ conn->num_files_open,
+ (err == -1 || err1 == -1) ? strerror(saved_errno) : ""));
if (fsp->fsp_name)
string_free(&fsp->fsp_name);
file_free(fsp);
- if (err == -1 || err1 == -1)
- return errno;
- else
+ if (err == -1 || err1 == -1) {
+ errno = saved_errno;
+ return saved_errno;
+ } else {
return 0;
+ }
}
/****************************************************************************
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index 33c75fffd53..7199b3ebbf3 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -135,8 +135,8 @@ uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf)
if (S_ISDIR(sbuf->st_mode))
result = aDIR | (result & aRONLY);
-#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE)
- if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) {
+#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
+ if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) {
result |= FILE_ATTRIBUTE_SPARSE;
}
#endif
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index c2fb6e34566..b9fe1ad1cfc 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -151,10 +151,10 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
int write_path = -1;
if (fsp->print_file) {
- int snum;
+ fstring sharename;
uint32 jobid;
- if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) {
+ if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) {
DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n",
(unsigned int)fsp->rap_print_jobid ));
errno = EBADF;
diff --git a/source/smbd/files.c b/source/smbd/files.c
index 80544c9a309..580dc545452 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -289,12 +289,12 @@ files_struct *file_find_fsp(files_struct *orig_fsp)
{
files_struct *fsp;
- for (fsp=Files;fsp;fsp=fsp->next) {
- if (fsp == orig_fsp)
- return fsp;
- }
+ for (fsp=Files;fsp;fsp=fsp->next) {
+ if (fsp == orig_fsp)
+ return fsp;
+ }
- return NULL;
+ return NULL;
}
/****************************************************************************
@@ -303,16 +303,16 @@ files_struct *file_find_fsp(files_struct *orig_fsp)
files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode)
{
- files_struct *fsp;
+ files_struct *fsp;
- for (fsp=Files;fsp;fsp=fsp->next) {
- if ( fsp->fd != -1 &&
- fsp->dev == dev &&
- fsp->inode == inode )
- return fsp;
- }
+ for (fsp=Files;fsp;fsp=fsp->next) {
+ if ( fsp->fd != -1 &&
+ fsp->dev == dev &&
+ fsp->inode == inode )
+ return fsp;
+ }
- return NULL;
+ return NULL;
}
/****************************************************************************
@@ -321,16 +321,16 @@ files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode)
files_struct *file_find_di_next(files_struct *start_fsp)
{
- files_struct *fsp;
+ files_struct *fsp;
- for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
- if ( fsp->fd != -1 &&
- fsp->dev == start_fsp->dev &&
- fsp->inode == start_fsp->inode )
- return fsp;
- }
+ for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
+ if ( fsp->fd != -1 &&
+ fsp->dev == start_fsp->dev &&
+ fsp->inode == start_fsp->inode )
+ return fsp;
+ }
- return NULL;
+ return NULL;
}
/****************************************************************************
@@ -388,7 +388,9 @@ void file_free(files_struct *fsp)
information */
ZERO_STRUCTP(fsp);
- if (fsp == chain_fsp) chain_fsp = NULL;
+ if (fsp == chain_fsp) {
+ chain_fsp = NULL;
+ }
SAFE_FREE(fsp);
}
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index dd9708356e7..610ee451201 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -441,7 +441,7 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
/* the client expects localtime */
t -= TimeDiff(t);
- PACKI(desc,"W",pjobid_to_rap(snum,queue->job)); /* uJobId */
+ PACKI(desc,"W",pjobid_to_rap(lp_const_servicename(snum),queue->job)); /* uJobId */
if (uLevel == 1) {
PACKS(desc,"B21",queue->fs_user); /* szUserName */
PACKS(desc,"B",""); /* pad */
@@ -548,9 +548,8 @@ static void fill_printq_info_52(connection_struct *conn, int snum,
PACKS(desc, "z", driver.info_3->datafile); /* Datafile name */
PACKS(desc, "z", driver.info_3->monitorname); /* language monitor */
- fstrcpy(location, "\\\\");
- fstrcat(location, get_called_name());
- fstrcat(location, "\\print$\\WIN40\\0");
+ fstrcpy(location, "\\\\%L\\print$\\WIN40\\0");
+ standard_sub_basic( "", location, sizeof(location)-1 );
PACKS(desc,"z", location); /* share to retrieve files */
PACKS(desc,"z", driver.info_3->defaultdatatype); /* default data type */
@@ -1501,10 +1500,12 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
if (!check_share_info(uLevel,str2)) return False;
data_len = fixed_len = string_len = 0;
- for (i=0;i<count;i++)
+ for (i=0;i<count;i++) {
+ fstring servicename_dos;
+ push_ascii_fstring(servicename_dos, lp_servicename(i));
if( lp_browseable( i )
&& lp_snum_ok( i )
- && (strlen( lp_servicename( i ) ) < 13) ) /* Maximum name length. */
+ && (strlen(servicename_dos) < 13) ) /* Maximum name length. */
{
total++;
data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0);
@@ -1517,6 +1518,7 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
else
missed = True;
}
+ }
*rdata_len = fixed_len + string_len;
*rdata = REALLOC(*rdata,*rdata_len);
memset(*rdata,0,*rdata_len);
@@ -1527,9 +1529,11 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
s_len = string_len;
for( i = 0; i < count; i++ )
{
+ fstring servicename_dos;
+ push_ascii_fstring(servicename_dos, lp_servicename(i));
if( lp_browseable( i )
&& lp_snum_ok( i )
- && (strlen( lp_servicename( i ) ) < 13) )
+ && (strlen(servicename_dos) < 13) )
{
if( fill_share_info( conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata ) < 0 )
break;
@@ -2118,11 +2122,12 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
char *p = skip_string(str2,1);
uint32 jobid;
int snum;
+ fstring sharename;
int errcode;
extern struct current_user current_user;
WERROR werr = WERR_OK;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
+ if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
/* check it's a supported varient */
@@ -2133,7 +2138,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
*rparam = REALLOC(*rparam,*rparam_len);
*rdata_len = 0;
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(sharename, jobid)) {
errcode = NERR_JobNotFound;
goto out;
}
@@ -2253,11 +2258,12 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
char *p = skip_string(str2,1);
uint32 jobid;
int snum;
+ fstring sharename;
int uLevel = SVAL(p,2);
int function = SVAL(p,4);
int place, errcode;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
+ if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
*rparam_len = 4;
*rparam = REALLOC(*rparam,*rparam_len);
@@ -2269,7 +2275,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
(!check_printjob_info(&desc,uLevel,str2)))
return(False);
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(sharename, jobid)) {
errcode=NERR_JobNotFound;
goto out;
}
@@ -2935,6 +2941,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
int count;
int i;
int snum;
+ fstring sharename;
uint32 jobid;
struct pack_desc desc;
print_queue_struct *queue=NULL;
@@ -2952,7 +2959,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
if (strcmp(str1,"WWrLh") != 0) return False;
if (!check_printjob_info(&desc,uLevel,str2)) return False;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
+ if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
if (snum < 0 || !VALID_SNUM(snum)) return(False);
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index d9e321fd968..eaaf68d6895 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -907,7 +907,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
#endif
if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
- fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
+ fsp->initial_allocation_size = smb_roundup(allocation_size);
if (fsp->is_directory) {
close_file(fsp,False);
END_PROFILE(SMBntcreateX);
@@ -920,7 +920,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
return ERROR_NT(NT_STATUS_DISK_FULL);
}
} else {
- fsp->initial_allocation_size = SMB_ROUNDUP(((SMB_BIG_UINT)file_len),SMB_ROUNDUP_ALLOCATION_SIZE);
+ fsp->initial_allocation_size = smb_roundup((SMB_BIG_UINT)file_len);
}
/*
@@ -1429,7 +1429,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
#endif
if (allocation_size && (allocation_size > file_len)) {
- fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
+ fsp->initial_allocation_size = smb_roundup(allocation_size);
if (fsp->is_directory) {
close_file(fsp,False);
END_PROFILE(SMBntcreateX);
@@ -1441,7 +1441,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
return ERROR_NT(NT_STATUS_DISK_FULL);
}
} else {
- fsp->initial_allocation_size = SMB_ROUNDUP(((SMB_BIG_UINT)file_len),SMB_ROUNDUP_ALLOCATION_SIZE);
+ fsp->initial_allocation_size = smb_roundup((SMB_BIG_UINT)file_len);
}
/* Realloc the size of parameters and data we will return */
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 6d559ac8280..55970493fa1 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -1409,9 +1409,17 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
}
if (delete_on_close) {
- NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
+ uint32 dosmode = existing_dos_mode;
+ NTSTATUS result;
+
+ if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
+ dosmode = new_dos_mode;
+ }
+ result = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
+ uint8 u_e_c;
+ uint32 u_e_code;
/* Remember to delete the mode we just added. */
if (add_share_mode) {
del_share_mode(fsp, NULL);
@@ -1419,6 +1427,10 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
unlock_share_entry_fsp(fsp);
fd_close(conn,fsp);
file_free(fsp);
+ ntstatus_to_dos(result, &u_e_c, &u_e_code);
+ unix_ERR_ntstatus = result;
+ unix_ERR_class = u_e_c;
+ unix_ERR_code = u_e_code;
return NULL;
}
}
@@ -1651,7 +1663,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
string_set(&fsp->fsp_name,fname);
if (delete_on_close) {
- NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
+ NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close, 0);
if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
file_free(fsp);
diff --git a/source/smbd/password.c b/source/smbd/password.c
index cf3c3d64d20..eb389d7013d 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -473,7 +473,7 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password,
{
BOOL ok = False;
-#if DEBUG_PASSWORD
+#ifdef DEBUG_PASSWORD
DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n",
user,password.data));
#endif
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 95938b1e15c..ab32d0591e9 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -3195,6 +3195,7 @@ int get_acl_group_bits( connection_struct *conn, const char *fname, mode_t *mode
int entry_id = SMB_ACL_FIRST_ENTRY;
SMB_ACL_ENTRY_T entry;
SMB_ACL_T posix_acl;
+ int result = -1;
posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
if (posix_acl == (SMB_ACL_T)NULL)
@@ -3209,20 +3210,22 @@ int get_acl_group_bits( connection_struct *conn, const char *fname, mode_t *mode
entry_id = SMB_ACL_NEXT_ENTRY;
if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) ==-1)
- return -1;
+ break;
if (tagtype == SMB_ACL_GROUP_OBJ) {
if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
- return -1;
+ break;
} else {
*mode &= ~(S_IRGRP|S_IWGRP|S_IXGRP);
*mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRGRP : 0);
*mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWGRP : 0);
*mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXGRP : 0);
- return 0;;
+ result = 0;
+ break;
}
}
}
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
return -1;
}
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index cdf607e2738..845f0588670 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -4514,13 +4514,18 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
data = smb_buf(inbuf);
- if (locktype & (LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_CHANGE_LOCKTYPE)) {
+ if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
/* we don't support these - and CANCEL_LOCK makes w2k
and XP reboot so I don't really want to be
compatible! (tridge) */
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
}
+ if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
+ /* Need to make this like a cancel.... JRA. */
+ return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ }
+
/* Check if this is an oplock break on a file
we have granted an oplock on.
*/
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index f3176940c2f..9b1f2aa2105 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -31,20 +31,43 @@ extern uint32 global_client_caps;
extern struct current_user current_user;
#define get_file_size(sbuf) ((sbuf).st_size)
+#define DIR_ENTRY_SAFETY_MARGIN 4096
+
+/********************************************************************
+ Roundup a value to the nearest SMB_ROUNDUP_ALLOCATION_SIZE boundary.
+ Only do this for Windows clients.
+********************************************************************/
+
+SMB_BIG_UINT smb_roundup(SMB_BIG_UINT val)
+{
+ /* Only roundup for Windows clients. */
+ enum remote_arch_types ra_type = get_remote_arch();
+ if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
+ val = SMB_ROUNDUP(val,SMB_ROUNDUP_ALLOCATION_SIZE);
+ }
+ return val;
+}
+
+/********************************************************************
+ Given a stat buffer return the allocated size on disk, taking into
+ account sparse files.
+********************************************************************/
-/* given a stat buffer return the allocated size on disk, taking into
- account sparse files */
SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
{
SMB_BIG_UINT ret;
+
#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
#else
ret = (SMB_BIG_UINT)get_file_size(*sbuf);
#endif
+
if (!ret && fsp && fsp->initial_allocation_size)
ret = fsp->initial_allocation_size;
- ret = SMB_ROUNDUP(ret,SMB_ROUNDUP_ALLOCATION_SIZE);
+
+ ret = smb_roundup(ret);
+
return ret;
}
@@ -734,32 +757,6 @@ static uint32 unix_filetype(mode_t mode)
}
/****************************************************************************
- Return the major devicenumber for UNIX extensions.
-****************************************************************************/
-
-static uint32 unix_dev_major(SMB_DEV_T dev)
-{
-#if defined(HAVE_DEVICE_MAJOR_FN)
- return (uint32)major(dev);
-#else
- return (uint32)(dev >> 8);
-#endif
-}
-
-/****************************************************************************
- Return the minor devicenumber for UNIX extensions.
-****************************************************************************/
-
-static uint32 unix_dev_minor(SMB_DEV_T dev)
-{
-#if defined(HAVE_DEVICE_MINOR_FN)
- return (uint32)minor(dev);
-#else
- return (uint32)(dev & 0xff);
-#endif
-}
-
-/****************************************************************************
Map wire perms onto standard UNIX permissions. Obey share restrictions.
****************************************************************************/
@@ -1360,7 +1357,12 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
info_level, max_data_bytes));
-
+
+ if (!maxentries) {
+ /* W2K3 seems to treat zero as 1. */
+ maxentries = 1;
+ }
+
switch (info_level) {
case SMB_INFO_STANDARD:
case SMB_INFO_QUERY_EA_SIZE:
@@ -1409,12 +1411,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
- pdata = Realloc(*ppdata, max_data_bytes + 1024);
+ pdata = Realloc(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if( pdata == NULL )
return(ERROR_DOS(ERRDOS,ERRnomem));
*ppdata = pdata;
- memset((char *)pdata,'\0',max_data_bytes + 1024);
+ memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
/* Realloc the params space */
params = Realloc(*pparams, 10);
@@ -1586,6 +1588,11 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
requires_resume_key, resume_key, resume_name, continue_bit, info_level));
+ if (!maxentries) {
+ /* W2K3 seems to treat zero as 1. */
+ maxentries = 1;
+ }
+
switch (info_level) {
case SMB_INFO_STANDARD:
case SMB_INFO_QUERY_EA_SIZE:
@@ -1602,12 +1609,12 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
- pdata = Realloc( *ppdata, max_data_bytes + 1024);
+ pdata = Realloc( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if(pdata == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
*ppdata = pdata;
- memset((char *)pdata,'\0',max_data_bytes + 1024);
+ memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
/* Realloc the params space */
params = Realloc(*pparams, 6*SIZEOFWORD);
@@ -1818,12 +1825,12 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
- pdata = Realloc(*ppdata, max_data_bytes + 1024);
+ pdata = Realloc(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if ( pdata == NULL )
return ERROR_DOS(ERRDOS,ERRnomem);
*ppdata = pdata;
- memset((char *)pdata,'\0',max_data_bytes + 1024);
+ memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
switch (info_level) {
case SMB_INFO_ALLOCATION:
@@ -2389,7 +2396,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
return ERROR_DOS(ERRDOS,ERRnomem);
*pparams = params;
memset((char *)params,'\0',2);
- data_size = max_data_bytes + 1024;
+ data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
pdata = Realloc(*ppdata, data_size);
if ( pdata == NULL )
return ERROR_DOS(ERRDOS,ERRnomem);
@@ -2804,25 +2811,38 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
open_file_shared. JRA.
****************************************************************************/
-NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
+NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
{
- /*
- * Only allow delete on close for writable shares.
- */
+ if (delete_on_close) {
+ /*
+ * Only allow delete on close for writable files.
+ */
- if (delete_on_close && !CAN_WRITE(fsp->conn)) {
- DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
+ if (dosmode & aRONLY) {
+ DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
fsp->fsp_name ));
- return NT_STATUS_ACCESS_DENIED;
- }
- /*
- * Only allow delete on close for files/directories opened with delete intent.
- */
+ return NT_STATUS_CANNOT_DELETE;
+ }
+
+ /*
+ * Only allow delete on close for writable shares.
+ */
+
+ if (!CAN_WRITE(fsp->conn)) {
+ DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
+ fsp->fsp_name ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /*
+ * Only allow delete on close for files/directories opened with delete intent.
+ */
- if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
- DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
+ if (!(fsp->desired_access & DELETE_ACCESS)) {
+ DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
fsp->fsp_name ));
- return NT_STATUS_ACCESS_DENIED;
+ return NT_STATUS_ACCESS_DENIED;
+ }
}
if(fsp->is_directory) {
@@ -2859,7 +2879,7 @@ NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
return NT_STATUS_ACCESS_DENIED;
if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
- DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
+ DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
fsp->fsp_name ));
unlock_share_entry_fsp(fsp);
return NT_STATUS_ACCESS_DENIED;
@@ -3189,7 +3209,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
fname, (double)allocation_size ));
if (allocation_size)
- allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
+ allocation_size = smb_roundup(allocation_size);
if(allocation_size != get_file_size(sbuf)) {
SMB_STRUCT_STAT new_sbuf;
@@ -3279,7 +3299,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadfid));
- status = set_delete_on_close_internal(fsp, delete_on_close);
+ status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
return ERROR_NT(status);