diff options
Diffstat (limited to 'source3/smbd')
32 files changed, 805 insertions, 1062 deletions
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index 74275368bd..c3fd0a2bc0 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -24,7 +24,17 @@ /* The signal we'll use to signify aio done. */ #ifndef RT_SIGNAL_AIO -#define RT_SIGNAL_AIO (SIGRTMIN+3) +#ifndef SIGRTMIN +#define SIGRTMIN NSIG +#endif +#define RT_SIGNAL_AIO (SIGRTMIN+3) +#endif + +#ifndef HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIVAL_PTR +#ifdef HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIGVAL_PTR +#define sival_int sigval_int +#define sival_ptr sigval_ptr +#endif #endif /**************************************************************************** @@ -581,6 +591,11 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr) { int err; + if(!aio_ex) { + DEBUG(3, ("handle_aio_completed: Non-existing aio_ex passed\n")); + return false; + } + /* Ensure the operation has really completed. */ if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) { DEBUG(10,( "handle_aio_completed: operation mid %u still in " diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 479361a8c1..4374b50eac 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -33,10 +33,10 @@ typedef struct _blocking_lock_record { files_struct *fsp; struct timeval expire_time; int lock_num; - SMB_BIG_UINT offset; - SMB_BIG_UINT count; - uint32 lock_pid; - uint32 blocking_pid; /* PID that blocks us. */ + uint64_t offset; + uint64_t count; + uint32_t lock_pid; + uint32_t blocking_pid; /* PID that blocks us. */ enum brl_flavour lock_flav; enum brl_type lock_type; char *inbuf; @@ -154,12 +154,12 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, files_struct *fsp, int lock_timeout, int lock_num, - uint32 lock_pid, + uint32_t lock_pid, enum brl_type lock_type, enum brl_flavour lock_flav, - SMB_BIG_UINT offset, - SMB_BIG_UINT count, - uint32 blocking_pid) + uint64_t offset, + uint64_t count, + uint32_t blocking_pid) { static bool set_lock_msg; size_t length = smb_len(req->inbuf)+4; @@ -331,7 +331,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) char *inbuf = blr->inbuf; files_struct *fsp = blr->fsp; uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; + uint64_t count = (uint64_t)0, offset = (uint64_t) 0; uint32 lock_pid; unsigned char locktype = CVAL(inbuf,smb_vwv3); bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); @@ -420,7 +420,7 @@ static bool process_lockingX(blocking_lock_record *blr) files_struct *fsp = blr->fsp; uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); - SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; + uint64_t count = (uint64_t)0, offset = (uint64_t)0; uint32 lock_pid; bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -704,7 +704,6 @@ static void process_blocking_lock_queue(void) * sitting around.... */ chain_size = 0; - file_chain_reset(); fsp = blr->fsp; conn = conn_find(SVAL(blr->inbuf,smb_tid)); @@ -875,8 +874,8 @@ static void process_blocking_lock_cancel_message(struct messaging_context *ctx, bool blocking_lock_cancel(files_struct *fsp, uint32 lock_pid, - SMB_BIG_UINT offset, - SMB_BIG_UINT count, + uint64_t offset, + uint64_t count, enum brl_flavour lock_flav, unsigned char locktype, NTSTATUS err) diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 2596e73380..64a4311256 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -1131,7 +1131,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw if ((can_change_time != 0) && (time(NULL) < can_change_time)) { DEBUG(1, ("user %s cannot change password now, must " "wait until %s\n", username, - http_timestring(can_change_time))); + http_timestring(talloc_tos(), can_change_time))); if (samr_reject_reason) { *samr_reject_reason = SAMR_REJECT_OTHER; } diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 818b4c70a8..d4c531ab19 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -505,7 +505,8 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) delete on close is done on normal and shutdown close. ****************************************************************************/ -static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_type) +static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, + enum file_close_type close_type) { NTSTATUS status = NT_STATUS_OK; NTSTATUS saved_status1 = NT_STATUS_OK; @@ -536,7 +537,7 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_ if (fsp->print_file) { print_fsp_end(fsp, close_type); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_OK; } @@ -585,7 +586,7 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_ conn->num_files_open, nt_errstr(status) )); - file_free(fsp); + file_free(req, fsp); return status; } @@ -593,7 +594,8 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_ Close a directory opened by an NT SMB call. ****************************************************************************/ -static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_type) +static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, + enum file_close_type close_type) { struct share_mode_lock *lck = 0; bool delete_dir = False; @@ -698,7 +700,7 @@ static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_ty * Do the code common to files and directories. */ close_filestruct(fsp); - file_free(fsp); + file_free(req, fsp); return status; } @@ -706,17 +708,18 @@ static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_ty Close a files_struct. ****************************************************************************/ -NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type) +NTSTATUS close_file(struct smb_request *req, files_struct *fsp, + enum file_close_type close_type) { NTSTATUS status; struct files_struct *base_fsp = fsp->base_fsp; if(fsp->is_directory) { - status = close_directory(fsp, close_type); + status = close_directory(req, fsp, close_type); } else if (fsp->fake_file_handle != NULL) { - status = close_fake_file(fsp); + status = close_fake_file(req, fsp); } else { - status = close_normal_file(fsp, close_type); + status = close_normal_file(req, fsp, close_type); } if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) { @@ -731,7 +734,7 @@ NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type) */ SMB_ASSERT(base_fsp->base_fsp == NULL); - close_file(base_fsp, close_type); + close_file(req, base_fsp, close_type); } return status; @@ -768,5 +771,5 @@ void msg_close_file(struct messaging_context *msg_ctx, DEBUG(10,("msg_close_file: failed to find file.\n")); return; } - close_file(fsp, NORMAL_CLOSE); + close_file(NULL, fsp, NORMAL_CLOSE); } diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index b9433bb965..7f34d2b8e2 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -252,8 +252,8 @@ void conn_free_internal(connection_struct *conn) /* Free vfs_connection_struct */ handle = conn->vfs_handles; while(handle) { - DLIST_REMOVE(conn->vfs_handles, handle); thandle = handle->next; + DLIST_REMOVE(conn->vfs_handles, handle); if (handle->free_data) handle->free_data(&handle->data); handle = thandle; diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c index 8dd5964f5f..3b72a9505a 100644 --- a/source3/smbd/connection.c +++ b/source3/smbd/connection.c @@ -2,17 +2,17 @@ Unix SMB/CIFS implementation. connection claim routines Copyright (C) Andrew Tridgell 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 the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -63,7 +63,7 @@ static int count_fn(struct db_record *rec, void *udp) { struct count_stat *cs = (struct count_stat *)udp; - + if (crec->cnum == -1) { return 0; } @@ -159,7 +159,7 @@ bool claim_connection(connection_struct *conn, const char *name, } crec.start = time(NULL); crec.bcast_msg_flags = msg_flags; - + strlcpy(crec.machine,get_remote_machine_name(),sizeof(crec.machine)); strlcpy(crec.addr,conn?conn->client_address: client_addr(get_client_fd(),addr,sizeof(addr)), @@ -224,109 +224,3 @@ bool register_message_flags(bool doreg, uint32 msg_flags) return True; } - -/********************************************************************* -*********************************************************************/ - -static TDB_DATA* make_pipe_rec_key( struct pipe_open_rec *prec ) -{ - TDB_DATA *kbuf = NULL; - fstring key_string; - - if ( !prec ) - return NULL; - - if ( (kbuf = TALLOC_P(prec, TDB_DATA)) == NULL ) { - return NULL; - } - - snprintf( key_string, sizeof(key_string), "%s/%d/%d", - prec->name, procid_to_pid(&prec->pid), prec->pnum ); - - *kbuf = string_term_tdb_data(talloc_strdup(prec, key_string)); - if (kbuf->dptr == NULL ) - return NULL; - - return kbuf; -} - -/********************************************************************* -*********************************************************************/ - -static void fill_pipe_open_rec( struct pipe_open_rec *prec, smb_np_struct *p ) -{ - prec->pid = pid_to_procid(sys_getpid()); - prec->pnum = p->pnum; - prec->uid = geteuid(); - fstrcpy( prec->name, p->name ); - - return; -} - -/********************************************************************* -*********************************************************************/ - -bool store_pipe_opendb( smb_np_struct *p ) -{ - struct db_record *dbrec; - struct pipe_open_rec *prec; - TDB_DATA *key; - TDB_DATA data; - bool ret = False; - - if ( (prec = TALLOC_P( NULL, struct pipe_open_rec)) == NULL ) { - DEBUG(0,("store_pipe_opendb: talloc failed!\n")); - return False; - } - - fill_pipe_open_rec( prec, p ); - if ( (key = make_pipe_rec_key( prec )) == NULL ) { - goto done; - } - - data.dptr = (uint8 *)prec; - data.dsize = sizeof(struct pipe_open_rec); - - if (!(dbrec = connections_fetch_record(prec, *key))) { - DEBUG(0, ("connections_fetch_record failed\n")); - goto done; - } - - ret = NT_STATUS_IS_OK(dbrec->store(dbrec, data, TDB_REPLACE)); - -done: - TALLOC_FREE( prec ); - return ret; -} - -/********************************************************************* -*********************************************************************/ - -bool delete_pipe_opendb( smb_np_struct *p ) -{ - struct db_record *dbrec; - struct pipe_open_rec *prec; - TDB_DATA *key; - bool ret = False; - - if ( (prec = TALLOC_P( NULL, struct pipe_open_rec)) == NULL ) { - DEBUG(0,("store_pipe_opendb: talloc failed!\n")); - return False; - } - - fill_pipe_open_rec( prec, p ); - if ( (key = make_pipe_rec_key( prec )) == NULL ) { - goto done; - } - - if (!(dbrec = connections_fetch_record(prec, *key))) { - DEBUG(0, ("connections_fetch_record failed\n")); - goto done; - } - - ret = NT_STATUS_IS_OK(dbrec->delete_rec(dbrec)); - -done: - TALLOC_FREE( prec ); - return ret; -} diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c index 1ddcd48d40..cd09d73923 100644 --- a/source3/smbd/dfree.c +++ b/source3/smbd/dfree.c @@ -23,10 +23,10 @@ Normalise for DOS usage. ****************************************************************************/ -static void disk_norm(bool small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) +static void disk_norm(bool small_query, uint64_t *bsize,uint64_t *dfree,uint64_t *dsize) { /* check if the disk is beyond the max disk size */ - SMB_BIG_UINT maxdisksize = lp_maxdisksize(); + uint64_t maxdisksize = lp_maxdisksize(); if (maxdisksize) { /* convert to blocks - and don't overflow */ maxdisksize = ((maxdisksize*1024)/(*bsize))*1024; @@ -62,13 +62,13 @@ static void disk_norm(bool small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree, Return number of 1K blocks available on a path and total number. ****************************************************************************/ -SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, bool small_query, - SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) +uint64_t sys_disk_free(connection_struct *conn, const char *path, bool small_query, + uint64_t *bsize,uint64_t *dfree,uint64_t *dsize) { - SMB_BIG_UINT dfree_retval; - SMB_BIG_UINT dfree_q = 0; - SMB_BIG_UINT bsize_q = 0; - SMB_BIG_UINT dsize_q = 0; + uint64_t dfree_retval; + uint64_t dfree_q = 0; + uint64_t bsize_q = 0; + uint64_t dsize_q = 0; const char *dfree_command; (*dfree) = (*dsize) = 0; @@ -90,7 +90,7 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, bool small path); if (!syscmd) { - return (SMB_BIG_UINT)-1; + return (uint64_t)-1; } DEBUG (3, ("disk_free: Running command %s\n", syscmd)); @@ -112,7 +112,7 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, bool small *bsize = STR_TO_SMB_BIG_UINT(p, NULL); else *bsize = 1024; - file_lines_free(lines); + TALLOC_FREE(lines); DEBUG (3, ("Parsed output of dfree, dsize=%u, dfree=%u, bsize=%u\n", (unsigned int)*dsize, (unsigned int)*dfree, (unsigned int)*bsize)); @@ -126,14 +126,14 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, bool small if (sys_fsusage(path, dfree, dsize) != 0) { DEBUG (0, ("disk_free: sys_fsusage() failed. Error was : %s\n", strerror(errno) )); - return (SMB_BIG_UINT)-1; + return (uint64_t)-1; } } } else { if (sys_fsusage(path, dfree, dsize) != 0) { DEBUG (0, ("disk_free: sys_fsusage() failed. Error was : %s\n", strerror(errno) )); - return (SMB_BIG_UINT)-1; + return (uint64_t)-1; } } @@ -174,16 +174,16 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, bool small Potentially returned cached dfree info. ****************************************************************************/ -SMB_BIG_UINT get_dfree_info(connection_struct *conn, +uint64_t get_dfree_info(connection_struct *conn, const char *path, bool small_query, - SMB_BIG_UINT *bsize, - SMB_BIG_UINT *dfree, - SMB_BIG_UINT *dsize) + uint64_t *bsize, + uint64_t *dfree, + uint64_t *dsize) { int dfree_cache_time = lp_dfree_cache_time(SNUM(conn)); struct dfree_cached_info *dfc = conn->dfree_info; - SMB_BIG_UINT dfree_ret; + uint64_t dfree_ret; if (!dfree_cache_time) { return SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize); @@ -199,7 +199,7 @@ SMB_BIG_UINT get_dfree_info(connection_struct *conn, dfree_ret = SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize); - if (dfree_ret == (SMB_BIG_UINT)-1) { + if (dfree_ret == (uint64_t)-1) { /* Don't cache bad data. */ return dfree_ret; } diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 88c6a51770..784b36d9bd 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -277,14 +277,15 @@ static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ * are not violating security in doing the setxattr. */ - if (!NT_STATUS_IS_OK(open_file_fchmod(conn,path,sbuf,&fsp))) + if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, path, sbuf, + &fsp))) return ret; become_root(); if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) { ret = True; } unbecome_root(); - close_file_fchmod(fsp); + close_file_fchmod(NULL, fsp); return ret; } DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr, path)); @@ -540,12 +541,13 @@ int file_set_dosmode(connection_struct *conn, const char *fname, * break batch oplocks open by others. JRA. */ files_struct *fsp; - if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,st,&fsp))) + if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname, st, + &fsp))) return -1; become_root(); ret = SMB_VFS_FCHMOD(fsp, unixmode); unbecome_root(); - close_file_fchmod(fsp); + close_file_fchmod(NULL, fsp); if (!newfile) { notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c index 8dd9abee1a..58b09604c4 100644 --- a/source3/smbd/fake_file.c +++ b/source3/smbd/fake_file.c @@ -98,7 +98,7 @@ enum FAKE_FILE_TYPE is_fake_file(const char *fname) Open a fake quota file with a share mode. ****************************************************************************/ -NTSTATUS open_fake_file(connection_struct *conn, +NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, uint16_t current_vuid, enum FAKE_FILE_TYPE fake_file_type, const char *fname, @@ -118,7 +118,7 @@ NTSTATUS open_fake_file(connection_struct *conn, } - status = file_new(conn, &fsp); + status = file_new(req, conn, &fsp); if(!NT_STATUS_IS_OK(status)) { return status; } @@ -137,7 +137,7 @@ NTSTATUS open_fake_file(connection_struct *conn, fsp->fake_file_handle = init_fake_file_handle(fake_file_type); if (fsp->fake_file_handle==NULL) { - file_free(fsp); + file_free(req, fsp); return NT_STATUS_NO_MEMORY; } @@ -146,16 +146,8 @@ NTSTATUS open_fake_file(connection_struct *conn, return NT_STATUS_OK; } -void destroy_fake_file_handle(struct fake_file_handle **fh) +NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp) { - if (!fh) { - return; - } - TALLOC_FREE(*fh); -} - -NTSTATUS close_fake_file(files_struct *fsp) -{ - file_free(fsp); + file_free(req, fsp); return NT_STATUS_OK; } diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 41a0b9296a..562f1e8d94 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -101,8 +101,7 @@ get any fatal errors that should immediately terminate the calling SMB processing whilst resolving. If the saved_last_component != 0, then the unmodified last component -of the pathname is returned there. This is used in an exceptional -case in reply_mv (so far). If saved_last_component == 0 then nothing +of the pathname is returned there. If saved_last_component == 0 then nothing is returned there. If last_component_wcard is true then a MS wildcard was detected and diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 17c473f028..4a27d02cfe 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -28,9 +28,6 @@ static int real_max_open_files; static struct bitmap *file_bmap; static files_struct *Files; - -/* a fsp to use when chaining */ -static files_struct *chain_fsp = NULL; static int files_used; @@ -57,7 +54,8 @@ static unsigned long get_gen_count(void) Find first available file slot. ****************************************************************************/ -NTSTATUS file_new(connection_struct *conn, files_struct **result) +NTSTATUS file_new(struct smb_request *req, connection_struct *conn, + files_struct **result) { int i; static int first_file; @@ -120,13 +118,17 @@ NTSTATUS file_new(connection_struct *conn, files_struct **result) DEBUG(5,("allocated file structure %d, fnum = %d (%d used)\n", i, fsp->fnum, files_used)); - chain_fsp = fsp; - - /* A new fsp invalidates a negative fsp_fi_cache. */ - if (fsp_fi_cache.fsp == NULL) { - ZERO_STRUCT(fsp_fi_cache); + if (req != NULL) { + req->chain_fsp = fsp; } + /* A new fsp invalidates the positive and + negative fsp_fi_cache as the new fsp is pushed + at the start of the list and we search from + a cache hit to the *end* of the list. */ + + ZERO_STRUCT(fsp_fi_cache); + *result = fsp; return NT_STATUS_OK; } @@ -142,7 +144,7 @@ void file_close_conn(connection_struct *conn) for (fsp=Files;fsp;fsp=next) { next = fsp->next; if (fsp->conn == conn) { - close_file(fsp,SHUTDOWN_CLOSE); + close_file(NULL, fsp, SHUTDOWN_CLOSE); } } } @@ -158,7 +160,7 @@ void file_close_pid(uint16 smbpid, int vuid) for (fsp=Files;fsp;fsp=next) { next = fsp->next; if ((fsp->file_pid == smbpid) && (fsp->vuid == vuid)) { - close_file(fsp,SHUTDOWN_CLOSE); + close_file(NULL, fsp, SHUTDOWN_CLOSE); } } } @@ -216,7 +218,7 @@ void file_close_user(int vuid) for (fsp=Files;fsp;fsp=next) { next=fsp->next; if (fsp->vuid == vuid) { - close_file(fsp,SHUTDOWN_CLOSE); + close_file(NULL, fsp, SHUTDOWN_CLOSE); } } } @@ -326,8 +328,7 @@ files_struct *file_find_di_first(struct file_id id) fsp_fi_cache.id = id; for (fsp=Files;fsp;fsp=fsp->next) { - if ( fsp->fh->fd != -1 && - file_id_equal(&fsp->file_id, &id)) { + if (file_id_equal(&fsp->file_id, &id)) { /* Setup positive cache. */ fsp_fi_cache.fsp = fsp; return fsp; @@ -348,8 +349,7 @@ files_struct *file_find_di_next(files_struct *start_fsp) files_struct *fsp; for (fsp = start_fsp->next;fsp;fsp=fsp->next) { - if ( fsp->fh->fd != -1 && - file_id_equal(&fsp->file_id, &start_fsp->file_id)) { + if (file_id_equal(&fsp->file_id, &start_fsp->file_id)) { return fsp; } } @@ -394,15 +394,13 @@ void file_sync_all(connection_struct *conn) Free up a fsp. ****************************************************************************/ -void file_free(files_struct *fsp) +void file_free(struct smb_request *req, files_struct *fsp) { DLIST_REMOVE(Files, fsp); string_free(&fsp->fsp_name); - if (fsp->fake_file_handle) { - destroy_fake_file_handle(&fsp->fake_file_handle); - } + TALLOC_FREE(fsp->fake_file_handle); if (fsp->fh->ref_count == 1) { SAFE_FREE(fsp->fh); @@ -431,8 +429,8 @@ void file_free(files_struct *fsp) information */ ZERO_STRUCTP(fsp); - if (fsp == chain_fsp) { - chain_fsp = NULL; + if ((req != NULL) && (fsp == req->chain_fsp)) { + req->chain_fsp = NULL; } /* Closing a file can invalidate the positive cache. */ @@ -472,44 +470,33 @@ files_struct *file_fnum(uint16 fnum) Get an fsp from a packet given the offset of a 16 bit fnum. ****************************************************************************/ -files_struct *file_fsp(uint16 fid) +files_struct *file_fsp(struct smb_request *req, uint16 fid) { files_struct *fsp; - if (chain_fsp) { - return chain_fsp; + if ((req != NULL) && (req->chain_fsp != NULL)) { + return req->chain_fsp; } fsp = file_fnum(fid); - if (fsp) { - chain_fsp = fsp; + if ((fsp != NULL) && (req != NULL)) { + req->chain_fsp = fsp; } return fsp; } /**************************************************************************** - Reset the chained fsp - done at the start of a packet reply. -****************************************************************************/ - -void file_chain_reset(void) -{ - chain_fsp = NULL; -} - -/**************************************************************************** Duplicate the file handle part for a DOS or FCB open. ****************************************************************************/ -NTSTATUS dup_file_fsp(files_struct *fsp, - uint32 access_mask, - uint32 share_access, - uint32 create_options, - files_struct **result) +NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *fsp, + uint32 access_mask, uint32 share_access, + uint32 create_options, files_struct **result) { NTSTATUS status; files_struct *dup_fsp; - status = file_new(fsp->conn, &dup_fsp); + status = file_new(NULL, fsp->conn, &dup_fsp); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index f4c45999ba..0ce226809e 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -5,17 +5,17 @@ SMB Version handling Copyright (C) John H Terpstra 1995-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 the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -162,7 +162,7 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, copy_trans_params_and_data(outbuf, align, rparam, tot_param_sent, this_lparam, rdata, tot_data_sent, this_ldata); - + SSVAL(outbuf,smb_vwv3,this_lparam); SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf)); SSVAL(outbuf,smb_vwv5,tot_param_sent); @@ -194,11 +194,15 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, Start the first part of an RPC reply which began with an SMBtrans request. ****************************************************************************/ -static void api_rpc_trans_reply(connection_struct *conn, struct smb_request *req, smb_np_struct *p) +static void api_rpc_trans_reply(connection_struct *conn, + struct smb_request *req, + files_struct *fsp, + int max_trans_reply) { bool is_data_outstanding; - char *rdata = (char *)SMB_MALLOC(p->max_trans_reply); - int data_len; + uint8_t *rdata = SMB_MALLOC_ARRAY(uint8_t, max_trans_reply); + ssize_t data_len; + NTSTATUS status; if(rdata == NULL) { DEBUG(0,("api_rpc_trans_reply: malloc fail.\n")); @@ -206,14 +210,15 @@ static void api_rpc_trans_reply(connection_struct *conn, struct smb_request *req return; } - if((data_len = read_from_pipe( p, rdata, p->max_trans_reply, - &is_data_outstanding)) < 0) { + status = np_read(fsp, rdata, max_trans_reply, &data_len, + &is_data_outstanding); + if (!NT_STATUS_IS_OK(status)) { SAFE_FREE(rdata); api_no_reply(conn,req); return; } - send_trans_reply(conn, req->inbuf, NULL, 0, rdata, data_len, + send_trans_reply(conn, req->inbuf, NULL, 0, (char *)rdata, data_len, is_data_outstanding); SAFE_FREE(rdata); return; @@ -223,25 +228,18 @@ static void api_rpc_trans_reply(connection_struct *conn, struct smb_request *req WaitNamedPipeHandleState ****************************************************************************/ -static void api_WNPHS(connection_struct *conn, struct smb_request *req, smb_np_struct *p, - char *param, int param_len) +static void api_WNPHS(connection_struct *conn, struct smb_request *req, + struct files_struct *fsp, char *param, int param_len) { - uint16 priority; - if (!param || param_len < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } - priority = SVAL(param,0); - DEBUG(4,("WaitNamedPipeHandleState priority %x\n", priority)); + DEBUG(4,("WaitNamedPipeHandleState priority %x\n", + (int)SVAL(param,0))); - if (wait_rpc_pipe_hnd_state(p, priority)) { - /* now send the reply */ - send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False); - return; - } - api_no_reply(conn,req); + send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False); } @@ -249,25 +247,17 @@ static void api_WNPHS(connection_struct *conn, struct smb_request *req, smb_np_s SetNamedPipeHandleState ****************************************************************************/ -static void api_SNPHS(connection_struct *conn, struct smb_request *req, smb_np_struct *p, - char *param, int param_len) +static void api_SNPHS(connection_struct *conn, struct smb_request *req, + struct files_struct *fsp, char *param, int param_len) { - uint16 id; - if (!param || param_len < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } - id = SVAL(param,0); - DEBUG(4,("SetNamedPipeHandleState to code %x\n", id)); + DEBUG(4,("SetNamedPipeHandleState to code %x\n", (int)SVAL(param,0))); - if (set_rpc_pipe_hnd_state(p, id)) { - /* now send the reply */ - send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False); - return; - } - api_no_reply(conn,req); + send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False); } @@ -297,14 +287,14 @@ static void api_no_reply(connection_struct *conn, struct smb_request *req) static void api_fd_reply(connection_struct *conn, uint16 vuid, struct smb_request *req, - uint16 *setup, char *data, char *params, + uint16 *setup, uint8_t *data, char *params, int suwcnt, int tdscnt, int tpscnt, int mdrcnt, int mprcnt) { - bool reply = False; - smb_np_struct *p = NULL; + struct files_struct *fsp; int pnum; int subcommand; + NTSTATUS status; DEBUG(5,("api_fd_reply\n")); @@ -318,12 +308,14 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid, /* Get the file handle and hence the file name. */ /* * NB. The setup array has already been transformed - * via SVAL and so is in gost byte order. + * via SVAL and so is in host byte order. */ pnum = ((int)setup[1]) & 0xFFFF; subcommand = ((int)setup[0]) & 0xFFFF; - if(!(p = get_rpc_pipe(pnum))) { + fsp = file_fsp(req, pnum); + + if (!fsp_is_np(fsp)) { if (subcommand == TRANSACT_WAITNAMEDPIPEHANDLESTATE) { /* Win9x does this call with a unicode pipe name, not a pnum. */ /* Just return success for now... */ @@ -338,37 +330,37 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid, return; } - if (vuid != p->vuid) { + if (vuid != fsp->vuid) { DEBUG(1, ("Got pipe request (pnum %x) using invalid VUID %d, " - "expected %d\n", pnum, vuid, p->vuid)); + "expected %d\n", pnum, vuid, fsp->vuid)); reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } - DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", subcommand, p->name, pnum)); - - /* record maximum data length that can be transmitted in an SMBtrans */ - p->max_trans_reply = mdrcnt; + DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", + subcommand, fsp->fsp_name, pnum)); - DEBUG(10,("api_fd_reply: p:%p max_trans_reply: %d\n", p, p->max_trans_reply)); + DEBUG(10, ("api_fd_reply: p:%p max_trans_reply: %d\n", fsp, mdrcnt)); switch (subcommand) { - case TRANSACT_DCERPCCMD: + case TRANSACT_DCERPCCMD: { /* dce/rpc command */ - reply = write_to_pipe(p, data, tdscnt); - if (!reply) { + ssize_t nwritten; + status = np_write(fsp, data, tdscnt, &nwritten); + if (!NT_STATUS_IS_OK(status)) { api_no_reply(conn, req); return; } - api_rpc_trans_reply(conn, req, p); + api_rpc_trans_reply(conn, req, fsp, mdrcnt); break; + } case TRANSACT_WAITNAMEDPIPEHANDLESTATE: /* Wait Named Pipe Handle state */ - api_WNPHS(conn, req, p, params, tpscnt); + api_WNPHS(conn, req, fsp, params, tpscnt); break; case TRANSACT_SETNAMEDPIPEHANDLESTATE: /* Set Named Pipe Handle state */ - api_SNPHS(conn, req, p, params, tpscnt); + api_SNPHS(conn, req, fsp, params, tpscnt); break; default: reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -406,7 +398,7 @@ static void named_pipe(connection_struct *conn, uint16 vuid, DEBUG(4,("named pipe command from Win95 (wow!)\n")); api_fd_reply(conn, vuid, req, - setup, data, params, + setup, (uint8_t *)data, params, suwcnt, tdscnt, tpscnt, mdrcnt, mprcnt); return; @@ -414,7 +406,7 @@ static void named_pipe(connection_struct *conn, uint16 vuid, if (strlen(name) < 1) { api_fd_reply(conn, vuid, req, - setup, data, + setup, (uint8_t *)data, params, suwcnt, tdscnt, tpscnt, mdrcnt, mprcnt); return; @@ -735,11 +727,11 @@ void reply_transs(struct smb_request *req) state->received_param += pcnt; state->received_data += dcnt; - + if ((state->received_data > state->total_data) || (state->received_param > state->total_param)) goto bad_param; - + if (pcnt) { if (pdisp > state->total_param || pcnt > state->total_param || diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index fe1d766b9d..0c866da706 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1154,7 +1154,7 @@ static int get_server_info(uint32 servertype, bool local_list_only; int i; - lines = file_lines_load(lock_path(SERVER_LIST), NULL, 0); + lines = file_lines_load(lock_path(SERVER_LIST), NULL, 0, NULL); if (!lines) { DEBUG(4,("Can't open %s - %s\n",lock_path(SERVER_LIST),strerror(errno))); return 0; @@ -1186,7 +1186,7 @@ static int get_server_info(uint32 servertype, *servers = SMB_REALLOC_ARRAY(*servers,struct srv_info_struct, alloced); if (!*servers) { DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n")); - file_lines_free(lines); + TALLOC_FREE(lines); return 0; } memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count)); @@ -1267,7 +1267,7 @@ static int get_server_info(uint32 servertype, } } - file_lines_free(lines); + TALLOC_FREE(lines); return count; } diff --git a/source3/smbd/map_username.c b/source3/smbd/map_username.c index 7536758bcb..a8899dd538 100644 --- a/source3/smbd/map_username.c +++ b/source3/smbd/map_username.c @@ -116,7 +116,7 @@ bool map_username(fstring user) } numlines = 0; - qlines = fd_lines_load(fd, &numlines,0); + qlines = fd_lines_load(fd, &numlines,0, NULL); DEBUGADD(10,("Lines returned = [%d]\n", numlines)); close(fd); @@ -127,7 +127,7 @@ bool map_username(fstring user) fstrcpy( user, qlines[0] ); } - file_lines_free(qlines); + TALLOC_FREE(qlines); return numlines != 0; } diff --git a/source3/smbd/noquotas.c b/source3/smbd/noquotas.c index c8ff8edf62..392b32437a 100644 --- a/source3/smbd/noquotas.c +++ b/source3/smbd/noquotas.c @@ -23,14 +23,14 @@ * Needed for auto generation of proto.h. */ -bool disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) +bool disk_quotas(const char *path,uint64_t *bsize,uint64_t *dfree,uint64_t *dsize) { (*bsize) = 512; /* This value should be ignored */ /* And just to be sure we set some values that hopefully */ /* will be larger that any possible real-world value */ - (*dfree) = (SMB_BIG_UINT)-1; - (*dsize) = (SMB_BIG_UINT)-1; + (*dfree) = (uint64_t)-1; + (*dsize) = (uint64_t)-1; /* As we have select not to use quotas, allways fail */ return False; diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c index 84b8e1098e..06da717799 100644 --- a/source3/smbd/notify_internal.c +++ b/source3/smbd/notify_internal.c @@ -166,7 +166,7 @@ static NTSTATUS notify_load(struct notify_context *notify, struct db_record *rec status = NT_STATUS_OK; if (blob.length > 0) { enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->array, + ndr_err = ndr_pull_struct_blob(&blob, notify->array, NULL, notify->array, (ndr_pull_flags_fn_t)ndr_pull_notify_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -220,7 +220,7 @@ static NTSTATUS notify_save(struct notify_context *notify, struct db_record *rec tmp_ctx = talloc_new(notify); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, notify->array, (ndr_push_flags_fn_t)ndr_push_notify_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -258,7 +258,7 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data return; } - ndr_err = ndr_pull_struct_blob(data, tmp_ctx, &ev, + ndr_err = ndr_pull_struct_blob(data, tmp_ctx, NULL, &ev, (ndr_pull_flags_fn_t)ndr_pull_notify_event); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -561,7 +561,7 @@ static NTSTATUS notify_send(struct notify_context *notify, struct notify_entry * tmp_ctx = talloc_new(notify); - ndr_err = ndr_push_struct_blob(&data, tmp_ctx, &ev, + ndr_err = ndr_push_struct_blob(&data, tmp_ctx, NULL, &ev, (ndr_push_flags_fn_t)ndr_push_notify_event); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); diff --git a/source3/smbd/ntquotas.c b/source3/smbd/ntquotas.c index c616c494dc..ae7034011e 100644 --- a/source3/smbd/ntquotas.c +++ b/source3/smbd/ntquotas.c @@ -22,14 +22,14 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_QUOTA -static SMB_BIG_UINT limit_nt2unix(SMB_BIG_UINT in, SMB_BIG_UINT bsize) +static uint64_t limit_nt2unix(uint64_t in, uint64_t bsize) { - SMB_BIG_UINT ret = (SMB_BIG_UINT)0; + uint64_t ret = (uint64_t)0; - ret = (SMB_BIG_UINT)(in/bsize); + ret = (uint64_t)(in/bsize); if (in>0 && ret==0) { /* we have to make sure that a overflow didn't set NO_LIMIT */ - ret = (SMB_BIG_UINT)1; + ret = (uint64_t)1; } if (in == SMB_NTQUOTAS_NO_LIMIT) @@ -42,11 +42,11 @@ static SMB_BIG_UINT limit_nt2unix(SMB_BIG_UINT in, SMB_BIG_UINT bsize) return ret; } -static SMB_BIG_UINT limit_unix2nt(SMB_BIG_UINT in, SMB_BIG_UINT bsize) +static uint64_t limit_unix2nt(uint64_t in, uint64_t bsize) { - SMB_BIG_UINT ret = (SMB_BIG_UINT)0; + uint64_t ret = (uint64_t)0; - ret = (SMB_BIG_UINT)(in*bsize); + ret = (uint64_t)(in*bsize); if (ret < in) { /* we overflow */ @@ -59,14 +59,14 @@ static SMB_BIG_UINT limit_unix2nt(SMB_BIG_UINT in, SMB_BIG_UINT bsize) return ret; } -static SMB_BIG_UINT limit_blk2inodes(SMB_BIG_UINT in) +static uint64_t limit_blk2inodes(uint64_t in) { - SMB_BIG_UINT ret = (SMB_BIG_UINT)0; + uint64_t ret = (uint64_t)0; - ret = (SMB_BIG_UINT)(in/2); + ret = (uint64_t)(in/2); if (ret == 0 && in != 0) - ret = (SMB_BIG_UINT)1; + ret = (uint64_t)1; return ret; } @@ -100,7 +100,7 @@ int vfs_get_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, return ret; } - qt->usedspace = (SMB_BIG_UINT)D.curblocks*D.bsize; + qt->usedspace = (uint64_t)D.curblocks*D.bsize; qt->softlim = limit_unix2nt(D.softlimit, D.bsize); qt->hardlim = limit_unix2nt(D.hardlimit, D.bsize); qt->qflags = D.qflags; @@ -121,7 +121,7 @@ int vfs_set_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, id.uid = -1; - D.bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + D.bsize = (uint64_t)QUOTABLOCK_SIZE; D.softlimit = limit_nt2unix(qt->softlim,D.bsize); D.hardlimit = limit_nt2unix(qt->hardlim,D.bsize); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 584399c86c..69ddcdae8d 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -22,6 +22,7 @@ extern int max_send; extern enum protocol_types Protocol; +extern const struct generic_mapping file_generic_mapping; static char *nttrans_realloc(char **ptr, size_t size) { @@ -267,7 +268,8 @@ bool is_ntfs_stream_name(const char *fname) static void nt_open_pipe(char *fname, connection_struct *conn, struct smb_request *req, int *ppnum) { - smb_np_struct *p = NULL; + files_struct *fsp; + NTSTATUS status; DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname)); @@ -284,19 +286,13 @@ static void nt_open_pipe(char *fname, connection_struct *conn, DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname)); - p = open_rpc_pipe_p(fname, conn, req->vuid); - if (!p) { - reply_doserror(req, ERRSRV, ERRnofids); + status = np_open(req, conn, fname, &fsp); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); return; } - /* TODO: Add pipe to db */ - - if ( !store_pipe_opendb( p ) ) { - DEBUG(3,("nt_open_pipe: failed to store %s pipe open.\n", fname)); - } - - *ppnum = p->pnum; + *ppnum = fsp->fnum; return; } @@ -390,7 +386,7 @@ void reply_ntcreate_and_X(struct smb_request *req) uint32 create_disposition; uint32 create_options; uint16 root_dir_fid; - SMB_BIG_UINT allocation_size; + uint64_t allocation_size; /* Breakout the oplock request bits so we can set the reply bits separately. */ uint32 fattr=0; @@ -422,10 +418,10 @@ void reply_ntcreate_and_X(struct smb_request *req) create_options = IVAL(req->inbuf,smb_ntcreate_CreateOptions); root_dir_fid = (uint16)IVAL(req->inbuf,smb_ntcreate_RootDirectoryFid); - allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf, + allocation_size = (uint64_t)IVAL(req->inbuf, smb_ntcreate_AllocationSize); #ifdef LARGE_SMB_OFF_T - allocation_size |= (((SMB_BIG_UINT)IVAL( + allocation_size |= (((uint64_t)IVAL( req->inbuf, smb_ntcreate_AllocationSize + 4)) << 32); #endif @@ -739,6 +735,10 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len, security_info_sent &= ~DACL_SECURITY_INFORMATION; } + /* Convert all the generic bits. */ + security_acl_map_generic(psd->dacl, &file_generic_mapping); + security_acl_map_generic(psd->sacl, &file_generic_mapping); + status = SMB_VFS_FSET_NT_ACL(fsp, security_info_sent, psd); TALLOC_FREE(psd); @@ -814,7 +814,7 @@ static void call_nt_transact_create(connection_struct *conn, struct ea_list *ea_list = NULL; NTSTATUS status; size_t param_len; - SMB_BIG_UINT allocation_size; + uint64_t allocation_size; int oplock_request; uint8_t oplock_granted; TALLOC_CTX *ctx = talloc_tos(); @@ -857,9 +857,9 @@ static void call_nt_transact_create(connection_struct *conn, sd_len = IVAL(params,36); ea_len = IVAL(params,40); root_dir_fid = (uint16)IVAL(params,4); - allocation_size = (SMB_BIG_UINT)IVAL(params,12); + allocation_size = (uint64_t)IVAL(params,12); #ifdef LARGE_SMB_OFF_T - allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32); + allocation_size |= (((uint64_t)IVAL(params,16)) << 32); #endif /* @@ -1183,7 +1183,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, &info, &fsp2); if (!NT_STATUS_IS_OK(status)) { - close_file(fsp1,ERROR_CLOSE); + close_file(NULL, fsp1, ERROR_CLOSE); return status; } @@ -1197,12 +1197,12 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, * Thus we don't look at the error return from the * close of fsp1. */ - close_file(fsp1,NORMAL_CLOSE); + close_file(NULL, fsp1, NORMAL_CLOSE); /* Ensure the modtime is set correctly on the destination file. */ set_close_write_time(fsp2, get_mtimespec(&sbuf1)); - status = close_file(fsp2,NORMAL_CLOSE); + status = close_file(NULL, fsp2, NORMAL_CLOSE); /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it creates the file. This isn't the correct thing to do in the copy @@ -1394,7 +1394,7 @@ static void call_nt_transact_notify_change(connection_struct *conn, return; } - fsp = file_fsp(SVAL(setup,4)); + fsp = file_fsp(req, SVAL(setup,4)); filter = IVAL(setup, 0); recursive = (SVAL(setup, 6) != 0) ? True : False; @@ -1494,7 +1494,7 @@ static void call_nt_transact_rename(connection_struct *conn, return; } - fsp = file_fsp(SVAL(params, 0)); + fsp = file_fsp(req, SVAL(params, 0)); if (!check_fsp(conn, req, fsp)) { return; } @@ -1563,7 +1563,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, return; } - fsp = file_fsp(SVAL(params,0)); + fsp = file_fsp(req, SVAL(params,0)); if(!fsp) { reply_doserror(req, ERRDOS, ERRbadfid); return; @@ -1659,7 +1659,7 @@ static void call_nt_transact_set_security_desc(connection_struct *conn, return; } - if((fsp = file_fsp(SVAL(params,0))) == NULL) { + if((fsp = file_fsp(req, SVAL(params,0))) == NULL) { reply_doserror(req, ERRDOS, ERRbadfid); return; } @@ -1723,7 +1723,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", function, fidnum, isFSctl, compfilter)); - fsp=file_fsp(fidnum); + fsp=file_fsp(req, fidnum); /* this check is done in each implemented function case for now because I don't want to break anything... --metze FSP_BELONGS_CONN(fsp,conn);*/ @@ -2030,7 +2030,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, } /* maybe we can check the quota_fnum */ - fsp = file_fsp(SVAL(params,0)); + fsp = file_fsp(req, SVAL(params,0)); if (!check_fsp_ntquota_handle(conn, req, fsp)) { DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); reply_nterror(req, NT_STATUS_INVALID_HANDLE); @@ -2127,16 +2127,16 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, /* then the len of the SID 4 bytes */ SIVAL(entry,4,sid_len); - /* unknown data 8 bytes SMB_BIG_UINT */ - SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/ + /* unknown data 8 bytes uint64_t */ + SBIG_UINT(entry,8,(uint64_t)0); /* this is not 0 in windows...-metze*/ - /* the used disk space 8 bytes SMB_BIG_UINT */ + /* the used disk space 8 bytes uint64_t */ SBIG_UINT(entry,16,tmp_list->quotas->usedspace); - /* the soft quotas 8 bytes SMB_BIG_UINT */ + /* the soft quotas 8 bytes uint64_t */ SBIG_UINT(entry,24,tmp_list->quotas->softlim); - /* the hard quotas 8 bytes SMB_BIG_UINT */ + /* the hard quotas 8 bytes uint64_t */ SBIG_UINT(entry,32,tmp_list->quotas->hardlim); /* and now the SID */ @@ -2225,16 +2225,16 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, /* then the len of the SID 4 bytes */ SIVAL(entry,4,sid_len); - /* unknown data 8 bytes SMB_BIG_UINT */ - SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/ + /* unknown data 8 bytes uint64_t */ + SBIG_UINT(entry,8,(uint64_t)0); /* this is not 0 in windows...-mezte*/ - /* the used disk space 8 bytes SMB_BIG_UINT */ + /* the used disk space 8 bytes uint64_t */ SBIG_UINT(entry,16,qt.usedspace); - /* the soft quotas 8 bytes SMB_BIG_UINT */ + /* the soft quotas 8 bytes uint64_t */ SBIG_UINT(entry,24,qt.softlim); - /* the hard quotas 8 bytes SMB_BIG_UINT */ + /* the hard quotas 8 bytes uint64_t */ SBIG_UINT(entry,32,qt.hardlim); /* and now the SID */ @@ -2297,7 +2297,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, } /* maybe we can check the quota_fnum */ - fsp = file_fsp(SVAL(params,0)); + fsp = file_fsp(req, SVAL(params,0)); if (!check_fsp_ntquota_handle(conn, req, fsp)) { DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); reply_nterror(req, NT_STATUS_INVALID_HANDLE); @@ -2328,10 +2328,10 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, * maybe its the change time in NTTIME */ - /* the used space 8 bytes (SMB_BIG_UINT)*/ - qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16); + /* the used space 8 bytes (uint64_t)*/ + qt.usedspace = (uint64_t)IVAL(pdata,16); #ifdef LARGE_SMB_OFF_T - qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32); + qt.usedspace |= (((uint64_t)IVAL(pdata,20)) << 32); #else /* LARGE_SMB_OFF_T */ if ((IVAL(pdata,20) != 0)&& ((qt.usedspace != 0xFFFFFFFF)|| @@ -2342,10 +2342,10 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, } #endif /* LARGE_SMB_OFF_T */ - /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ - qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24); + /* the soft quotas 8 bytes (uint64_t)*/ + qt.softlim = (uint64_t)IVAL(pdata,24); #ifdef LARGE_SMB_OFF_T - qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32); + qt.softlim |= (((uint64_t)IVAL(pdata,28)) << 32); #else /* LARGE_SMB_OFF_T */ if ((IVAL(pdata,28) != 0)&& ((qt.softlim != 0xFFFFFFFF)|| @@ -2356,10 +2356,10 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, } #endif /* LARGE_SMB_OFF_T */ - /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ - qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32); + /* the hard quotas 8 bytes (uint64_t)*/ + qt.hardlim = (uint64_t)IVAL(pdata,32); #ifdef LARGE_SMB_OFF_T - qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32); + qt.hardlim |= (((uint64_t)IVAL(pdata,36)) << 32); #else /* LARGE_SMB_OFF_T */ if ((IVAL(pdata,36) != 0)&& ((qt.hardlim != 0xFFFFFFFF)|| diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 8b32907a4b..d858fb969f 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -890,7 +890,8 @@ static bool open_match_attributes(connection_struct *conn, Try and find a duplicated file handle. ****************************************************************************/ -static files_struct *fcb_or_dos_open(connection_struct *conn, +static files_struct *fcb_or_dos_open(struct smb_request *req, + connection_struct *conn, const char *fname, struct file_id id, uint16 file_pid, @@ -940,7 +941,7 @@ static files_struct *fcb_or_dos_open(connection_struct *conn, } /* We need to duplicate this fsp. */ - if (!NT_STATUS_IS_OK(dup_file_fsp(fsp, access_mask, share_access, + if (!NT_STATUS_IS_OK(dup_file_fsp(req, fsp, access_mask, share_access, create_options, &dup_fsp))) { return NULL; } @@ -1178,7 +1179,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname)); - return print_fsp_open(conn, fname, req->vuid, result); + return print_fsp_open(req, conn, fname, req->vuid, result); } if (!parent_dirname_talloc(talloc_tos(), fname, &parent_dir, @@ -1435,7 +1436,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, return NT_STATUS_ACCESS_DENIED; } - status = file_new(conn, &fsp); + status = file_new(req, conn, &fsp); if(!NT_STATUS_IS_OK(status)) { return status; } @@ -1464,7 +1465,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, fname, &old_write_time); if (lck == NULL) { - file_free(fsp); + file_free(req, fsp); DEBUG(0, ("Could not get share mode lock\n")); return NT_STATUS_SHARING_VIOLATION; } @@ -1475,7 +1476,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, oplock_request)) { schedule_defer_open(lck, request_time, req); TALLOC_FREE(lck); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_SHARING_VIOLATION; } @@ -1495,7 +1496,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, oplock_request)) { schedule_defer_open(lck, request_time, req); TALLOC_FREE(lck); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_SHARING_VIOLATION; } } @@ -1503,7 +1504,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) { /* DELETE_PENDING is not deferred for a second */ TALLOC_FREE(lck); - file_free(fsp); + file_free(req, fsp); return status; } @@ -1524,13 +1525,13 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, DEBUG(0, ("DOS open without an SMB " "request!\n")); TALLOC_FREE(lck); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_INTERNAL_ERROR; } /* Use the client requested access mask here, * not the one we open with. */ - fsp_dup = fcb_or_dos_open(conn, fname, id, + fsp_dup = fcb_or_dos_open(req, conn, fname, id, req->smbpid, req->vuid, access_mask, @@ -1539,7 +1540,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, if (fsp_dup) { TALLOC_FREE(lck); - file_free(fsp); + file_free(req, fsp); if (pinfo) { *pinfo = FILE_WAS_OPENED; } @@ -1625,7 +1626,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, } else { status = NT_STATUS_ACCESS_DENIED; } - file_free(fsp); + file_free(req, fsp); return status; } @@ -1663,7 +1664,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, if (lck != NULL) { TALLOC_FREE(lck); } - file_free(fsp); + file_free(req, fsp); return fsp_open; } @@ -1694,7 +1695,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, DEBUG(0, ("open_file_ntcreate: Could not get share " "mode lock for %s\n", fname)); fd_close(fsp); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_SHARING_VIOLATION; } @@ -1705,7 +1706,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, schedule_defer_open(lck, request_time, req); TALLOC_FREE(lck); fd_close(fsp); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_SHARING_VIOLATION; } @@ -1724,7 +1725,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, schedule_defer_open(lck, request_time, req); TALLOC_FREE(lck); fd_close(fsp); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_SHARING_VIOLATION; } } @@ -1733,7 +1734,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, struct deferred_open_record state; fd_close(fsp); - file_free(fsp); + file_free(req, fsp); state.delayed_for_oplocks = False; state.id = id; @@ -1775,7 +1776,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, TALLOC_FREE(lck); fd_close(fsp); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_SHARING_VIOLATION; } @@ -1801,7 +1802,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, status = map_nt_error_from_unix(errno); TALLOC_FREE(lck); fd_close(fsp); - file_free(fsp); + file_free(req, fsp); return status; } } @@ -1852,7 +1853,8 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, /* Handle strange delete on close create semantics. */ if ((create_options & FILE_DELETE_ON_CLOSE) - && (is_ntfs_stream_name(fname) + && (((conn->fs_capabilities & FILE_NAMED_STREAMS) + && is_ntfs_stream_name(fname)) || can_set_initial_delete_on_close(lck))) { status = can_set_delete_on_close(fsp, True, new_dos_attributes); @@ -1861,7 +1863,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, del_share_mode(lck, fsp); TALLOC_FREE(lck); fd_close(fsp); - file_free(fsp); + file_free(req, fsp); return status; } /* Note that here we set the *inital* delete on close flag, @@ -1947,7 +1949,8 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, Open a file for for write to ensure that we can fchmod it. ****************************************************************************/ -NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname, +NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn, + const char *fname, SMB_STRUCT_STAT *psbuf, files_struct **result) { files_struct *fsp = NULL; @@ -1957,7 +1960,7 @@ NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname, return NT_STATUS_INVALID_PARAMETER; } - status = file_new(conn, &fsp); + status = file_new(req, conn, &fsp); if(!NT_STATUS_IS_OK(status)) { return status; } @@ -1974,7 +1977,7 @@ NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname, */ if (!NT_STATUS_IS_OK(status)) { - file_free(fsp); + file_free(req, fsp); return status; } @@ -1986,10 +1989,10 @@ NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname, Close the fchmod file fd - ensure no locks are lost. ****************************************************************************/ -NTSTATUS close_file_fchmod(files_struct *fsp) +NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp) { NTSTATUS status = fd_close(fsp); - file_free(fsp); + file_free(req, fsp); return status; } @@ -2116,7 +2119,9 @@ NTSTATUS open_directory(connection_struct *conn, (unsigned int)create_disposition, (unsigned int)file_attributes)); - if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) && is_ntfs_stream_name(fname)) { + if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) && + (conn->fs_capabilities & FILE_NAMED_STREAMS) && + is_ntfs_stream_name(fname)) { DEBUG(2, ("open_directory: %s is a stream name!\n", fname)); return NT_STATUS_NOT_A_DIRECTORY; } @@ -2195,7 +2200,7 @@ NTSTATUS open_directory(connection_struct *conn, return NT_STATUS_NOT_A_DIRECTORY; } - status = file_new(conn, &fsp); + status = file_new(req, conn, &fsp); if(!NT_STATUS_IS_OK(status)) { return status; } @@ -2233,7 +2238,7 @@ NTSTATUS open_directory(connection_struct *conn, if (lck == NULL) { DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname)); - file_free(fsp); + file_free(req, fsp); return NT_STATUS_SHARING_VIOLATION; } @@ -2243,7 +2248,7 @@ NTSTATUS open_directory(connection_struct *conn, if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(lck); - file_free(fsp); + file_free(req, fsp); return status; } @@ -2256,7 +2261,7 @@ NTSTATUS open_directory(connection_struct *conn, status = can_set_delete_on_close(fsp, True, 0); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) { TALLOC_FREE(lck); - file_free(fsp); + file_free(req, fsp); return status; } @@ -2297,7 +2302,7 @@ NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, cons &fsp); if (NT_STATUS_IS_OK(status)) { - close_file(fsp, NORMAL_CLOSE); + close_file(req, fsp, NORMAL_CLOSE); } return status; @@ -2507,7 +2512,7 @@ static NTSTATUS open_streams_for_delete(connection_struct *conn, DEBUG(10, ("Closing stream # %d, %s\n", i, streams[i]->fsp_name)); - close_file(streams[i], NORMAL_CLOSE); + close_file(NULL, streams[i], NORMAL_CLOSE); } fail: @@ -2528,7 +2533,7 @@ NTSTATUS create_file_unixpath(connection_struct *conn, uint32_t create_options, uint32_t file_attributes, uint32_t oplock_request, - SMB_BIG_UINT allocation_size, + uint64_t allocation_size, struct security_descriptor *sd, struct ea_list *ea_list, @@ -2605,9 +2610,7 @@ NTSTATUS create_file_unixpath(connection_struct *conn, && (create_disposition != FILE_CREATE) && (share_access & FILE_SHARE_DELETE) && (access_mask & DELETE_ACCESS) - && (((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) - && !lp_delete_readonly(SNUM(conn))) - || !can_delete_file_in_directory(conn, fname))) { + && (!can_delete_file_in_directory(conn, fname))) { status = NT_STATUS_ACCESS_DENIED; goto fail; } @@ -2763,6 +2766,10 @@ NTSTATUS create_file_unixpath(connection_struct *conn, fsp->access_mask = FILE_GENERIC_ALL; + /* Convert all the generic bits. */ + security_acl_map_generic(sd->dacl, &file_generic_mapping); + security_acl_map_generic(sd->sacl, &file_generic_mapping); + status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd); fsp->access_mask = saved_access_mask; @@ -2802,7 +2809,7 @@ NTSTATUS create_file_unixpath(connection_struct *conn, } } else { fsp->initial_allocation_size = smb_roundup( - fsp->conn, (SMB_BIG_UINT)sbuf.st_size); + fsp->conn, (uint64_t)sbuf.st_size); } } @@ -2836,11 +2843,11 @@ NTSTATUS create_file_unixpath(connection_struct *conn, DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status))); if (fsp != NULL) { - close_file(fsp, ERROR_CLOSE); + close_file(req, fsp, ERROR_CLOSE); fsp = NULL; } if (base_fsp != NULL) { - close_file(base_fsp, ERROR_CLOSE); + close_file(req, base_fsp, ERROR_CLOSE); base_fsp = NULL; } return status; @@ -2856,7 +2863,7 @@ NTSTATUS create_file(connection_struct *conn, uint32_t create_options, uint32_t file_attributes, uint32_t oplock_request, - SMB_BIG_UINT allocation_size, + uint64_t allocation_size, struct security_descriptor *sd, struct ea_list *ea_list, @@ -2894,7 +2901,7 @@ NTSTATUS create_file(connection_struct *conn, * This filename is relative to a directory fid. */ char *parent_fname = NULL; - files_struct *dir_fsp = file_fsp(root_dir_fid); + files_struct *dir_fsp = file_fsp(req, root_dir_fid); if (dir_fsp == NULL) { status = NT_STATUS_INVALID_HANDLE; @@ -2907,7 +2914,8 @@ NTSTATUS create_file(connection_struct *conn, * Check to see if this is a mac fork of some kind. */ - if (is_ntfs_stream_name(fname)) { + if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && + is_ntfs_stream_name(fname)) { status = NT_STATUS_OBJECT_PATH_NOT_FOUND; goto fail; } @@ -2994,7 +3002,7 @@ NTSTATUS create_file(connection_struct *conn, * also tries a QUERY_FILE_INFO on the file and then * close it */ - status = open_fake_file(conn, req->vuid, + status = open_fake_file(req, conn, req->vuid, fake_file_type, fname, access_mask, &fsp); if (!NT_STATUS_IS_OK(status)) { @@ -3086,7 +3094,7 @@ NTSTATUS create_file(connection_struct *conn, DEBUG(10, ("create_file: %s\n", nt_errstr(status))); if (fsp != NULL) { - close_file(fsp, ERROR_CLOSE); + close_file(req, fsp, ERROR_CLOSE); fsp = NULL; } return status; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1d3514429f..88e7b766be 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -545,7 +545,7 @@ static bool user_ok(const char *user, int snum) ret = True; if (lp_invalid_users(snum)) { - str_list_copy(talloc_tos(), &invalid, lp_invalid_users(snum)); + invalid = str_list_copy(talloc_tos(), lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { @@ -561,7 +561,7 @@ static bool user_ok(const char *user, int snum) TALLOC_FREE(invalid); if (ret && lp_valid_users(snum)) { - str_list_copy(talloc_tos(), &valid, lp_valid_users(snum)); + valid = str_list_copy(talloc_tos(), lp_valid_users(snum)); if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 4fdcdcc557..25a1fe2e63 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -32,18 +32,6 @@ #define MAX_PIPE_NAME_LEN 24 -/* PIPE/<name>/<pid>/<pnum> */ -#define PIPEDB_KEY_FORMAT "PIPE/%s/%u/%d" - -struct pipe_dbrec { - struct server_id pid; - int pnum; - uid_t uid; - - char name[MAX_PIPE_NAME_LEN]; - fstring user; -}; - /**************************************************************************** Reply to an open and X on a named pipe. This code is basically stolen from reply_open_and_X with some @@ -54,9 +42,10 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) { const char *fname = NULL; char *pipe_name = NULL; - smb_np_struct *p; + files_struct *fsp; int size=0,fmode=0,mtime=0,rmode=0; TALLOC_CTX *ctx = talloc_tos(); + NTSTATUS status; /* XXXX we need to handle passed times, sattr and flags */ srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &pipe_name, @@ -101,9 +90,9 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) /* can be opened and add it in after the open. */ DEBUG(3,("Known pipe %s opening.\n",fname)); - p = open_rpc_pipe_p(fname, conn, req->vuid); - if (!p) { - reply_doserror(req, ERRSRV, ERRnofids); + status = np_open(req, conn, fname, &fsp); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); return; } @@ -119,7 +108,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) rmode = 1; } - SSVAL(req->outbuf,smb_vwv2, p->pnum); + SSVAL(req->outbuf,smb_vwv2, fsp->fnum); SSVAL(req->outbuf,smb_vwv3,fmode); srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime); SIVAL(req->outbuf,smb_vwv6,size); @@ -136,27 +125,32 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) void reply_pipe_write(struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv0)); + files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); size_t numtowrite = SVAL(req->inbuf,smb_vwv1); - int nwritten; - char *data; + ssize_t nwritten; + uint8_t *data; - if (!p) { + if (!fsp_is_np(fsp)) { reply_doserror(req, ERRDOS, ERRbadfid); return; } - if (p->vuid != req->vuid) { + if (fsp->vuid != req->vuid) { reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } - data = smb_buf(req->inbuf) + 3; + data = (uint8_t *)smb_buf(req->inbuf) + 3; if (numtowrite == 0) { nwritten = 0; } else { - nwritten = write_to_pipe(p, data, numtowrite); + NTSTATUS status; + status = np_write(fsp, data, numtowrite, &nwritten); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } } if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { @@ -168,7 +162,8 @@ void reply_pipe_write(struct smb_request *req) SSVAL(req->outbuf,smb_vwv0,nwritten); - DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); + DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", fsp->fnum, + (int)nwritten)); return; } @@ -182,31 +177,33 @@ void reply_pipe_write(struct smb_request *req) void reply_pipe_write_and_X(struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv2)); + files_struct *fsp = file_fsp(req, SVAL(req->inbuf, smb_vwv2)); size_t numtowrite = SVAL(req->inbuf,smb_vwv10); - int nwritten = -1; + ssize_t nwritten; int smb_doff = SVAL(req->inbuf, smb_vwv11); bool pipe_start_message_raw = ((SVAL(req->inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) == (PIPE_START_MESSAGE|PIPE_RAW_MODE)); - char *data; + uint8_t *data; - if (!p) { + if (!fsp_is_np(fsp)) { reply_doserror(req, ERRDOS, ERRbadfid); return; } - if (p->vuid != req->vuid) { + if (fsp->vuid != req->vuid) { reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } - data = smb_base(req->inbuf) + smb_doff; + data = (uint8_t *)smb_base(req->inbuf) + smb_doff; if (numtowrite == 0) { nwritten = 0; } else { + NTSTATUS status; + if(pipe_start_message_raw) { /* * For the start of a message in named pipe byte mode, @@ -225,7 +222,11 @@ void reply_pipe_write_and_X(struct smb_request *req) data += 2; numtowrite -= 2; } - nwritten = write_to_pipe(p, data, numtowrite); + status = np_write(fsp, data, numtowrite, &nwritten); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } } if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { @@ -238,7 +239,8 @@ void reply_pipe_write_and_X(struct smb_request *req) nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten); SSVAL(req->outbuf,smb_vwv2,nwritten); - DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); + DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", fsp->fnum, + (int)nwritten)); chain_reply(req); } @@ -251,12 +253,13 @@ void reply_pipe_write_and_X(struct smb_request *req) void reply_pipe_read_and_X(struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv2)); + files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); int smb_maxcnt = SVAL(req->inbuf,smb_vwv5); int smb_mincnt = SVAL(req->inbuf,smb_vwv6); - int nread = -1; - char *data; + ssize_t nread; + uint8_t *data; bool unused; + NTSTATUS status; /* we don't use the offset given to use for pipe reads. This is deliberate, instead we always return the next lump of @@ -265,18 +268,23 @@ void reply_pipe_read_and_X(struct smb_request *req) uint32 smb_offs = IVAL(req->inbuf,smb_vwv3); #endif - if (!p) { + if (!fsp_is_np(fsp)) { reply_doserror(req, ERRDOS, ERRbadfid); return; } + if (fsp->vuid != req->vuid) { + reply_nterror(req, NT_STATUS_INVALID_HANDLE); + return; + } + reply_outbuf(req, 12, smb_maxcnt); - data = smb_buf(req->outbuf); + data = (uint8_t *)smb_buf(req->outbuf); - nread = read_from_pipe(p, data, smb_maxcnt, &unused); + status = np_read(fsp, data, smb_maxcnt, &nread, &unused); - if (nread < 0) { + if (!NT_STATUS_IS_OK(status)) { reply_doserror(req, ERRDOS, ERRnoaccess); return; } @@ -288,33 +296,7 @@ void reply_pipe_read_and_X(struct smb_request *req) SSVAL(smb_buf(req->outbuf),-2,nread); DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n", - p->pnum, smb_mincnt, smb_maxcnt, nread)); + fsp->fnum, smb_mincnt, smb_maxcnt, (int)nread)); chain_reply(req); } - -/**************************************************************************** - Reply to a close. -****************************************************************************/ - -void reply_pipe_close(connection_struct *conn, struct smb_request *req) -{ - smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv0)); - - if (!p) { - reply_doserror(req, ERRDOS, ERRbadfid); - return; - } - - DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); - - if (!close_rpc_pipe_hnd(p)) { - reply_doserror(req, ERRDOS, ERRbadfid); - return; - } - - /* TODO: REMOVE PIPE FROM DB */ - - reply_outbuf(req, 0, 0); - return; -} diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 7479aea076..848d3e4a6d 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -890,13 +890,12 @@ static bool nt4_compatible_acls(void) not get. Deny entries are implicit on get with ace->perms = 0. ****************************************************************************/ -static SEC_ACCESS map_canon_ace_perms(int snum, +static uint32_t map_canon_ace_perms(int snum, enum security_ace_type *pacl_type, mode_t perms, bool directory_ace) { - SEC_ACCESS sa; - uint32 nt_mask = 0; + uint32_t nt_mask = 0; *pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED; @@ -935,8 +934,7 @@ static SEC_ACCESS map_canon_ace_perms(int snum, DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n", (unsigned int)perms, (unsigned int)nt_mask )); - init_sec_access(&sa,nt_mask); - return sa; + return nt_mask; } /**************************************************************************** @@ -988,7 +986,7 @@ static mode_t map_nt_perms( uint32 *mask, int type) Unpack a SEC_DESC into a UNIX owner and group. ****************************************************************************/ -NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd) +NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, const SEC_DESC *psd) { DOM_SID owner_sid; DOM_SID grp_sid; @@ -1329,11 +1327,13 @@ static void check_owning_objs(canon_ace *ace, DOM_SID *pfile_owner_sid, DOM_SID Unpack a SEC_DESC into two canonical ace lists. ****************************************************************************/ -static bool create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst, - DOM_SID *pfile_owner_sid, - DOM_SID *pfile_grp_sid, - canon_ace **ppfile_ace, canon_ace **ppdir_ace, - SEC_ACL *dacl) +static bool create_canon_ace_lists(files_struct *fsp, + SMB_STRUCT_STAT *pst, + DOM_SID *pfile_owner_sid, + DOM_SID *pfile_grp_sid, + canon_ace **ppfile_ace, + canon_ace **ppdir_ace, + const SEC_ACL *dacl) { bool all_aces_are_inherit_only = (fsp->is_directory ? True : False); canon_ace *file_ace = NULL; @@ -2016,12 +2016,14 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode) succeeding. ****************************************************************************/ -static bool unpack_canon_ace(files_struct *fsp, - SMB_STRUCT_STAT *pst, - DOM_SID *pfile_owner_sid, - DOM_SID *pfile_grp_sid, - canon_ace **ppfile_ace, canon_ace **ppdir_ace, - uint32 security_info_sent, SEC_DESC *psd) +static bool unpack_canon_ace(files_struct *fsp, + SMB_STRUCT_STAT *pst, + DOM_SID *pfile_owner_sid, + DOM_SID *pfile_grp_sid, + canon_ace **ppfile_ace, + canon_ace **ppdir_ace, + uint32 security_info_sent, + const SEC_DESC *psd) { canon_ace *file_ace = NULL; canon_ace *dir_ace = NULL; @@ -2958,9 +2960,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, */ for (ace = file_ace; ace != NULL; ace = ace->next) { - SEC_ACCESS acc; - - acc = map_canon_ace_perms(SNUM(conn), + uint32_t acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, ace->perms, S_ISDIR(sbuf->st_mode)); @@ -2975,19 +2975,14 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, /* The User must have access to a profile share - even * if we can't map the SID. */ if (lp_profile_acls(SNUM(conn))) { - SEC_ACCESS acc; - - init_sec_access(&acc,FILE_GENERIC_ALL); init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, - acc, 0); + FILE_GENERIC_ALL, 0); } for (ace = dir_ace; ace != NULL; ace = ace->next) { - SEC_ACCESS acc; - - acc = map_canon_ace_perms(SNUM(conn), + uint32_t acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, ace->perms, S_ISDIR(sbuf->st_mode)); @@ -3005,10 +3000,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, /* The User must have access to a profile share - even * if we can't map the SID. */ if (lp_profile_acls(SNUM(conn))) { - SEC_ACCESS acc; - - init_sec_access(&acc,FILE_GENERIC_ALL); - init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, + init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_ALL, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| SEC_ACE_FLAG_INHERIT_ONLY|0); } @@ -3199,7 +3191,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) return -1; } - if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,&st,&fsp))) { + if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname, &st, &fsp))) { return -1; } @@ -3214,7 +3206,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) ret = SMB_VFS_FCHOWN(fsp, uid, (gid_t)-1); unbecome_root(); - close_file_fchmod(fsp); + close_file_fchmod(NULL, fsp); return ret; } @@ -3223,26 +3215,26 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) Take care of parent ACL inheritance. ****************************************************************************/ -static NTSTATUS append_parent_acl(files_struct *fsp, - SMB_STRUCT_STAT *psbuf, - SEC_DESC *psd, +NTSTATUS append_parent_acl(files_struct *fsp, + const SEC_DESC *pcsd, SEC_DESC **pp_new_sd) { SEC_DESC *parent_sd = NULL; files_struct *parent_fsp = NULL; - TALLOC_CTX *mem_ctx = talloc_parent(psd); + TALLOC_CTX *mem_ctx = talloc_tos(); char *parent_name = NULL; SEC_ACE *new_ace = NULL; - unsigned int num_aces = psd->dacl->num_aces; + unsigned int num_aces = pcsd->dacl->num_aces; SMB_STRUCT_STAT sbuf; NTSTATUS status; int info; unsigned int i, j; - bool is_dacl_protected = (psd->type & SE_DESC_DACL_PROTECTED); + SEC_DESC *psd = dup_sec_desc(talloc_tos(), pcsd); + bool is_dacl_protected = (pcsd->type & SE_DESC_DACL_PROTECTED); ZERO_STRUCT(sbuf); - if (mem_ctx == NULL) { + if (psd == NULL) { return NT_STATUS_NO_MEMORY; } @@ -3272,7 +3264,7 @@ static NTSTATUS append_parent_acl(files_struct *fsp, status = SMB_VFS_GET_NT_ACL(parent_fsp->conn, parent_fsp->fsp_name, DACL_SECURITY_INFORMATION, &parent_sd ); - close_file(parent_fsp, NORMAL_CLOSE); + close_file(NULL, parent_fsp, NORMAL_CLOSE); if (!NT_STATUS_IS_OK(status)) { return status; @@ -3398,11 +3390,6 @@ static NTSTATUS append_parent_acl(files_struct *fsp, parent_name)); } - /* This sucks. psd should be const and we should - * be doing a deep-copy here. We're getting away - * with is as we know parent_sd is talloced off - * talloc_tos() as well as psd. JRA. */ - psd->dacl->aces = new_ace; psd->dacl->num_aces = i; psd->type &= ~(SE_DESC_DACL_AUTO_INHERITED| @@ -3418,7 +3405,7 @@ static NTSTATUS append_parent_acl(files_struct *fsp, This should be the only external function needed for the UNIX style set ACL. ****************************************************************************/ -NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) +NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC *psd) { connection_struct *conn = fsp->conn; uid_t user = (uid_t)-1; @@ -3523,16 +3510,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); + /* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx + * for details. JRA. + */ + if ((security_info_sent & DACL_SECURITY_INFORMATION) && psd->dacl != NULL && (psd->type & (SE_DESC_DACL_AUTO_INHERITED| SE_DESC_DACL_AUTO_INHERIT_REQ))== (SE_DESC_DACL_AUTO_INHERITED| SE_DESC_DACL_AUTO_INHERIT_REQ) ) { - status = append_parent_acl(fsp, &sbuf, psd, &psd); + SEC_DESC *new_sd = NULL; + status = append_parent_acl(fsp, psd, &new_sd); if (!NT_STATUS_IS_OK(status)) { return status; } + psd = new_sd; } acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid, diff --git a/source3/smbd/process.c b/source3/smbd/process.c index b2d19e11e3..a8b93d8e1c 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -105,7 +105,11 @@ static bool valid_smb_header(const uint8_t *inbuf) if (is_encrypted_packet(inbuf)) { return true; } - return (strncmp(smb_base(inbuf),"\377SMB",4) == 0); + /* + * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0) + * but it just looks weird to call strncmp for this one. + */ + return (IVAL(smb_base(inbuf), 0) == 0x424D53FF); } /* Socket functions for smbd packet processing. */ @@ -376,6 +380,7 @@ void init_smb_request(struct smb_request *req, req->unread_bytes = unread_bytes; req->encrypted = encrypted; req->conn = conn_find(req->tid); + req->chain_fsp = NULL; /* Ensure we have at least wct words and 2 bytes of bcc. */ if (smb_size + req->wct*2 > req_size) { @@ -706,7 +711,7 @@ The timeout is in milliseconds ****************************************************************************/ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer, - size_t *buffer_len, int timeout, + size_t *buffer_len, size_t *p_unread, bool *p_encrypted) { fd_set r_fds, w_fds; @@ -720,13 +725,8 @@ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer, again: - if (timeout >= 0) { - to.tv_sec = timeout / 1000; - to.tv_usec = (timeout % 1000) * 1000; - } else { - to.tv_sec = SMBD_SELECT_TIMEOUT; - to.tv_usec = 0; - } + to.tv_sec = SMBD_SELECT_TIMEOUT; + to.tv_usec = 0; /* * Note that this call must be before processing any SMB @@ -747,7 +747,7 @@ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer, pop_message = True; } else { struct timeval tv; - SMB_BIG_INT tdif; + int64_t tdif; GetTimeOfDay(&tv); tdif = usec_time_diff(&msg->end_time, &tv); @@ -869,7 +869,7 @@ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer, /* Did we timeout ? */ if (selrtn == 0) { - return NT_STATUS_IO_TIMEOUT; + goto again; } /* @@ -978,7 +978,7 @@ force write permissions on print services. */ static const struct smb_message_struct { const char *name; - void (*fn_new)(struct smb_request *req); + void (*fn)(struct smb_request *req); int flags; } smb_messages[256] = { @@ -1354,7 +1354,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in exit_server_cleanly("Non-SMB packet"); } - if (smb_messages[type].fn_new == NULL) { + if (smb_messages[type].fn == NULL) { DEBUG(0,("Unknown message type %d!\n",type)); smb_dump("Unknown", 1, (char *)req->inbuf, size); reply_unknown_new(req, type); @@ -1476,7 +1476,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in return conn; } - smb_messages[type].fn_new(req); + smb_messages[type].fn(req); return req->conn; } @@ -1491,8 +1491,6 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc struct smb_request *req; chain_size = 0; - file_chain_reset(); - reset_chain_p(); if (!(req = talloc(talloc_tos(), struct smb_request))) { smb_panic("could not allocate smb_request"); @@ -1540,25 +1538,6 @@ static void process_smb(char *inbuf, size_t nread, size_t unread_bytes, bool enc DO_PROFILE_INC(smb_count); - if (trans_num == 0) { - char addr[INET6_ADDRSTRLEN]; - - /* on the first packet, check the global hosts allow/ hosts - deny parameters before doing any parsing of the packet - passed to us by the client. This prevents attacks on our - parsing code from hosts not in the hosts allow list */ - - if (!check_access(smbd_server_fd(), lp_hostsallow(-1), - lp_hostsdeny(-1))) { - /* send a negative session response "not listening on calling name" */ - static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; - DEBUG( 1, ( "Connection denied from %s\n", - client_addr(get_client_fd(),addr,sizeof(addr)) ) ); - (void)srv_send_smb(smbd_server_fd(),(char *)buf,false); - exit_server_cleanly("connection denied"); - } - } - DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, smb_len(inbuf) ) ); DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num, @@ -1738,6 +1717,7 @@ void chain_reply(struct smb_request *req) smb_panic("could not allocate smb_request"); } init_smb_request(req2, (uint8 *)inbuf2,0, req->encrypted); + req2->chain_fsp = req->chain_fsp; /* process the request */ switch_message(smb_com2, req2, new_size); @@ -1837,23 +1817,6 @@ void chain_reply(struct smb_request *req) } /**************************************************************************** - Setup the needed select timeout in milliseconds. -****************************************************************************/ - -static int setup_select_timeout(void) -{ - int select_timeout; - - select_timeout = SMBD_SELECT_TIMEOUT*1000; - - if (print_notify_messages_pending()) { - select_timeout = MIN(select_timeout, 1000); - } - - return select_timeout; -} - -/**************************************************************************** Check if services need reloading. ****************************************************************************/ @@ -1907,113 +1870,40 @@ void check_reload(time_t t) } /**************************************************************************** - Process any timeout housekeeping. Return False if the caller should exit. + Process commands from the client ****************************************************************************/ -static void timeout_processing(int *select_timeout, - time_t *last_timeout_processing_time) +void smbd_process(void) { - time_t t; - - *last_timeout_processing_time = t = time(NULL); - - /* become root again if waiting */ - change_to_root_user(); - - /* check if we need to reload services */ - check_reload(t); - - if(global_machine_password_needs_changing && - /* for ADS we need to do a regular ADS password change, not a domain - password change */ - lp_security() == SEC_DOMAIN) { - - unsigned char trust_passwd_hash[16]; - time_t lct; - void *lock; - - /* - * We're in domain level security, and the code that - * read the machine password flagged that the machine - * password needs changing. - */ - - /* - * First, open the machine password file with an exclusive lock. - */ - - lock = secrets_get_trust_account_lock(NULL, lp_workgroup()); + unsigned int num_smbs = 0; + size_t unread_bytes = 0; - if (lock == NULL) { - DEBUG(0,("process: unable to lock the machine account password for \ -machine %s in domain %s.\n", global_myname(), lp_workgroup() )); - return; - } + char addr[INET6_ADDRSTRLEN]; - if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) { - DEBUG(0,("process: unable to read the machine account password for \ -machine %s in domain %s.\n", global_myname(), lp_workgroup())); - TALLOC_FREE(lock); - return; - } + /* + * Before the first packet, check the global hosts allow/ hosts deny + * parameters before doing any parsing of packets passed to us by the + * client. This prevents attacks on our parsing code from hosts not in + * the hosts allow list. + */ + if (!check_access(smbd_server_fd(), lp_hostsallow(-1), + lp_hostsdeny(-1))) { /* - * Make sure someone else hasn't already done this. + * send a negative session response "not listening on calling + * name" */ - - if(t < lct + lp_machine_password_timeout()) { - global_machine_password_needs_changing = False; - TALLOC_FREE(lock); - return; - } - - /* always just contact the PDC here */ - - change_trust_account_password( lp_workgroup(), NULL); - global_machine_password_needs_changing = False; - TALLOC_FREE(lock); + unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; + DEBUG( 1, ("Connection denied from %s\n", + client_addr(get_client_fd(),addr,sizeof(addr)) ) ); + (void)srv_send_smb(smbd_server_fd(),(char *)buf,false); + exit_server_cleanly("connection denied"); } - /* update printer queue caches if necessary */ - - update_monitored_printq_cache(); - - /* - * Now we are root, check if the log files need pruning. - * Force a log file check. - */ - force_check_log_size(); - check_log_size(); - - /* Send any queued printer notify message to interested smbd's. */ - - print_notify_send_messages(smbd_messaging_context(), 0); - - /* - * Modify the select timeout depending upon - * what we have remaining in our queues. - */ - - *select_timeout = setup_select_timeout(); - - return; -} - -/**************************************************************************** - Process commands from the client -****************************************************************************/ - -void smbd_process(void) -{ - time_t last_timeout_processing_time = time(NULL); - unsigned int num_smbs = 0; - size_t unread_bytes = 0; - max_recv = MIN(lp_maxxmit(),BUFFER_SIZE); while (True) { - int select_timeout = setup_select_timeout(); - int num_echos; + NTSTATUS status; char *inbuf = NULL; size_t inbuf_len = 0; bool encrypted = false; @@ -2021,82 +1911,24 @@ void smbd_process(void) errno = 0; - /* Did someone ask for immediate checks on things like blocking locks ? */ - if (select_timeout == 0) { - timeout_processing(&select_timeout, - &last_timeout_processing_time); - num_smbs = 0; /* Reset smb counter. */ - } - run_events(smbd_event_context(), 0, NULL, NULL); - while (True) { - NTSTATUS status; - - status = receive_message_or_smb( - talloc_tos(), &inbuf, &inbuf_len, - select_timeout, &unread_bytes, &encrypted); - - if (NT_STATUS_IS_OK(status)) { - break; - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - timeout_processing( - &select_timeout, - &last_timeout_processing_time); - continue; - } + status = receive_message_or_smb( + talloc_tos(), &inbuf, &inbuf_len, + &unread_bytes, &encrypted); + if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("receive_message_or_smb failed: %s, " "exiting\n", nt_errstr(status))); return; - - num_smbs = 0; /* Reset smb counter. */ } - - /* - * Ensure we do timeout processing if the SMB we just got was - * only an echo request. This allows us to set the select - * timeout in 'receive_message_or_smb()' to any value we like - * without worrying that the client will send echo requests - * faster than the select timeout, thus starving out the - * essential processing (change notify, blocking locks) that - * the timeout code does. JRA. - */ - num_echos = smb_echo_count; - process_smb(inbuf, inbuf_len, unread_bytes, encrypted); TALLOC_FREE(inbuf); - if (smb_echo_count != num_echos) { - timeout_processing(&select_timeout, - &last_timeout_processing_time); - num_smbs = 0; /* Reset smb counter. */ - } - num_smbs++; - /* - * If we are getting smb requests in a constant stream - * with no echos, make sure we attempt timeout processing - * every select_timeout milliseconds - but only check for this - * every 200 smb requests. - */ - - if ((num_smbs % 200) == 0) { - time_t new_check_time = time(NULL); - if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) { - timeout_processing( - &select_timeout, - &last_timeout_processing_time); - num_smbs = 0; /* Reset smb counter. */ - last_timeout_processing_time = new_check_time; /* Reset time. */ - } - } - /* The timeout_processing function isn't run nearly often enough to implement 'max log size' without overrunning the size of the file by many megabytes. diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index f47e89bd22..3aa4652508 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -45,7 +45,7 @@ * Declare here, define at end: reduces likely "include" interaction problems. * David Lee <T.D.Lee@durham.ac.uk> */ -bool disk_quotas_vxfs(const char *name, char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize); +bool disk_quotas_vxfs(const char *name, char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize); #endif /* VXFS_QUOTA */ @@ -63,13 +63,13 @@ bool disk_quotas_vxfs(const char *name, char *path, SMB_BIG_UINT *bsize, SMB_BIG #include "samba_linux_quota.h" typedef struct _LINUX_SMB_DISK_QUOTA { - SMB_BIG_UINT bsize; - SMB_BIG_UINT hardlimit; /* In bsize units. */ - SMB_BIG_UINT softlimit; /* In bsize units. */ - SMB_BIG_UINT curblocks; /* In bsize units. */ - SMB_BIG_UINT ihardlimit; /* inode hard limit. */ - SMB_BIG_UINT isoftlimit; /* inode soft limit. */ - SMB_BIG_UINT curinodes; /* Current used inodes. */ + uint64_t bsize; + uint64_t hardlimit; /* In bsize units. */ + uint64_t softlimit; /* In bsize units. */ + uint64_t curblocks; /* In bsize units. */ + uint64_t ihardlimit; /* inode hard limit. */ + uint64_t isoftlimit; /* inode soft limit. */ + uint64_t curinodes; /* Current used inodes. */ } LINUX_SMB_DISK_QUOTA; @@ -95,13 +95,13 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, gid_t egrp_id, LI if (ret) return ret; - dp->bsize = (SMB_BIG_UINT)512; - dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit; - dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit; - dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit; - dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit; - dp->curinodes = (SMB_BIG_UINT)D.d_icount; - dp->curblocks = (SMB_BIG_UINT)D.d_bcount; + dp->bsize = (uint64_t)512; + dp->softlimit = (uint64_t)D.d_blk_softlimit; + dp->hardlimit = (uint64_t)D.d_blk_hardlimit; + dp->ihardlimit = (uint64_t)D.d_ino_hardlimit; + dp->isoftlimit = (uint64_t)D.d_ino_softlimit; + dp->curinodes = (uint64_t)D.d_icount; + dp->curblocks = (uint64_t)D.d_bcount; return ret; } @@ -134,13 +134,13 @@ static int get_smb_linux_v1_quota(char *path, uid_t euser_id, gid_t egrp_id, LIN if (ret && errno != EDQUOT) return ret; - dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; - dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; - dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; - dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; - dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; - dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; - dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; + dp->bsize = (uint64_t)QUOTABLOCK_SIZE; + dp->softlimit = (uint64_t)D.dqb_bsoftlimit; + dp->hardlimit = (uint64_t)D.dqb_bhardlimit; + dp->ihardlimit = (uint64_t)D.dqb_ihardlimit; + dp->isoftlimit = (uint64_t)D.dqb_isoftlimit; + dp->curinodes = (uint64_t)D.dqb_curinodes; + dp->curblocks = (uint64_t)D.dqb_curblocks; return ret; } @@ -160,13 +160,13 @@ static int get_smb_linux_v2_quota(char *path, uid_t euser_id, gid_t egrp_id, LIN if (ret && errno != EDQUOT) return ret; - dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; - dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; - dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; - dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; - dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; - dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; - dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize; + dp->bsize = (uint64_t)QUOTABLOCK_SIZE; + dp->softlimit = (uint64_t)D.dqb_bsoftlimit; + dp->hardlimit = (uint64_t)D.dqb_bhardlimit; + dp->ihardlimit = (uint64_t)D.dqb_ihardlimit; + dp->isoftlimit = (uint64_t)D.dqb_isoftlimit; + dp->curinodes = (uint64_t)D.dqb_curinodes; + dp->curblocks = ((uint64_t)D.dqb_curspace) / dp->bsize; return ret; } @@ -190,13 +190,13 @@ static int get_smb_linux_gen_quota(char *path, uid_t euser_id, gid_t egrp_id, LI if (ret && errno != EDQUOT) return ret; - dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; - dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; - dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; - dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; - dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; - dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; - dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize; + dp->bsize = (uint64_t)QUOTABLOCK_SIZE; + dp->softlimit = (uint64_t)D.dqb_bsoftlimit; + dp->hardlimit = (uint64_t)D.dqb_bhardlimit; + dp->ihardlimit = (uint64_t)D.dqb_ihardlimit; + dp->isoftlimit = (uint64_t)D.dqb_isoftlimit; + dp->curinodes = (uint64_t)D.dqb_curinodes; + dp->curblocks = ((uint64_t)D.dqb_curspace) / dp->bsize; return ret; } @@ -205,7 +205,7 @@ static int get_smb_linux_gen_quota(char *path, uid_t euser_id, gid_t egrp_id, LI Try to get the disk space from disk quotas (LINUX version). ****************************************************************************/ -bool disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { int r; SMB_STRUCT_STAT S; @@ -306,7 +306,7 @@ bool disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB try to get the disk space from disk quotas (CRAY VERSION) ****************************************************************************/ -bool disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { struct mntent *mnt; FILE *fd; @@ -454,7 +454,7 @@ static int my_xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr) } /* Restricted to SUNOS5 for the moment, I haven`t access to others to test. */ -static bool nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +static bool nfs_quotas(char *nfspath, uid_t euser_id, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uid_t uid = euser_id; struct dqblk D; @@ -468,7 +468,7 @@ static bool nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B enum clnt_stat clnt_stat; bool ret = True; - *bsize = *dfree = *dsize = (SMB_BIG_UINT)0; + *bsize = *dfree = *dsize = (uint64_t)0; len=strcspn(mnttype, ":"); pathname=strstr(mnttype, ":"); @@ -544,7 +544,7 @@ static bool nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize; *dsize = D.dqb_bsoftlimit; - if (D.dqb_curblocks == D.dqb_curblocks == 1) + if (D.dqb_curblocks == 1) *bsize = 512; if (D.dqb_curblocks > D.dqb_bsoftlimit) { @@ -575,9 +575,9 @@ Quota code by Peter Urbanec (amiga@cse.unsw.edu.au). ****************************************************************************/ bool disk_quotas(const char *path, - SMB_BIG_UINT *bsize, - SMB_BIG_UINT *dfree, - SMB_BIG_UINT *dsize) + uint64_t *bsize, + uint64_t *dfree, + uint64_t *dsize) { uid_t euser_id; int ret; @@ -750,7 +750,7 @@ bool disk_quotas(const char *path, try to get the disk space from disk quotas - OSF1 version ****************************************************************************/ -bool disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { int r, save_errno; struct dqblk D; @@ -816,7 +816,7 @@ try to get the disk space from disk quotas (IRIX 6.2 version) #include <sys/quota.h> #include <mntent.h> -bool disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uid_t euser_id; int r; @@ -1009,7 +1009,7 @@ static int my_xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr) } /* Works on FreeBSD, too. :-) */ -static bool nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +static bool nfs_quotas(char *nfspath, uid_t euser_id, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uid_t uid = euser_id; struct dqblk D; @@ -1023,7 +1023,7 @@ static bool nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B enum clnt_stat clnt_stat; bool ret = True; - *bsize = *dfree = *dsize = (SMB_BIG_UINT)0; + *bsize = *dfree = *dsize = (uint64_t)0; len=strcspn(mnttype, ":"); pathname=strstr(mnttype, ":"); @@ -1104,7 +1104,7 @@ static bool nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize; *dsize = D.dqb_bsoftlimit; - if (D.dqb_curblocks == D.dqb_curblocks == 1) + if (D.dqb_curblocks == 1) *bsize = DEV_BSIZE; if (D.dqb_curblocks > D.dqb_bsoftlimit) { @@ -1134,7 +1134,7 @@ static bool nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B try to get the disk space from disk quotas - default version ****************************************************************************/ -bool disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { int r; struct dqblk D; @@ -1353,7 +1353,7 @@ Hints for porting: #include <sys/fs/vx_aioctl.h> #include <sys/fs/vx_ioctl.h> -bool disk_quotas_vxfs(const char *name, char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +bool disk_quotas_vxfs(const char *name, char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uid_t user_id, euser_id; int ret; @@ -1437,14 +1437,14 @@ bool disk_quotas_vxfs(const char *name, char *path, SMB_BIG_UINT *bsize, SMB_BIG #else /* WITH_QUOTAS */ -bool disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) +bool disk_quotas(const char *path,uint64_t *bsize,uint64_t *dfree,uint64_t *dsize) { (*bsize) = 512; /* This value should be ignored */ /* And just to be sure we set some values that hopefully */ /* will be larger that any possible real-world value */ - (*dfree) = (SMB_BIG_UINT)-1; - (*dsize) = (SMB_BIG_UINT)-1; + (*dfree) = (uint64_t)-1; + (*dsize) = (uint64_t)-1; /* As we have select not to use quotas, allways fail */ return false; @@ -1455,7 +1455,7 @@ bool disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BI /* wrapper to the new sys_quota interface this file should be removed later */ -bool disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) +bool disk_quotas(const char *path,uint64_t *bsize,uint64_t *dfree,uint64_t *dsize) { int r; SMB_DISK_QUOTA D; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 6933533672..25480c6e3b 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -29,7 +29,6 @@ /* look in server.c for some explanation of these variables */ extern enum protocol_types Protocol; extern int max_recv; -unsigned int smb_echo_count = 0; extern uint32 global_client_caps; extern bool global_encrypted_passwords_negotiated; @@ -340,8 +339,7 @@ bool check_fsp_open(connection_struct *conn, struct smb_request *req, } /**************************************************************************** - Check if we have a correct fsp pointing to a file. Replacement for the - CHECK_FSP macro. + Check if we have a correct fsp pointing to a file. ****************************************************************************/ bool check_fsp(connection_struct *conn, struct smb_request *req, @@ -426,22 +424,22 @@ void reply_special(char *inbuf) * header. */ char outbuf[smb_size]; - + static bool already_got_session = False; *name1 = *name2 = 0; - + memset(outbuf, '\0', sizeof(outbuf)); smb_setlen(outbuf,0); - + switch (msg_type) { case 0x81: /* session request */ - + if (already_got_session) { exit_server_cleanly("multiple session request not permitted"); } - + SCVAL(outbuf,0,0x82); SCVAL(outbuf,3,0); if (name_len(inbuf+4) > 50 || @@ -480,24 +478,24 @@ void reply_special(char *inbuf) already_got_session = True; break; - + case 0x89: /* session keepalive request (some old clients produce this?) */ SCVAL(outbuf,0,SMBkeepalive); SCVAL(outbuf,3,0); break; - + case 0x82: /* positive session response */ case 0x83: /* negative session response */ case 0x84: /* retarget session response */ DEBUG(0,("Unexpected session response\n")); break; - + case SMBkeepalive: /* session keepalive */ default: return; } - + DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n", msg_type, msg_flags)); @@ -749,7 +747,12 @@ void reply_tcon_and_X(struct smb_request *req) SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS| (lp_csc_policy(SNUM(conn)) << 2)); - init_dfsroot(conn, req->inbuf, req->outbuf); + if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) { + DEBUG(2,("Serving %s as a Dfs root\n", + lp_servicename(SNUM(conn)) )); + SSVAL(req->outbuf, smb_vwv2, + SMB_SHARE_IN_DFS | SVAL(req->outbuf, smb_vwv2)); + } } @@ -827,8 +830,8 @@ void reply_ioctl(struct smb_request *req) switch (ioctl_code) { case IOCTL_QUERY_JOB_INFO: { - files_struct *fsp = file_fsp(SVAL(req->inbuf, - smb_vwv0)); + files_struct *fsp = file_fsp( + req, SVAL(req->inbuf, smb_vwv0)); if (!fsp) { reply_doserror(req, ERRDOS, ERRbadfid); END_PROFILE(SMBioctl); @@ -1059,7 +1062,7 @@ void reply_getatr(struct smb_request *req) SSVAL(req->outbuf, smb_flg2, SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME); } - + DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) ); END_PROFILE(SMBgetatr); @@ -1166,9 +1169,9 @@ void reply_setatr(struct smb_request *req) } reply_outbuf(req, 0, 0); - + DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) ); - + END_PROFILE(SMBsetatr); return; } @@ -1180,17 +1183,17 @@ void reply_setatr(struct smb_request *req) void reply_dskattr(struct smb_request *req) { connection_struct *conn = req->conn; - SMB_BIG_UINT dfree,dsize,bsize; + uint64_t dfree,dsize,bsize; START_PROFILE(SMBdskattr); - if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { + if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) { reply_unixerror(req, ERRHRD, ERRgeneral); END_PROFILE(SMBdskattr); return; } reply_outbuf(req, 5, 0); - + if (Protocol <= PROTOCOL_LANMAN2) { double total_space, free_space; /* we need to scale this to a number that DOS6 can handle. We @@ -1202,9 +1205,9 @@ void reply_dskattr(struct smb_request *req) total_space = dsize * (double)bsize; free_space = dfree * (double)bsize; - dsize = (SMB_BIG_UINT)((total_space+63*512) / (64*512)); - dfree = (SMB_BIG_UINT)((free_space+63*512) / (64*512)); - + dsize = (uint64_t)((total_space+63*512) / (64*512)); + dfree = (uint64_t)((free_space+63*512) / (64*512)); + if (dsize > 0xFFFF) dsize = 0xFFFF; if (dfree > 0xFFFF) dfree = 0xFFFF; @@ -1689,7 +1692,7 @@ void reply_open(struct smb_request *req) if (fattr & aDIR) { DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name)); - close_file(fsp,ERROR_CLOSE); + close_file(req, fsp, ERROR_CLOSE); reply_doserror(req, ERRDOS,ERRnoaccess); END_PROFILE(SMBopen); return; @@ -1710,7 +1713,7 @@ void reply_open(struct smb_request *req) SCVAL(req->outbuf,smb_flg, CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); } - + if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { SCVAL(req->outbuf,smb_flg, CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); @@ -1746,7 +1749,7 @@ void reply_open_and_X(struct smb_request *req) int smb_action = 0; files_struct *fsp; NTSTATUS status; - SMB_BIG_UINT allocation_size; + uint64_t allocation_size; ssize_t retval = -1; uint32 access_mask; uint32 share_mode; @@ -1769,7 +1772,7 @@ void reply_open_and_X(struct smb_request *req) core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); oplock_request = ex_oplock_request | core_oplock_request; smb_ofun = SVAL(req->inbuf,smb_vwv8); - allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv9); + allocation_size = (uint64_t)IVAL(req->inbuf,smb_vwv9); /* If it's an IPC, pass off the pipe handler. */ if (IS_IPC(conn)) { @@ -1832,14 +1835,14 @@ void reply_open_and_X(struct smb_request *req) if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) { fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { - close_file(fsp,ERROR_CLOSE); + close_file(req, fsp, ERROR_CLOSE); reply_nterror(req, NT_STATUS_DISK_FULL); END_PROFILE(SMBopenX); return; } retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size); if (retval < 0) { - close_file(fsp,ERROR_CLOSE); + close_file(req, fsp, ERROR_CLOSE); reply_nterror(req, NT_STATUS_DISK_FULL); END_PROFILE(SMBopenX); return; @@ -1850,7 +1853,7 @@ void reply_open_and_X(struct smb_request *req) fattr = dos_mode(conn,fsp->fsp_name,&sbuf); mtime = sbuf.st_mtime; if (fattr & aDIR) { - close_file(fsp,ERROR_CLOSE); + close_file(req, fsp, ERROR_CLOSE); reply_doserror(req, ERRDOS, ERRnoaccess); END_PROFILE(SMBopenX); return; @@ -2198,7 +2201,7 @@ void reply_ctemp(struct smb_request *req) SCVAL(req->outbuf, smb_flg, CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); } - + if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { SCVAL(req->outbuf, smb_flg, CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); @@ -2365,11 +2368,11 @@ static NTSTATUS do_unlink(connection_struct *conn, /* The set is across all open files on this dev/inode pair. */ if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) { - close_file(fsp, NORMAL_CLOSE); + close_file(req, fsp, NORMAL_CLOSE); return NT_STATUS_ACCESS_DENIED; } - return close_file(fsp,NORMAL_CLOSE); + return close_file(req, fsp, NORMAL_CLOSE); } /**************************************************************************** @@ -2810,7 +2813,7 @@ void reply_readbraw(struct smb_request *req) * return a zero length response here. */ - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); /* * We have to do a check_fsp by hand here, as @@ -2889,8 +2892,8 @@ void reply_readbraw(struct smb_request *req) maxcount = MIN(65535,maxcount); if (is_locked(fsp,(uint32)req->smbpid, - (SMB_BIG_UINT)maxcount, - (SMB_BIG_UINT)startpos, + (uint64_t)maxcount, + (uint64_t)startpos, READ_LOCK)) { reply_readbraw_error(); END_PROFILE(SMBreadbraw); @@ -2911,14 +2914,14 @@ void reply_readbraw(struct smb_request *req) if (nread < mincount) nread = 0; #endif - + DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu " "min=%lu nread=%lu\n", fsp->fnum, (double)startpos, (unsigned long)maxcount, (unsigned long)mincount, (unsigned long)nread ) ); - + send_file_readbraw(conn, fsp, startpos, nread, mincount); DEBUG(5,("reply_readbraw finished\n")); @@ -2952,7 +2955,7 @@ void reply_lockread(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBlockread); @@ -2975,7 +2978,7 @@ void reply_lockread(struct smb_request *req) reply_outbuf(req, 5, numtoread + 3); data = smb_buf(req->outbuf) + 3; - + /* * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+ * protocol request that predates the read/write lock concept. @@ -2983,12 +2986,12 @@ void reply_lockread(struct smb_request *req) * for a write lock. JRA. * Note that the requested lock size is unaffected by max_recv. */ - + br_lck = do_lock(smbd_messaging_context(), fsp, req->smbpid, - (SMB_BIG_UINT)numtoread, - (SMB_BIG_UINT)startpos, + (uint64_t)numtoread, + (uint64_t)startpos, WRITE_LOCK, WINDOWS_LOCK, False, /* Non-blocking lock. */ @@ -3019,7 +3022,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", END_PROFILE(SMBlockread); return; } - + srv_set_message((char *)req->outbuf, 5, nread+3, False); SSVAL(req->outbuf,smb_vwv0,nread); @@ -3027,7 +3030,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", p = smb_buf(req->outbuf); SCVAL(p,0,0); /* pad byte. */ SSVAL(p,1,nread); - + DEBUG(3,("lockread fnum=%d num=%d nread=%d\n", fsp->fnum, (int)numtoread, (int)nread)); @@ -3060,7 +3063,7 @@ void reply_read(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBread); @@ -3091,9 +3094,9 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", reply_outbuf(req, 5, numtoread+3); data = smb_buf(req->outbuf) + 3; - - if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtoread, - (SMB_BIG_UINT)startpos, READ_LOCK)) { + + if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtoread, + (uint64_t)startpos, READ_LOCK)) { reply_doserror(req, ERRDOS,ERRlock); END_PROFILE(SMBread); return; @@ -3114,7 +3117,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", SSVAL(req->outbuf,smb_vwv5,nread+3); SCVAL(smb_buf(req->outbuf),0,1); SSVAL(smb_buf(req->outbuf),1,nread); - + DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", fsp->fnum, (int)numtoread, (int)nread ) ); @@ -3304,7 +3307,7 @@ void reply_read_and_X(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv2)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2)); startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3); smb_maxcnt = SVAL(req->inbuf,smb_vwv5); @@ -3379,8 +3382,8 @@ void reply_read_and_X(struct smb_request *req) } - if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)smb_maxcnt, - (SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)smb_maxcnt, + (uint64_t)startpos, READ_LOCK)) { END_PROFILE(SMBreadX); reply_doserror(req, ERRDOS, ERRlock); return; @@ -3452,7 +3455,7 @@ void reply_writebraw(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { error_to_writebrawerr(req); END_PROFILE(SMBwritebraw); @@ -3489,8 +3492,8 @@ void reply_writebraw(struct smb_request *req) return; } - if (is_locked(fsp,(uint32)req->smbpid,(SMB_BIG_UINT)tcount, - (SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,(uint32)req->smbpid,(uint64_t)tcount, + (uint64_t)startpos, WRITE_LOCK)) { reply_doserror(req, ERRDOS, ERRlock); error_to_writebrawerr(req); END_PROFILE(SMBwritebraw); @@ -3656,8 +3659,8 @@ void reply_writeunlock(struct smb_request *req) END_PROFILE(SMBwriteunlock); return; } - - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBwriteunlock); @@ -3673,10 +3676,10 @@ void reply_writeunlock(struct smb_request *req) numtowrite = SVAL(req->inbuf,smb_vwv1); startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); data = smb_buf(req->inbuf) + 3; - + if (numtowrite - && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite, - (SMB_BIG_UINT)startpos, WRITE_LOCK)) { + && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, + (uint64_t)startpos, WRITE_LOCK)) { reply_doserror(req, ERRDOS, ERRlock); END_PROFILE(SMBwriteunlock); return; @@ -3690,7 +3693,7 @@ void reply_writeunlock(struct smb_request *req) } else { nwritten = write_file(req,fsp,data,startpos,numtowrite); } - + status = sync_file(conn, fsp, False /* write through */); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n", @@ -3710,8 +3713,8 @@ void reply_writeunlock(struct smb_request *req) status = do_unlock(smbd_messaging_context(), fsp, req->smbpid, - (SMB_BIG_UINT)numtowrite, - (SMB_BIG_UINT)startpos, + (uint64_t)numtowrite, + (uint64_t)startpos, WINDOWS_LOCK); if (NT_STATUS_V(status)) { @@ -3722,12 +3725,12 @@ void reply_writeunlock(struct smb_request *req) } reply_outbuf(req, 1, 0); - + SSVAL(req->outbuf,smb_vwv0,nwritten); - + DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); - + END_PROFILE(SMBwriteunlock); return; } @@ -3764,7 +3767,7 @@ void reply_write(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBwrite); @@ -3780,9 +3783,9 @@ void reply_write(struct smb_request *req) numtowrite = SVAL(req->inbuf,smb_vwv1); startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); data = smb_buf(req->inbuf) + 3; - - if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite, - (SMB_BIG_UINT)startpos, WRITE_LOCK)) { + + if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, + (uint64_t)startpos, WRITE_LOCK)) { reply_doserror(req, ERRDOS, ERRlock); END_PROFILE(SMBwrite); return; @@ -3831,14 +3834,14 @@ void reply_write(struct smb_request *req) } reply_outbuf(req, 1, 0); - + SSVAL(req->outbuf,smb_vwv0,nwritten); if (nwritten < (ssize_t)numtowrite) { SCVAL(req->outbuf,smb_rcls,ERRHRD); SSVAL(req->outbuf,smb_err,ERRdiskfull); } - + DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); END_PROFILE(SMBwrite); @@ -3994,7 +3997,7 @@ void reply_write_and_X(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv2)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2)); startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3); write_through = BITSETW(req->inbuf+smb_vwv7,0); @@ -4037,8 +4040,8 @@ void reply_write_and_X(struct smb_request *req) } if (is_locked(fsp,(uint32)req->smbpid, - (SMB_BIG_UINT)numtowrite, - (SMB_BIG_UINT)startpos, WRITE_LOCK)) { + (uint64_t)numtowrite, + (uint64_t)startpos, WRITE_LOCK)) { reply_doserror(req, ERRDOS, ERRlock); END_PROFILE(SMBwriteX); return; @@ -4059,7 +4062,7 @@ void reply_write_and_X(struct smb_request *req) END_PROFILE(SMBwriteX); return; } - + nwritten = write_file(req,fsp,data,startpos,numtowrite); } @@ -4115,7 +4118,7 @@ void reply_lseek(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { return; @@ -4175,7 +4178,7 @@ void reply_lseek(struct smb_request *req) reply_outbuf(req, 2, 0); SIVAL(req->outbuf,smb_vwv0,res); - + DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n", fsp->fnum, (double)startpos, (double)res, mode)); @@ -4201,12 +4204,12 @@ void reply_flush(struct smb_request *req) } fnum = SVAL(req->inbuf,smb_vwv0); - fsp = file_fsp(fnum); + fsp = file_fsp(req, fnum); if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) { return; } - + if (!fsp) { file_sync_all(conn); } else { @@ -4219,7 +4222,7 @@ void reply_flush(struct smb_request *req) return; } } - + reply_outbuf(req, 0, 0); DEBUG(3,("flush\n")); @@ -4263,17 +4266,10 @@ void reply_close(struct smb_request *req) return; } - /* If it's an IPC, pass off to the pipe handler. */ - if (IS_IPC(conn)) { - reply_pipe_close(conn, req); - END_PROFILE(SMBclose); - return; - } - - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); /* - * We can only use CHECK_FSP if we know it's not a directory. + * We can only use check_fsp if we know it's not a directory. */ if(!fsp || (fsp->conn != conn) || (fsp->vuid != req->vuid)) { @@ -4287,7 +4283,7 @@ void reply_close(struct smb_request *req) * Special case - close NT SMB directory handle. */ DEBUG(3,("close directory fnum=%d\n", fsp->fnum)); - status = close_file(fsp,NORMAL_CLOSE); + status = close_file(req, fsp, NORMAL_CLOSE); } else { time_t t; /* @@ -4297,7 +4293,7 @@ void reply_close(struct smb_request *req) DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n", fsp->fh->fd, fsp->fnum, conn->num_files_open)); - + /* * Take care of any time sent in the close. */ @@ -4310,8 +4306,8 @@ void reply_close(struct smb_request *req) * was detected on close - normally this is due to * a disk full error. If not then it was probably an I/O error. */ - - status = close_file(fsp,NORMAL_CLOSE); + + status = close_file(req, fsp, NORMAL_CLOSE); } if (!NT_STATUS_IS_OK(status)) { @@ -4348,7 +4344,7 @@ void reply_writeclose(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBwriteclose); @@ -4365,15 +4361,15 @@ void reply_writeclose(struct smb_request *req) mtime = convert_time_t_to_timespec(srv_make_unix_date3( req->inbuf+smb_vwv4)); data = smb_buf(req->inbuf) + 1; - + if (numtowrite - && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite, - (SMB_BIG_UINT)startpos, WRITE_LOCK)) { + && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, + (uint64_t)startpos, WRITE_LOCK)) { reply_doserror(req, ERRDOS,ERRlock); END_PROFILE(SMBwriteclose); return; } - + nwritten = write_file(req,fsp,data,startpos,numtowrite); set_close_write_time(fsp, mtime); @@ -4386,19 +4382,19 @@ void reply_writeclose(struct smb_request *req) if (numtowrite) { DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n", fsp->fsp_name )); - close_status = close_file(fsp,NORMAL_CLOSE); + close_status = close_file(req, fsp, NORMAL_CLOSE); } DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n", fsp->fnum, (int)numtowrite, (int)nwritten, conn->num_files_open)); - + if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { reply_doserror(req, ERRHRD, ERRdiskfull); END_PROFILE(SMBwriteclose); return; } - + if(!NT_STATUS_IS_OK(close_status)) { reply_nterror(req, close_status); END_PROFILE(SMBwriteclose); @@ -4406,7 +4402,7 @@ void reply_writeclose(struct smb_request *req) } reply_outbuf(req, 1, 0); - + SSVAL(req->outbuf,smb_vwv0,nwritten); END_PROFILE(SMBwriteclose); return; @@ -4422,7 +4418,7 @@ void reply_writeclose(struct smb_request *req) void reply_lock(struct smb_request *req) { connection_struct *conn = req->conn; - SMB_BIG_UINT count,offset; + uint64_t count,offset; NTSTATUS status; files_struct *fsp; struct byte_range_lock *br_lck = NULL; @@ -4435,7 +4431,7 @@ void reply_lock(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBlock); @@ -4444,8 +4440,8 @@ void reply_lock(struct smb_request *req) release_level_2_oplocks_on_change(fsp); - count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1); - offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3); + count = (uint64_t)IVAL(req->inbuf,smb_vwv1); + offset = (uint64_t)IVAL(req->inbuf,smb_vwv3); DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", fsp->fh->fd, fsp->fnum, (double)offset, (double)count)); @@ -4482,7 +4478,7 @@ void reply_lock(struct smb_request *req) void reply_unlock(struct smb_request *req) { connection_struct *conn = req->conn; - SMB_BIG_UINT count,offset; + uint64_t count,offset; NTSTATUS status; files_struct *fsp; @@ -4494,16 +4490,16 @@ void reply_unlock(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBunlock); return; } - - count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1); - offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3); - + + count = (uint64_t)IVAL(req->inbuf,smb_vwv1); + offset = (uint64_t)IVAL(req->inbuf,smb_vwv3); + status = do_unlock(smbd_messaging_context(), fsp, req->smbpid, @@ -4611,8 +4607,6 @@ void reply_echo(struct smb_request *req) TALLOC_FREE(req->outbuf); - smb_echo_count++; - END_PROFILE(SMBecho); return; } @@ -4626,7 +4620,7 @@ void reply_printopen(struct smb_request *req) connection_struct *conn = req->conn; files_struct *fsp; NTSTATUS status; - + START_PROFILE(SMBsplopen); if (req->wct < 2) { @@ -4642,7 +4636,7 @@ void reply_printopen(struct smb_request *req) } /* Open for exclusive use, write only. */ - status = print_fsp_open(conn, NULL, req->vuid, &fsp); + status = print_fsp_open(req, conn, NULL, req->vuid, &fsp); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -4652,7 +4646,7 @@ void reply_printopen(struct smb_request *req) reply_outbuf(req, 1, 0); SSVAL(req->outbuf,smb_vwv0,fsp->fnum); - + DEBUG(3,("openprint fd=%d fnum=%d\n", fsp->fh->fd, fsp->fnum)); @@ -4678,7 +4672,7 @@ void reply_printclose(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBsplclose); @@ -4690,11 +4684,11 @@ void reply_printclose(struct smb_request *req) END_PROFILE(SMBsplclose); return; } - + DEBUG(3,("printclose fd=%d fnum=%d\n", fsp->fh->fd,fsp->fnum)); - - status = close_file(fsp,NORMAL_CLOSE); + + status = close_file(req, fsp, NORMAL_CLOSE); if(!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -4744,7 +4738,7 @@ void reply_printqueue(struct smb_request *req) SSVAL(req->outbuf,smb_vwv1,0); SCVAL(smb_buf(req->outbuf),0,1); SSVAL(smb_buf(req->outbuf),1,0); - + DEBUG(3,("printqueue start_index=%d max_count=%d\n", start_index, max_count)); @@ -4760,7 +4754,7 @@ void reply_printqueue(struct smb_request *req) num_to_get = 0; else num_to_get = MIN(num_to_get,count-first); - + for (i=first;i<first+num_to_get;i++) { char blob[28]; @@ -4793,10 +4787,10 @@ void reply_printqueue(struct smb_request *req) } SAFE_FREE(queue); - + DEBUG(3,("%d entries returned in queue\n",count)); } - + END_PROFILE(SMBsplretq); return; } @@ -4819,8 +4813,8 @@ void reply_printwrite(struct smb_request *req) END_PROFILE(SMBsplwr); return; } - - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBsplwr); @@ -5217,7 +5211,7 @@ static bool resolve_wildcards(TALLOC_CTX *ctx, char *ext1 = NULL; char *ext2 = NULL; char *p,*p2, *pname1, *pname2; - + name2_copy = talloc_strdup(ctx, name2); if (!name2_copy) { return False; @@ -5229,7 +5223,7 @@ static bool resolve_wildcards(TALLOC_CTX *ctx, if (!pname1 || !pname2) { return False; } - + /* Truncate the copy of name2 at the last '/' */ *pname2 = '\0'; @@ -5583,10 +5577,10 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n", fsp->fsp_name,newname)); - rename_open_files(conn, lck, newname); - notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname); + rename_open_files(conn, lck, newname); + /* * A rename acts as a new file create w.r.t. allowing an initial delete * on close, probably because in Windows there is a new handle to the @@ -5789,7 +5783,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, last_component_dest, attrs, replace_if_exists); - close_file(fsp, NORMAL_CLOSE); + close_file(req, fsp, NORMAL_CLOSE); DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n", nt_errstr(status), directory,newname)); @@ -5893,7 +5887,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, status = rename_internals_fsp(conn, fsp, destname, dname, attrs, replace_if_exists); - close_file(fsp, NORMAL_CLOSE); + close_file(req, fsp, NORMAL_CLOSE); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("rename_internals_fsp returned %s for " @@ -6108,7 +6102,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, TALLOC_FREE(dest); if (!NT_STATUS_IS_OK(status)) { - close_file(fsp1,ERROR_CLOSE); + close_file(NULL, fsp1, ERROR_CLOSE); return status; } @@ -6127,7 +6121,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size); } - close_file(fsp1,NORMAL_CLOSE); + close_file(NULL, fsp1, NORMAL_CLOSE); /* Ensure the modtime is set correctly on the destination file. */ set_close_write_time(fsp2, get_mtimespec(&src_sbuf)); @@ -6138,7 +6132,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, * Thus we don't look at the error return from the * close of fsp1. */ - status = close_file(fsp2,NORMAL_CLOSE); + status = close_file(NULL, fsp2, NORMAL_CLOSE); if (!NT_STATUS_IS_OK(status)) { return status; @@ -6502,17 +6496,17 @@ uint32 get_lock_pid( char *data, int data_offset, bool large_file_format) Get a lock count, dealing with large count requests. ****************************************************************************/ -SMB_BIG_UINT get_lock_count( char *data, int data_offset, bool large_file_format) +uint64_t get_lock_count( char *data, int data_offset, bool large_file_format) { - SMB_BIG_UINT count = 0; + uint64_t count = 0; if(!large_file_format) { - count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset)); + count = (uint64_t)IVAL(data,SMB_LKLEN_OFFSET(data_offset)); } else { #if defined(HAVE_LONGLONG) - count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) | - ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset))); + count = (((uint64_t) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) | + ((uint64_t) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset))); #else /* HAVE_LONGLONG */ /* @@ -6529,7 +6523,7 @@ SMB_BIG_UINT get_lock_count( char *data, int data_offset, bool large_file_format SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0); } - count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)); + count = (uint64_t)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)); #endif /* HAVE_LONGLONG */ } @@ -6546,26 +6540,26 @@ static 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); } #endif /* !defined(HAVE_LONGLONG) */ @@ -6574,19 +6568,19 @@ static uint32 map_lock_offset(uint32 high, uint32 low) Get a lock offset, dealing with large offset requests. ****************************************************************************/ -SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err) +uint64_t get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err) { - SMB_BIG_UINT offset = 0; + uint64_t offset = 0; *err = False; if(!large_file_format) { - offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset)); + offset = (uint64_t)IVAL(data,SMB_LKOFF_OFFSET(data_offset)); } else { #if defined(HAVE_LONGLONG) - offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) | - ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset))); + offset = (((uint64_t) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) | + ((uint64_t) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset))); #else /* HAVE_LONGLONG */ /* @@ -6595,7 +6589,7 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_forma * negotiated. For boxes without large unsigned ints mangle the * lock offset by mapping the top 32 bits onto the lower 32. */ - + 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)); @@ -6603,7 +6597,7 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_forma if((new_low = map_lock_offset(high, low)) == 0) { *err = True; - return (SMB_BIG_UINT)-1; + return (uint64_t)-1; } DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n", @@ -6612,7 +6606,7 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_forma SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low); } - offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)); + offset = (uint64_t)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)); #endif /* HAVE_LONGLONG */ } @@ -6631,7 +6625,7 @@ void reply_lockingX(struct smb_request *req) unsigned char oplocklevel; uint16 num_ulocks; uint16 num_locks; - SMB_BIG_UINT count = 0, offset = 0; + uint64_t count = 0, offset = 0; uint32 lock_pid; int32 lock_timeout; int i; @@ -6647,8 +6641,8 @@ void reply_lockingX(struct smb_request *req) END_PROFILE(SMBlockingX); return; } - - fsp = file_fsp(SVAL(req->inbuf,smb_vwv2)); + + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2)); locktype = CVAL(req->inbuf,smb_vwv3); oplocklevel = CVAL(req->inbuf,smb_vwv3+1); num_ulocks = SVAL(req->inbuf,smb_vwv6); @@ -6660,7 +6654,7 @@ void reply_lockingX(struct smb_request *req) END_PROFILE(SMBlockingX); return; } - + data = smb_buf(req->inbuf); if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) { @@ -6671,7 +6665,7 @@ void reply_lockingX(struct smb_request *req) END_PROFILE(SMBlockingX); return; } - + /* Check if this is an oplock break on a file we have granted an oplock on. */ @@ -6688,7 +6682,7 @@ void reply_lockingX(struct smb_request *req) * Make sure we have granted an exclusive or batch oplock on * this file. */ - + if (fsp->oplock_type == 0) { /* The Samba4 nbench simulator doesn't understand @@ -6720,7 +6714,7 @@ void reply_lockingX(struct smb_request *req) } else { result = downgrade_oplock(fsp); } - + if (!result) { DEBUG(0, ("reply_lockingX: error in removing " "oplock on file %s\n", fsp->fsp_name)); @@ -6749,7 +6743,7 @@ void reply_lockingX(struct smb_request *req) * We do this check *after* we have checked this is not a oplock break * response message. JRA. */ - + release_level_2_oplocks_on_change(fsp); if (smb_buflen(req->inbuf) < @@ -6758,14 +6752,14 @@ void reply_lockingX(struct smb_request *req) END_PROFILE(SMBlockingX); return; } - + /* Data now points at the beginning of the list of smb_unlkrng structs */ for(i = 0; i < (int)num_ulocks; i++) { lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); - + /* * There is no error code marked "stupid client bug".... :-). */ @@ -6778,7 +6772,7 @@ void reply_lockingX(struct smb_request *req) DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for " "pid %u, file %s\n", (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name )); - + status = do_unlock(smbd_messaging_context(), fsp, lock_pid, @@ -6798,20 +6792,20 @@ void reply_lockingX(struct smb_request *req) if (!lp_blocking_locks(SNUM(conn))) { lock_timeout = 0; } - + /* Now do any requested locks */ data += ((large_file_format ? 20 : 10)*num_ulocks); - + /* Data now points at the beginning of the list of smb_lkrng structs */ - + for(i = 0; i < (int)num_locks; i++) { enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ? READ_LOCK:WRITE_LOCK); lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); - + /* * There is no error code marked "stupid client bug".... :-). */ @@ -6820,12 +6814,12 @@ void reply_lockingX(struct smb_request *req) reply_doserror(req, ERRDOS, ERRnoaccess); return; } - + DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid " "%u, file %s timeout = %d\n", (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name, (int)lock_timeout )); - + if (locktype & LOCKING_ANDX_CANCEL_LOCK) { if (lp_blocking_locks(SNUM(conn))) { @@ -6924,7 +6918,7 @@ void reply_lockingX(struct smb_request *req) return; } } - + /* If any of the above locks failed, then we must unlock all of the previous locks (X/Open spec). */ @@ -6941,7 +6935,7 @@ void reply_lockingX(struct smb_request *req) count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); - + /* * There is no error code marked "stupid client * bug".... :-). @@ -6951,7 +6945,7 @@ void reply_lockingX(struct smb_request *req) reply_doserror(req, ERRDOS, ERRnoaccess); return; } - + do_unlock(smbd_messaging_context(), fsp, lock_pid, @@ -6965,10 +6959,10 @@ void reply_lockingX(struct smb_request *req) } reply_outbuf(req, 2, 0); - + DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n", fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks)); - + END_PROFILE(SMBlockingX); chain_reply(req); } @@ -7024,7 +7018,7 @@ void reply_setattrE(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if(!fsp || (fsp->conn != conn)) { reply_doserror(req, ERRDOS, ERRbadfid); @@ -7042,7 +7036,7 @@ void reply_setattrE(struct smb_request *req) srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */ ts[1] = convert_time_t_to_timespec( srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */ - + reply_outbuf(req, 0, 0); /* @@ -7074,7 +7068,7 @@ void reply_setattrE(struct smb_request *req) END_PROFILE(SMBsetattrE); return; } - + DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n", fsp->fnum, (unsigned int)ts[0].tv_sec, @@ -7135,7 +7129,7 @@ void reply_getattrE(struct smb_request *req) return; } - fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); if(!fsp || (fsp->conn != conn)) { reply_doserror(req, ERRDOS, ERRbadfid); @@ -7149,9 +7143,9 @@ void reply_getattrE(struct smb_request *req) END_PROFILE(SMBgetattrE); return; } - + mode = dos_mode(conn,fsp->fsp_name,&sbuf); - + /* * Convert the times into dos times. Set create * date to be last modify date as UNIX doesn't save @@ -7176,9 +7170,9 @@ void reply_getattrE(struct smb_request *req) SIVAL(req->outbuf, smb_vwv8, allocation_size); } SSVAL(req->outbuf,smb_vwv10, mode); - + DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum)); - + END_PROFILE(SMBgetattrE); return; } diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c index e9dc46aa3c..3822ee191e 100644 --- a/source3/smbd/seal.c +++ b/source3/smbd/seal.c @@ -426,9 +426,14 @@ static NTSTATUS srv_enc_spnego_gss_negotiate(unsigned char **ppdata, size_t *p_d data_blob_free(&auth_reply); SAFE_FREE(*ppdata); - *ppdata = response.data; + *ppdata = (unsigned char *)memdup(response.data, response.length); + if ((*ppdata) == NULL && response.length > 0) { + status = NT_STATUS_NO_MEMORY; + } *p_data_size = response.length; + data_blob_free(&response); + return status; } #endif @@ -463,8 +468,13 @@ static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_si } SAFE_FREE(*ppdata); - *ppdata = response.data; + *ppdata = (unsigned char *)memdup(response.data, response.length); + if ((*ppdata) == NULL && response.length > 0) { + status = NT_STATUS_NO_MEMORY; + } *p_data_size = response.length; + data_blob_free(&response); + return status; } @@ -585,8 +595,11 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn, } SAFE_FREE(*ppdata); - *ppdata = response.data; + *ppdata = (unsigned char *)memdup(response.data, response.length); + if ((*ppdata) == NULL && response.length > 0) + return NT_STATUS_NO_MEMORY; *p_data_size = response.length; + data_blob_free(&response); return status; } @@ -636,8 +649,11 @@ static NTSTATUS srv_enc_raw_ntlm_auth(connection_struct *conn, /* Return the raw blob. */ SAFE_FREE(*ppdata); - *ppdata = response.data; + *ppdata = (unsigned char *)memdup(response.data, response.length); + if ((*ppdata) == NULL && response.length > 0) + return NT_STATUS_NO_MEMORY; *p_data_size = response.length; + data_blob_free(&response); return status; } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 53116f3d98..4e81263ee4 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -840,7 +840,7 @@ bool reload_services(bool test) if (lp_loaded()) { char *fname = lp_configfile(); - if (file_exist(fname, NULL) && + if (file_exist(fname) && !strcsequal(fname, get_dyn_CONFIGFILE())) { set_dyn_CONFIGFILE(fname); test = False; @@ -888,7 +888,7 @@ bool reload_services(bool test) enum server_exit_reason { SERVER_EXIT_NORMAL, SERVER_EXIT_ABNORMAL }; static void exit_server_common(enum server_exit_reason how, - const char *const reason) NORETURN_ATTRIBUTE; + const char *const reason) _NORETURN_; static void exit_server_common(enum server_exit_reason how, const char *const reason) @@ -1067,6 +1067,30 @@ static bool deadtime_fn(const struct timeval *now, void *private_data) return True; } +/* + * Do the recurring log file and smb.conf reload checks. + */ + +static bool housekeeping_fn(const struct timeval *now, void *private_data) +{ + change_to_root_user(); + + /* update printer queue caches if necessary */ + update_monitored_printq_cache(); + + /* check if we need to reload services */ + check_reload(time(NULL)); + + /* Change machine password if neccessary. */ + attempt_machine_password_change(); + + /* + * Force a log file check. + */ + force_check_log_size(); + check_log_size(); + return true; +} /**************************************************************************** main program. @@ -1295,7 +1319,7 @@ extern void build_options(bool screen); setpgid( (pid_t)0, (pid_t)0); #endif - if (!directory_exist(lp_lockdir(), NULL)) + if (!directory_exist(lp_lockdir())) mkdir(lp_lockdir(), 0755); if (is_daemon) @@ -1426,6 +1450,13 @@ extern void build_options(bool screen); exit(1); } + if (!(event_add_idle(smbd_event_context(), NULL, + timeval_set(SMBD_SELECT_TIMEOUT, 0), + "housekeeping", housekeeping_fn, NULL))) { + DEBUG(0, ("Could not add housekeeping event\n")); + exit(1); + } + #ifdef CLUSTER_SUPPORT if (lp_clustering()) { diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 0b851f1e48..05197021a3 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -1296,10 +1296,9 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password, void close_cnum(connection_struct *conn, uint16 vuid) { - if (IS_IPC(conn)) { - pipe_close_conn(conn); - } else { - file_close_conn(conn); + file_close_conn(conn); + + if (!IS_IPC(conn)) { dptr_closecnum(conn); } diff --git a/source3/smbd/session.c b/source3/smbd/session.c index 3b431a19be..8163eb30af 100644 --- a/source3/smbd/session.c +++ b/source3/smbd/session.c @@ -113,7 +113,10 @@ bool session_claim(user_struct *vuser) break; } - sess_pid = ((struct sessionid *)rec->value.dptr)->pid; + memcpy(&sess_pid, + ((char *)rec->value.dptr) + + offsetof(struct sessionid, pid), + sizeof(sess_pid)); if (!process_exists(sess_pid)) { DEBUG(5, ("%s has died -- re-using session\n", diff --git a/source3/smbd/statvfs.c b/source3/smbd/statvfs.c index 0e9a2c2ebe..ee33e13a48 100644 --- a/source3/smbd/statvfs.c +++ b/source3/smbd/statvfs.c @@ -118,7 +118,7 @@ static int darwin_statvfs(const char *path, vfs_statvfs_struct *statbuf) statbuf->UserBlocksAvail = sbuf.f_bavail; statbuf->TotalFileNodes = sbuf.f_files; statbuf->FreeFileNodes = sbuf.f_ffree; - statbuf->FsIdentifier = *(SMB_BIG_UINT *)(&sbuf.f_fsid); /* Ick. */ + statbuf->FsIdentifier = *(uint64_t *)(&sbuf.f_fsid); /* Ick. */ statbuf->FsCapabilities = darwin_fs_capabilities(sbuf.f_mntonname); return 0; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2e2da5cc71..1da45a8b58 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -47,9 +47,9 @@ static char *store_file_unix_basic_info2(connection_struct *conn, Only do this for Windows clients. ********************************************************************/ -SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val) +uint64_t smb_roundup(connection_struct *conn, uint64_t val) { - SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn)); + uint64_t rval = lp_allocation_roundup_size(SNUM(conn)); /* Only roundup for Windows clients. */ enum remote_arch_types ra_type = get_remote_arch(); @@ -64,18 +64,18 @@ SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val) account sparse files. ********************************************************************/ -SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, const SMB_STRUCT_STAT *sbuf) +uint64_t get_allocation_size(connection_struct *conn, files_struct *fsp, const SMB_STRUCT_STAT *sbuf) { - SMB_BIG_UINT ret; + uint64_t ret; if(S_ISDIR(sbuf->st_mode)) { return 0; } #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) - ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks; + ret = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks; #else - ret = (SMB_BIG_UINT)get_file_size(*sbuf); + ret = (uint64_t)get_file_size(*sbuf); #endif if (fsp && fsp->initial_allocation_size) @@ -1031,7 +1031,7 @@ static void call_trans2open(connection_struct *conn, mtime = sbuf.st_mtime; inode = sbuf.st_ino; if (fattr & aDIR) { - close_file(fsp,ERROR_CLOSE); + close_file(req, fsp, ERROR_CLOSE); reply_doserror(req, ERRDOS,ERRnoaccess); return; } @@ -1264,7 +1264,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, long prev_dirpos=0; uint32 mode=0; SMB_OFF_T file_size = 0; - SMB_BIG_UINT allocation_size = 0; + uint64_t allocation_size = 0; uint32 len; struct timespec mdate_ts, adate_ts, create_date_ts; time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0; @@ -1892,7 +1892,7 @@ static void call_trans2findfirst(connection_struct *conn, bool requires_resume_key; int info_level; char *directory = NULL; - const char *mask = NULL; + char *mask = NULL; char *p; int last_entry_off=0; int dptr_num = -1; @@ -1980,7 +1980,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", return; } - ntstatus = unix_convert(ctx, conn, directory, True, &directory, NULL, &sbuf); + ntstatus = unix_convert(ctx, conn, directory, True, &directory, &mask, &sbuf); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); return; @@ -1996,10 +1996,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", if(p == NULL) { /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */ if((directory[0] == '.') && (directory[1] == '\0')) { - mask = "*"; + mask = talloc_strdup(ctx,"*"); + if (!mask) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } mask_contains_wcard = True; - } else { - mask = directory; } directory = talloc_strdup(talloc_tos(), "./"); if (!directory) { @@ -2007,7 +2009,6 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", return; } } else { - mask = p+1; *p = 0; } @@ -2612,22 +2613,22 @@ static void call_trans2qfsinfo(connection_struct *conn, switch (info_level) { case SMB_INFO_ALLOCATION: { - SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; + uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 18; - if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { + if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { reply_unixerror(req, ERRHRD, ERRgeneral); return; } block_size = lp_block_size(snum); if (bsize < block_size) { - SMB_BIG_UINT factor = block_size/bsize; + uint64_t factor = block_size/bsize; bsize = block_size; dsize /= factor; dfree /= factor; } if (bsize > block_size) { - SMB_BIG_UINT factor = bsize/block_size; + uint64_t factor = bsize/block_size; bsize = block_size; dsize *= factor; dfree *= factor; @@ -2732,21 +2733,21 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi case SMB_QUERY_FS_SIZE_INFO: case SMB_FS_SIZE_INFORMATION: { - SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; + uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 24; - if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { + if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { reply_unixerror(req, ERRHRD, ERRgeneral); return; } block_size = lp_block_size(snum); if (bsize < block_size) { - SMB_BIG_UINT factor = block_size/bsize; + uint64_t factor = block_size/bsize; bsize = block_size; dsize /= factor; dfree /= factor; } if (bsize > block_size) { - SMB_BIG_UINT factor = bsize/block_size; + uint64_t factor = bsize/block_size; bsize = block_size; dsize *= factor; dfree *= factor; @@ -2765,21 +2766,21 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned case SMB_FS_FULL_SIZE_INFORMATION: { - SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; + uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 32; - if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { + if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { reply_unixerror(req, ERRHRD, ERRgeneral); return; } block_size = lp_block_size(snum); if (bsize < block_size) { - SMB_BIG_UINT factor = block_size/bsize; + uint64_t factor = block_size/bsize; bsize = block_size; dsize /= factor; dfree /= factor; } if (bsize > block_size) { - SMB_BIG_UINT factor = bsize/block_size; + uint64_t factor = bsize/block_size; bsize = block_size; dsize *= factor; dfree *= factor; @@ -2810,8 +2811,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned * what we have to send --metze: * * Unknown1: 24 NULL bytes - * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so - * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so + * Soft Quota Treshold: 8 bytes seems like uint64_t or so + * Hard Quota Limit: 8 bytes seems like uint64_t or so * Quota Flags: 2 byte : * Unknown3: 6 NULL bytes * @@ -2859,9 +2860,9 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn)))); /* Unknown1 24 NULL bytes*/ - SBIG_UINT(pdata,0,(SMB_BIG_UINT)0); - SBIG_UINT(pdata,8,(SMB_BIG_UINT)0); - SBIG_UINT(pdata,16,(SMB_BIG_UINT)0); + SBIG_UINT(pdata,0,(uint64_t)0); + SBIG_UINT(pdata,8,(uint64_t)0); + SBIG_UINT(pdata,16,(uint64_t)0); /* Default Soft Quota 8 bytes */ SBIG_UINT(pdata,24,quotas.softlim); @@ -2934,7 +2935,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned /* We have POSIX ACLs, pathname, encryption, * large read/write, and locking capability. */ - SBIG_UINT(pdata,4,((SMB_BIG_UINT)( + SBIG_UINT(pdata,4,((uint64_t)( CIFS_UNIX_POSIX_ACLS_CAP| CIFS_UNIX_POSIX_PATHNAMES_CAP| CIFS_UNIX_FCNTL_LOCKS_CAP| @@ -3036,9 +3037,9 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SIVAL(pdata, 0, flags); SIVAL(pdata, 4, SMB_WHOAMI_MASK); SBIG_UINT(pdata, 8, - (SMB_BIG_UINT)conn->server_info->utok.uid); + (uint64_t)conn->server_info->utok.uid); SBIG_UINT(pdata, 16, - (SMB_BIG_UINT)conn->server_info->utok.gid); + (uint64_t)conn->server_info->utok.gid); if (data_len >= max_data_bytes) { @@ -3077,7 +3078,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned /* GID list */ for (i = 0; i < conn->server_info->utok.ngroups; ++i) { SBIG_UINT(pdata, data_len, - (SMB_BIG_UINT)conn->server_info->utok.groups[i]); + (uint64_t)conn->server_info->utok.groups[i]); data_len += 8; } @@ -3297,7 +3298,7 @@ cap_low = 0x%x, cap_high = 0x%x\n", * but we didn't use the last 6 bytes for now * --metze */ - fsp = file_fsp(SVAL(params,0)); + fsp = file_fsp(req, SVAL(params,0)); if (!check_fsp_ntquota_handle(conn, req, fsp)) { @@ -3318,10 +3319,10 @@ cap_low = 0x%x, cap_high = 0x%x\n", /* unknown_1 24 NULL bytes in pdata*/ - /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ - quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24); + /* the soft quotas 8 bytes (uint64_t)*/ + quotas.softlim = (uint64_t)IVAL(pdata,24); #ifdef LARGE_SMB_OFF_T - quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32); + quotas.softlim |= (((uint64_t)IVAL(pdata,28)) << 32); #else /* LARGE_SMB_OFF_T */ if ((IVAL(pdata,28) != 0)&& ((quotas.softlim != 0xFFFFFFFF)|| @@ -3334,10 +3335,10 @@ cap_low = 0x%x, cap_high = 0x%x\n", } #endif /* LARGE_SMB_OFF_T */ - /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ - quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32); + /* the hard quotas 8 bytes (uint64_t)*/ + quotas.hardlim = (uint64_t)IVAL(pdata,32); #ifdef LARGE_SMB_OFF_T - quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32); + quotas.hardlim |= (((uint64_t)IVAL(pdata,36)) << 32); #else /* LARGE_SMB_OFF_T */ if ((IVAL(pdata,36) != 0)&& ((quotas.hardlim != 0xFFFFFFFF)|| @@ -3753,7 +3754,7 @@ static void call_trans2qpipeinfo(connection_struct *conn, unsigned int data_size = 0; unsigned int param_size = 2; uint16 info_level; - smb_np_struct *p_pipe = NULL; + files_struct *fsp; if (!params) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -3765,8 +3766,8 @@ static void call_trans2qpipeinfo(connection_struct *conn, return; } - p_pipe = get_rpc_pipe_p(SVAL(params,0)); - if (p_pipe == NULL) { + fsp = file_fsp(req, SVAL(params,0)); + if (!fsp_is_np(fsp)) { reply_nterror(req, NT_STATUS_INVALID_HANDLE); return; } @@ -3827,7 +3828,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, int mode=0; int nlink; SMB_OFF_T file_size=0; - SMB_BIG_UINT allocation_size=0; + uint64_t allocation_size=0; unsigned int data_size = 0; unsigned int param_size = 2; SMB_STRUCT_STAT sbuf; @@ -3872,7 +3873,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, return; } - fsp = file_fsp(SVAL(params,0)); + fsp = file_fsp(req, SVAL(params,0)); info_level = SVAL(params,2); DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); @@ -4681,8 +4682,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd case SMB_QUERY_POSIX_LOCK: { NTSTATUS status = NT_STATUS_INVALID_LEVEL; - SMB_BIG_UINT count; - SMB_BIG_UINT offset; + uint64_t count; + uint64_t offset; uint32 lock_pid; enum brl_type lock_type; @@ -4710,13 +4711,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); #if defined(HAVE_LONGLONG) - offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | - ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET)); - count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | - ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); + offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | + ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET)); + count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | + ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); #else /* HAVE_LONGLONG */ - offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET); - count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); + offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET); + count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); #endif /* HAVE_LONGLONG */ status = query_lock(fsp, @@ -5015,12 +5016,12 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, if (vfs_set_filelen(new_fsp, size) == -1) { status = map_nt_error_from_unix(errno); - close_file(new_fsp,NORMAL_CLOSE); + close_file(req, new_fsp,NORMAL_CLOSE); return status; } trigger_write_time_update_immediate(new_fsp); - close_file(new_fsp,NORMAL_CLOSE); + close_file(req, new_fsp,NORMAL_CLOSE); return NT_STATUS_OK; } @@ -5122,7 +5123,7 @@ static NTSTATUS smb_file_position_information(connection_struct *conn, int total_data, files_struct *fsp) { - SMB_BIG_UINT position_information; + uint64_t position_information; if (total_data < 8) { return NT_STATUS_INVALID_PARAMETER; @@ -5133,9 +5134,9 @@ static NTSTATUS smb_file_position_information(connection_struct *conn, return NT_STATUS_OK; } - position_information = (SMB_BIG_UINT)IVAL(pdata,0); + position_information = (uint64_t)IVAL(pdata,0); #ifdef LARGE_SMB_OFF_T - position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); + position_information |= (((uint64_t)IVAL(pdata,4)) << 32); #else /* LARGE_SMB_OFF_T */ if (IVAL(pdata,4) != 0) { /* more than 32 bits? */ @@ -5474,8 +5475,8 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn, int total_data, files_struct *fsp) { - SMB_BIG_UINT count; - SMB_BIG_UINT offset; + uint64_t count; + uint64_t offset; uint32 lock_pid; bool blocking_lock = False; enum brl_type lock_type; @@ -5522,13 +5523,13 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn, lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); #if defined(HAVE_LONGLONG) - offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | - ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET)); - count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | - ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); + offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | + ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET)); + count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | + ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); #else /* HAVE_LONGLONG */ - offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET); - count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); + offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET); + count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); #endif /* HAVE_LONGLONG */ DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u," @@ -5701,7 +5702,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf) { - SMB_BIG_UINT allocation_size = 0; + uint64_t allocation_size = 0; NTSTATUS status = NT_STATUS_OK; files_struct *new_fsp = NULL; @@ -5713,9 +5714,9 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, return NT_STATUS_INVALID_PARAMETER; } - allocation_size = (SMB_BIG_UINT)IVAL(pdata,0); + allocation_size = (uint64_t)IVAL(pdata,0); #ifdef LARGE_SMB_OFF_T - allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); + allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32); #else /* LARGE_SMB_OFF_T */ if (IVAL(pdata,4) != 0) { /* more than 32 bits? */ @@ -5770,7 +5771,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, if (allocation_size != get_file_size(*psbuf)) { if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) { status = map_nt_error_from_unix(errno); - close_file(new_fsp,NORMAL_CLOSE); + close_file(req, new_fsp, NORMAL_CLOSE); return status; } } @@ -5782,7 +5783,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, */ trigger_write_time_update_immediate(new_fsp); - close_file(new_fsp,NORMAL_CLOSE); + close_file(req, new_fsp, NORMAL_CLOSE); return NT_STATUS_OK; } @@ -6195,7 +6196,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, &fsp); if (NT_STATUS_IS_OK(status)) { - close_file(fsp, NORMAL_CLOSE); + close_file(req, fsp, NORMAL_CLOSE); } info_level_return = SVAL(pdata,16); @@ -6388,7 +6389,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn, /* Realloc the data size */ *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size); if (*ppdata == NULL) { - close_file(fsp,ERROR_CLOSE); + close_file(req, fsp, ERROR_CLOSE); *pdata_return_size = 0; return NT_STATUS_NO_MEMORY; } @@ -6506,7 +6507,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, if (lck == NULL) { DEBUG(0, ("smb_posix_unlink: Could not get share mode " "lock for file %s\n", fsp->fsp_name)); - close_file(fsp, NORMAL_CLOSE); + close_file(req, fsp, NORMAL_CLOSE); return NT_STATUS_INVALID_PARAMETER; } @@ -6522,7 +6523,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, continue; } /* Fail with sharing violation. */ - close_file(fsp, NORMAL_CLOSE); + close_file(req, fsp, NORMAL_CLOSE); TALLOC_FREE(lck); return NT_STATUS_SHARING_VIOLATION; } @@ -6539,12 +6540,12 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, psbuf); if (!NT_STATUS_IS_OK(status)) { - close_file(fsp, NORMAL_CLOSE); + close_file(req, fsp, NORMAL_CLOSE); TALLOC_FREE(lck); return status; } TALLOC_FREE(lck); - return close_file(fsp, NORMAL_CLOSE); + return close_file(req, fsp, NORMAL_CLOSE); } /**************************************************************************** @@ -6581,7 +6582,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, return; } - fsp = file_fsp(SVAL(params,0)); + fsp = file_fsp(req, SVAL(params,0)); /* Basic check for non-null fsp. */ if (!check_fsp_open(conn, req, fsp)) { return; @@ -7064,10 +7065,11 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } - } else if (IVAL(pdata,0) != 4) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; } + /* If total_data == 4 Windows doesn't care what values + * are placed in that field, it just ignores them. + * The System i QNTC IBM SMB client puts bad values here, + * so ignore them. */ status = create_directory(conn, req, directory); @@ -7249,7 +7251,7 @@ static void call_trans2ioctl(connection_struct *conn, unsigned int max_data_bytes) { char *pdata = *ppdata; - files_struct *fsp = file_fsp(SVAL(req->inbuf,smb_vwv15)); + files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv15)); /* check for an invalid fid before proceeding */ diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 1e137dd908..011f31dd24 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -501,13 +501,13 @@ ssize_t vfs_pwrite_data(struct smb_request *req, Returns 0 on success, -1 on failure. ****************************************************************************/ -int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) +int vfs_allocate_file_space(files_struct *fsp, uint64_t len) { int ret; SMB_STRUCT_STAT st; connection_struct *conn = fsp->conn; - SMB_BIG_UINT space_avail; - SMB_BIG_UINT bsize,dfree,dsize; + uint64_t space_avail; + uint64_t bsize,dfree,dsize; release_level_2_oplocks_on_change(fsp); @@ -527,10 +527,10 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) if (ret == -1) return ret; - if (len == (SMB_BIG_UINT)st.st_size) + if (len == (uint64_t)st.st_size) return 0; - if (len < (SMB_BIG_UINT)st.st_size) { + if (len < (uint64_t)st.st_size) { /* Shrink - use ftruncate. */ DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n", @@ -551,7 +551,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) len -= st.st_size; len /= 1024; /* Len is now number of 1k blocks needed. */ space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); - if (space_avail == (SMB_BIG_UINT)-1) { + if (space_avail == (uint64_t)-1) { return -1; } |