diff options
author | Gerald Carter <jerry@samba.org> | 2004-10-25 19:25:54 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2004-10-25 19:25:54 +0000 |
commit | 317ab676bf28d3922dc0fba02e908a766035872f (patch) | |
tree | d9ea00a371f92740e58b95991b4b56723454304d /source/smbd | |
parent | 943c0aaaeb5a24a9501a164e9a765384e8e8a2ff (diff) | |
download | samba-317ab676bf28d3922dc0fba02e908a766035872f.tar.gz |
r3220: merging current 3.0 code to release branch
Diffstat (limited to 'source/smbd')
-rw-r--r-- | source/smbd/chgpasswd.c | 7 | ||||
-rw-r--r-- | source/smbd/close.c | 26 | ||||
-rw-r--r-- | source/smbd/dosmode.c | 4 | ||||
-rw-r--r-- | source/smbd/fileio.c | 4 | ||||
-rw-r--r-- | source/smbd/files.c | 46 | ||||
-rw-r--r-- | source/smbd/lanman.c | 31 | ||||
-rw-r--r-- | source/smbd/nttrans.c | 8 | ||||
-rw-r--r-- | source/smbd/open.c | 16 | ||||
-rw-r--r-- | source/smbd/password.c | 2 | ||||
-rw-r--r-- | source/smbd/posix_acls.c | 9 | ||||
-rw-r--r-- | source/smbd/reply.c | 7 | ||||
-rw-r--r-- | source/smbd/trans2.c | 128 |
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); |