diff options
author | Jeremy Allison <jra@samba.org> | 2006-07-11 18:01:26 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:19:14 -0500 |
commit | fbdcf2663b56007a438ac4f0d8d82436b1bfe688 (patch) | |
tree | 4e42c1f061391cea3d640152fd240682cbf4fd9a /source3/smbd | |
parent | 5bf62a0c3cc95abe918f3e772bb10e0a90fdce22 (diff) | |
download | samba-fbdcf2663b56007a438ac4f0d8d82436b1bfe688.tar.gz samba-fbdcf2663b56007a438ac4f0d8d82436b1bfe688.tar.bz2 samba-fbdcf2663b56007a438ac4f0d8d82436b1bfe688.zip |
r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
to do the upper layer directories but this is what
everyone is waiting for....
Jeremy.
(This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8)
Diffstat (limited to 'source3/smbd')
34 files changed, 869 insertions, 1808 deletions
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index a8db498ef5..04ab01eb66 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -34,7 +34,7 @@ typedef struct _blocking_lock_record { int lock_num; SMB_BIG_UINT offset; SMB_BIG_UINT count; - uint16 lock_pid; + uint32 lock_pid; enum brl_flavour lock_flav; enum brl_type lock_type; char *inbuf; @@ -74,7 +74,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, files_struct *fsp, int lock_timeout, int lock_num, - uint16 lock_pid, + uint32 lock_pid, enum brl_type lock_type, enum brl_flavour lock_flav, SMB_BIG_UINT offset, SMB_BIG_UINT count) @@ -121,7 +121,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, memcpy(blr->inbuf, inbuf, length); blr->length = length; - br_lck = brl_get_locks(blr->fsp); + br_lck = brl_get_locks(NULL, blr->fsp); if (!br_lck) { free_blocking_lock_record(blr); return False; @@ -136,7 +136,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, PENDING_LOCK, blr->lock_flav, &my_lock_ctx); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); @@ -236,7 +236,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) 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; - uint16 lock_pid; + uint32 lock_pid; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -344,7 +344,7 @@ static BOOL process_lockread(blocking_lock_record *blr) data = smb_buf(outbuf) + 3; status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, startpos, READ_LOCK, @@ -417,7 +417,7 @@ static BOOL process_lock(blocking_lock_record *blr) errno = 0; status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, @@ -471,7 +471,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) 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; - uint16 lock_pid; + uint32 lock_pid; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; BOOL my_lock_ctx = False; @@ -625,7 +625,7 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp) for(blr = blocking_lock_queue; blr; blr = next) { next = blr->next; if(blr->fsp->fnum == fsp->fnum) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ @@ -637,7 +637,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } @@ -658,7 +658,7 @@ void remove_pending_lock_requests_by_mid(int mid) next = blr->next; if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ @@ -670,7 +670,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); @@ -754,7 +754,7 @@ void process_blocking_lock_queue(time_t t) fsp->fnum, fsp->fsp_name )); if((blr->expire_time != -1) && (blr->expire_time <= t)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Lock expired - throw away all previously @@ -771,7 +771,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); @@ -780,7 +780,7 @@ void process_blocking_lock_queue(time_t t) } if(!change_to_user(conn,vuid)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Remove the entry and return an error to the client. @@ -793,7 +793,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", @@ -804,7 +804,7 @@ void process_blocking_lock_queue(time_t t) } if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Remove the entry and return an error to the client. @@ -817,7 +817,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); @@ -834,7 +834,7 @@ void process_blocking_lock_queue(time_t t) */ if(blocking_lock_record_process(blr)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { brl_remove_pending_lock(br_lck, @@ -843,7 +843,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } free_blocking_lock_record(blr); diff --git a/source3/smbd/change_trust_pw.c b/source3/smbd/change_trust_pw.c index 738d12151d..31f03cc7fa 100644 --- a/source3/smbd/change_trust_pw.c +++ b/source3/smbd/change_trust_pw.c @@ -79,17 +79,19 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n", dc_name, nt_errstr(nt_status))); cli_shutdown(cli); + cli = NULL; goto failed; } nt_status = trust_pw_find_change_and_store_it(netlogon_pipe, cli->mem_ctx, domain); cli_shutdown(cli); + cli = NULL; failed: if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n", - timestring(False), domain)); + current_timestring(False), domain)); } else DEBUG(5,("change_trust_account_password: sucess!\n")); diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index d857611c35..52182f3129 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -57,7 +57,7 @@ BOOL conn_snum_used(int snum) { connection_struct *conn; for (conn=Connections;conn;conn=conn->next) { - if (conn->service == snum) { + if (conn->params->service == snum) { return(True); } } @@ -136,8 +136,10 @@ find_again: return NULL; } - if ((conn=TALLOC_ZERO_P(mem_ctx, connection_struct))==NULL) { + if (!(conn=TALLOC_ZERO_P(mem_ctx, connection_struct)) || + !(conn->params = TALLOC_P(mem_ctx, struct share_params))) { DEBUG(0,("talloc_zero() failed!\n")); + TALLOC_FREE(mem_ctx); return NULL; } conn->mem_ctx = mem_ctx; @@ -314,7 +316,7 @@ void msg_force_tdis(int msg_type, struct process_id pid, void *buf, size_t len) for (conn=Connections;conn;conn=next) { next=conn->next; - if (strequal(lp_servicename(conn->service), sharename)) { + if (strequal(lp_servicename(SNUM(conn)), sharename)) { DEBUG(1,("Forcing close of share %s cnum=%d\n", sharename, conn->cnum)); close_cnum(conn, (uint16)-1); diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c index 07d3181144..0442a9441a 100644 --- a/source3/smbd/connection.c +++ b/source3/smbd/connection.c @@ -83,7 +83,7 @@ BOOL yield_connection(connection_struct *conn, const char *name) struct count_stat { pid_t mypid; int curr_connections; - char *name; + const char *name; BOOL Clear; }; @@ -124,43 +124,55 @@ static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *u Claim an entry in the connections database. ****************************************************************************/ -BOOL claim_connection(connection_struct *conn, const char *name,int max_connections,BOOL Clear, uint32 msg_flags) +int count_current_connections( const char *sharename, BOOL clear ) { - struct connections_key key; - struct connections_data crec; - TDB_DATA kbuf, dbuf; - - if (!tdb) - tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR | O_CREAT, 0644); + struct count_stat cs; - if (!tdb) - return False; + cs.mypid = sys_getpid(); + cs.curr_connections = 0; + cs.name = sharename; + cs.Clear = clear; /* - * Enforce the max connections parameter. + * This has a race condition, but locking the chain before hand is worse + * as it leads to deadlock. */ - if (max_connections > 0) { - struct count_stat cs; + if (tdb_traverse(tdb, count_fn, &cs) == -1) { + DEBUG(0,("claim_connection: traverse of connections.tdb failed with error %s.\n", + tdb_errorstr(tdb) )); + return False; + } + + return cs.curr_connections; +} - cs.mypid = sys_getpid(); - cs.curr_connections = 0; - cs.name = lp_servicename(SNUM(conn)); - cs.Clear = Clear; +/**************************************************************************** + Claim an entry in the connections database. +****************************************************************************/ - /* - * This has a race condition, but locking the chain before hand is worse - * as it leads to deadlock. - */ +BOOL claim_connection(connection_struct *conn, const char *name,int max_connections,BOOL Clear, uint32 msg_flags) +{ + struct connections_key key; + struct connections_data crec; + TDB_DATA kbuf, dbuf; - if (tdb_traverse(tdb, count_fn, &cs) == -1) { - DEBUG(0,("claim_connection: traverse of connections.tdb failed with error %s.\n", - tdb_errorstr(tdb) )); + if (!tdb) { + if ( (tdb =conn_tdb_ctx()) == NULL ) { return False; } + } + + /* + * Enforce the max connections parameter. + */ - if (cs.curr_connections >= max_connections) { + if (max_connections > 0) { + int curr_connections; + + curr_connections = count_current_connections( lp_servicename(SNUM(conn)), True ); + + if (curr_connections >= max_connections) { DEBUG(1,("claim_connection: Max connections (%d) exceeded for %s\n", max_connections, name )); return False; @@ -241,3 +253,108 @@ BOOL register_message_flags(BOOL doreg, uint32 msg_flags) SAFE_FREE(dbuf.dptr); 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 ); + + if ( (kbuf->dptr = talloc_strdup(prec, key_string)) == NULL ) + return NULL; + + kbuf->dsize = strlen(key_string)+1; + + 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 pipe_open_rec *prec; + TDB_DATA *key; + TDB_DATA data; + TDB_CONTEXT *pipe_tdb; + 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 = (char*)prec; + data.dsize = sizeof(struct pipe_open_rec); + + if ( (pipe_tdb = conn_tdb_ctx() ) == NULL ) { + goto done; + } + + ret = (tdb_store( pipe_tdb, *key, data, TDB_REPLACE ) != -1); + +done: + TALLOC_FREE( prec ); + return ret; +} + +/********************************************************************* +*********************************************************************/ + +BOOL delete_pipe_opendb( smb_np_struct *p ) +{ + struct pipe_open_rec *prec; + TDB_DATA *key; + TDB_CONTEXT *pipe_tdb; + 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 ( (pipe_tdb = conn_tdb_ctx() ) == NULL ) { + goto done; + } + + ret = (tdb_delete( pipe_tdb, *key ) != -1 ); + +done: + TALLOC_FREE( prec ); + return ret; +} diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5ba9e1ed57..96e0923dbd 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -741,7 +741,7 @@ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask) { - mangle_map(filename,True,False,SNUM(conn)); + mangle_map(filename,True,False,conn->params); return mask_match_search(filename,mask,False); } @@ -787,8 +787,9 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn mask_match_search(filename,mask,False) || mangle_mask_match(conn,filename,mask)) { - if (!mangle_is_8_3(filename, False, SNUM(conn))) - mangle_map(filename,True,False,SNUM(conn)); + if (!mangle_is_8_3(filename, False, conn->params)) + mangle_map(filename,True,False, + conn->params); pstrcpy(fname,filename); *path = 0; @@ -857,17 +858,17 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S /* Pseudo-open the file (note - no fd's created). */ if(S_ISDIR(pst->st_mode)) { - fsp = open_directory(conn, name, pst, + status = open_directory(conn, name, pst, READ_CONTROL_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, /* no create options. */ - NULL); + NULL, &fsp); } else { - fsp = open_file_stat(conn, name, pst); + status = open_file_stat(conn, name, pst, &fsp); } - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { return False; } @@ -920,17 +921,17 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ if(S_ISDIR(pst->st_mode)) { return True; } else { - fsp = open_file_ntcreate(conn, name, pst, + status = open_file_ntcreate(conn, name, pst, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - &info); + &info, &fsp); } - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { return False; } diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 61145fde2f..260a8dadbd 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -300,8 +300,7 @@ static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ * are not violating security in doing the setxattr. */ - fsp = open_file_fchmod(conn,path,sbuf); - if (!fsp) + if (!NT_STATUS_IS_OK(open_file_fchmod(conn,path,sbuf,&fsp))) return ret; become_root(); if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) { @@ -518,8 +517,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, * holding. We need to review this.... may need to * break batch oplocks open by others. JRA. */ - files_struct *fsp = open_file_fchmod(conn,fname,st); - if (!fsp) + files_struct *fsp; + if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,st,&fsp))) return -1; become_root(); ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); diff --git a/source3/smbd/error.c b/source3/smbd/error.c index fa236f0de0..409781eaa9 100644 --- a/source3/smbd/error.c +++ b/source3/smbd/error.c @@ -24,40 +24,6 @@ extern struct unix_error_map unix_dos_nt_errmap[]; extern uint32 global_client_caps; -/* these can be set by some functions to override the error codes */ -static int override_ERR_class; -static uint32 override_ERR_code; -static NTSTATUS override_ERR_ntstatus; - -/**************************************************************************** - Setting eclass and ecode only and status to NT_STATUS_INVALID forces DOS errors. - Setting status only and eclass and ecode to -1 forces NT errors. -****************************************************************************/ - -void set_saved_error_triple(int eclass, int ecode, NTSTATUS status) -{ - override_ERR_class = eclass; - override_ERR_code = ecode; - override_ERR_ntstatus = status; -} - -void set_saved_ntstatus(NTSTATUS status) -{ - uint8 tmp_eclass; /* Hmmm. override_ERR_class is not uint8... */ - override_ERR_ntstatus = status; - ntstatus_to_dos(status, &tmp_eclass, &override_ERR_code); - override_ERR_class = tmp_eclass; - -} - -/**************************************************************************** - Return the current settings of the error triple. Return True if any are set. -****************************************************************************/ - -NTSTATUS get_saved_ntstatus(void) -{ - return override_ERR_ntstatus; -} /**************************************************************************** Create an error packet from a cached error. @@ -103,6 +69,10 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_s return error_packet(outbuf,eclass,ecode,ntstatus,line,file); } +BOOL use_nt_status(void) +{ + return lp_nt_status_support() && (global_client_caps & CAP_STATUS32); +} /**************************************************************************** Create an error packet. Normally called using the ERROR() macro. @@ -117,18 +87,9 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in BOOL force_nt_status = False; BOOL force_dos_status = False; - if (override_ERR_class != SMB_SUCCESS || !NT_STATUS_IS_OK(override_ERR_ntstatus)) { - eclass = override_ERR_class; - ecode = override_ERR_code; - ntstatus = override_ERR_ntstatus; - override_ERR_class = SMB_SUCCESS; - override_ERR_code = 0; - override_ERR_ntstatus = NT_STATUS_OK; - } - if (eclass == (uint8)-1) { force_nt_status = True; - } else if (NT_STATUS_IS_INVALID(ntstatus)) { + } else if (NT_STATUS_IS_DOS(ntstatus)) { force_dos_status = True; } @@ -146,7 +107,10 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in nt_errstr(ntstatus))); } else { /* We're returning a DOS error only. */ - if (eclass == 0 && NT_STATUS_V(ntstatus)) { + if (NT_STATUS_IS_DOS(ntstatus)) { + eclass = NT_STATUS_DOS_CLASS(ntstatus); + ecode = NT_STATUS_DOS_CODE(ntstatus); + } else if (eclass == 0 && NT_STATUS_V(ntstatus)) { ntstatus_to_dos(ntstatus, &eclass, &ecode); } diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c index b4f1f02b72..7c5eeae5c7 100644 --- a/source3/smbd/fake_file.c +++ b/source3/smbd/fake_file.c @@ -101,24 +101,26 @@ enum FAKE_FILE_TYPE is_fake_file(const char *fname) Open a fake quota file with a share mode. ****************************************************************************/ -files_struct *open_fake_file(connection_struct *conn, +NTSTATUS open_fake_file(connection_struct *conn, enum FAKE_FILE_TYPE fake_file_type, const char *fname, - uint32 access_mask) + uint32 access_mask, + files_struct **result) { files_struct *fsp = NULL; + NTSTATUS status; /* access check */ if (current_user.ut.uid != 0) { DEBUG(1,("open_fake_file_shared: access_denied to service[%s] file[%s] user[%s]\n", lp_servicename(SNUM(conn)),fname,conn->user)); - errno = EACCES; - return NULL; + return NT_STATUS_ACCESS_DENIED; + } - fsp = file_new(conn); - if(!fsp) { - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; } DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n", @@ -128,7 +130,7 @@ files_struct *open_fake_file(connection_struct *conn, fsp->fh->fd = -1; fsp->vuid = current_user.vuid; fsp->fh->pos = -1; - fsp->can_lock = True; /* Should this be true ? */ + fsp->can_lock = False; /* Should this be true ? - No, JRA */ fsp->access_mask = access_mask; string_set(&fsp->fsp_name,fname); @@ -136,11 +138,12 @@ files_struct *open_fake_file(connection_struct *conn, if (fsp->fake_file_handle==NULL) { file_free(fsp); - return NULL; + return NT_STATUS_NO_MEMORY; } conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 6c0f8b7758..1ea5228e91 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -46,12 +46,13 @@ static BOOL fname_equal(const char *name1, const char *name2, BOOL case_sensitiv Mangle the 2nd name and check if it is then equal to the first name. ****************************************************************************/ -static BOOL mangled_equal(const char *name1, const char *name2, int snum) +static BOOL mangled_equal(const char *name1, const char *name2, + const struct share_params *p) { pstring tmpname; pstrcpy(tmpname, name2); - mangle_map(tmpname, True, False, snum); + mangle_map(tmpname, True, False, p); return strequal(name1, tmpname); } @@ -189,7 +190,8 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen * sensitive then searching won't help. */ - if (conn->case_sensitive && !mangle_is_mangled(name, SNUM(conn)) && !*lp_mangled_map(SNUM(conn))) + if (conn->case_sensitive && !mangle_is_mangled(name, conn->params) && + !*lp_mangled_map(conn->params)) return(False); name_has_wildcard = ms_has_wild(start); @@ -199,7 +201,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen * just a component. JRA. */ - if (mangle_is_mangled(start, SNUM(conn))) + if (mangle_is_mangled(start, conn->params)) component_was_mangled = True; /* @@ -318,7 +320,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen * purposes. Fix inspired by Thomas Neumann <t.neumann@iku-ag.de>. */ if (!conn->case_preserve || - (mangle_is_8_3(start, False, SNUM(conn)) && + (mangle_is_8_3(start, False, conn->params) && !conn->short_case_preserve)) { strnorm(start, lp_defaultcase(SNUM(conn))); } @@ -328,8 +330,8 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen * base of the filename. */ - if (mangle_is_mangled(start, SNUM(conn))) { - mangle_check_cache( start, sizeof(pstring) - 1 - (start - name), SNUM(conn)); + if (mangle_is_mangled(start, conn->params)) { + mangle_check_cache( start, sizeof(pstring) - 1 - (start - name), conn->params); } DEBUG(5,("New file %s\n",start)); @@ -444,7 +446,7 @@ static BOOL scan_directory(connection_struct *conn, const char *path, char *name BOOL mangled; long curpos; - mangled = mangle_is_mangled(name, SNUM(conn)); + mangled = mangle_is_mangled(name, conn->params); /* handle null paths */ if (*path == 0) @@ -466,7 +468,7 @@ static BOOL scan_directory(connection_struct *conn, const char *path, char *name */ if (mangled && !conn->case_sensitive) { - mangled = !mangle_check_cache( name, maxlength, SNUM(conn)); + mangled = !mangle_check_cache( name, maxlength, conn->params); } /* open the directory */ @@ -495,7 +497,7 @@ static BOOL scan_directory(connection_struct *conn, const char *path, char *name * against unmangled name. */ - if ((mangled && mangled_equal(name,dname,SNUM(conn))) || fname_equal(name, dname, conn->case_sensitive)) { + if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) { /* we've found the file, change it's name and return */ safe_strcpy(name, dname, maxlength); CloseDir(cur_dir); diff --git a/source3/smbd/files.c b/source3/smbd/files.c index e020d8e13a..7069818dee 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -59,7 +59,7 @@ static unsigned long get_gen_count(void) Find first available file slot. ****************************************************************************/ -files_struct *file_new(connection_struct *conn) +NTSTATUS file_new(connection_struct *conn, files_struct **result) { int i; static int first_file; @@ -82,14 +82,12 @@ files_struct *file_new(connection_struct *conn) /* TODO: We have to unconditionally return a DOS error here, * W2k3 even returns ERRDOS/ERRnofids for ntcreate&x with * NTSTATUS negotiated */ - set_saved_ntstatus(NT_STATUS_TOO_MANY_OPENED_FILES); - return NULL; + return NT_STATUS_TOO_MANY_OPENED_FILES; } fsp = SMB_MALLOC_P(files_struct); if (!fsp) { - set_saved_ntstatus(NT_STATUS_NO_MEMORY); - return NULL; + return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(fsp); @@ -97,8 +95,7 @@ files_struct *file_new(connection_struct *conn) fsp->fh = SMB_MALLOC_P(struct fd_handle); if (!fsp->fh) { SAFE_FREE(fsp); - set_saved_ntstatus(NT_STATUS_NO_MEMORY); - return NULL; + return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(fsp->fh); @@ -131,8 +128,9 @@ files_struct *file_new(connection_struct *conn) if (fsp_fi_cache.fsp == NULL) { ZERO_STRUCT(fsp_fi_cache); } - - return fsp; + + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** @@ -464,24 +462,16 @@ void file_free(files_struct *fsp) } /**************************************************************************** - Get a fsp from a packet given the offset of a 16 bit fnum. + Get an fsp from a 16 bit fnum. ****************************************************************************/ -files_struct *file_fsp(char *buf, int where) +files_struct *file_fnum(uint16 fnum) { - int fnum, count=0; files_struct *fsp; - - if (chain_fsp) - return chain_fsp; - - if (!buf) - return NULL; - fnum = SVAL(buf, where); + int count=0; for (fsp=Files;fsp;fsp=fsp->next, count++) { if (fsp->fnum == fnum) { - chain_fsp = fsp; if (count > 10) { DLIST_PROMOTE(Files, fsp); } @@ -492,6 +482,29 @@ files_struct *file_fsp(char *buf, int where) } /**************************************************************************** + Get an fsp from a packet given the offset of a 16 bit fnum. +****************************************************************************/ + +files_struct *file_fsp(char *buf, int where) +{ + files_struct *fsp; + + if (chain_fsp) { + return chain_fsp; + } + + if (!buf) { + return NULL; + } + + fsp = file_fnum(SVAL(buf, where)); + if (fsp) { + chain_fsp = fsp; + } + return fsp; +} + +/**************************************************************************** Reset the chained fsp - done at the start of a packet reply. ****************************************************************************/ @@ -504,15 +517,19 @@ void file_chain_reset(void) Duplicate the file handle part for a DOS or FCB open. ****************************************************************************/ -files_struct *dup_file_fsp(files_struct *fsp, +NTSTATUS dup_file_fsp(files_struct *fsp, uint32 access_mask, uint32 share_access, - uint32 create_options) + uint32 create_options, + files_struct **result) { - files_struct *dup_fsp = file_new(fsp->conn); + NTSTATUS status; + files_struct *dup_fsp; - if (!dup_fsp) { - return NULL; + status = file_new(fsp->conn, &dup_fsp); + + if (!NT_STATUS_IS_OK(status)) { + return status; } SAFE_FREE(dup_fsp->fh); @@ -547,5 +564,6 @@ files_struct *dup_file_fsp(files_struct *fsp, dup_fsp->aio_write_behind = fsp->aio_write_behind; string_set(&dup_fsp->fsp_name,fsp->fsp_name); - return dup_fsp; + *result = dup_fsp; + return NT_STATUS_OK; } diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index e4531d8ae9..2d6db8f2a3 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -72,7 +72,11 @@ static int CopyExpanded(connection_struct *conn, StrnCpy(buf,src,sizeof(buf)/2); pstring_sub(buf,"%S",lp_servicename(snum)); - standard_sub_conn(conn,buf,sizeof(buf)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + buf, sizeof(buf)); l = push_ascii(*dst,buf,*n, STR_TERMINATE); (*dst) += l; (*n) -= l; @@ -99,7 +103,11 @@ static int StrlenExpanded(connection_struct *conn, int snum, char *s) } StrnCpy(buf,s,sizeof(buf)/2); pstring_sub(buf,"%S",lp_servicename(snum)); - standard_sub_conn(conn,buf,sizeof(buf)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + buf, sizeof(buf)); return strlen(buf) + 1; } @@ -111,7 +119,11 @@ static char *Expand(connection_struct *conn, int snum, char *s) } StrnCpy(buf,s,sizeof(buf)/2); pstring_sub(buf,"%S",lp_servicename(snum)); - standard_sub_conn(conn,buf,sizeof(buf)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + buf, sizeof(buf)); return &buf[0]; } @@ -593,7 +605,7 @@ static void fill_printq_info_52(connection_struct *conn, int snum, PACKS(desc, "z", driver.info_3->monitorname); /* language monitor */ fstrcpy(location, "\\\\%L\\print$\\WIN40\\0"); - standard_sub_basic( "", location, sizeof(location)-1 ); + standard_sub_basic( "", "", location, sizeof(location)-1 ); PACKS(desc,"z", location); /* share to retrieve files */ PACKS(desc,"z", driver.info_3->defaultdatatype); /* default data type */ @@ -2534,7 +2546,6 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha char *str2 = skip_string(str1,1); char *p = skip_string(str2,1); uint32 jobid; - int snum; fstring sharename; int uLevel = SVAL(p,2); int function = SVAL(p,4); @@ -2548,9 +2559,9 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha return False; } - if ( (snum = lp_servicenumber(sharename)) == -1 ) { - DEBUG(0,("api_PrintJobInfo: unable to get service number from sharename [%s]\n", - sharename)); + if (!share_defined(sharename)) { + DEBUG(0,("api_PrintJobInfo: sharen [%s] not defined\n", + sharename)); return False; } @@ -2573,14 +2584,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha /* change job place in the queue, data gives the new place */ place = SVAL(data,0); - if (print_job_set_place(snum, jobid, place)) { + if (print_job_set_place(sharename, jobid, place)) { errcode=NERR_Success; } break; case 0xb: /* change print job name, data gives the name */ - if (print_job_set_name(snum, jobid, data)) { + if (print_job_set_name(sharename, jobid, data)) { errcode=NERR_Success; } break; @@ -2701,7 +2712,11 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par SIVAL(p,6,0); } else { SIVAL(p,6,PTR_DIFF(p2,*rdata)); - standard_sub_conn(conn,comment,sizeof(comment)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + comment, sizeof(comment)); StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0)); p2 = skip_string(p2,1); } @@ -3126,8 +3141,12 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param SSVALS(p,102,-1); /* bad_pw_count */ SSVALS(p,104,-1); /* num_logons */ SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */ - pstrcpy(p2,"\\\\%L"); - standard_sub_conn(conn, p2,0); + { + pstring tmp; + pstrcpy(tmp, "\\\\%L"); + standard_sub_basic("", "", tmp, sizeof(tmp)); + pstrcpy(p2, tmp); + } p2 = skip_string(p2,1); SSVAL(p,110,49); /* country_code */ SSVAL(p,112,860); /* code page */ diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c index ed69a6210e..16f99636eb 100644 --- a/source3/smbd/mangle.c +++ b/source3/smbd/mangle.c @@ -81,22 +81,24 @@ void mangle_change_to_posix(void) /* see if a filename has come out of our mangling code */ -BOOL mangle_is_mangled(const char *s, int snum) +BOOL mangle_is_mangled(const char *s, const struct share_params *p) { - return mangle_fns->is_mangled(s, snum); + return mangle_fns->is_mangled(s, p); } /* see if a filename matches the rules of a 8.3 filename */ -BOOL mangle_is_8_3(const char *fname, BOOL check_case, int snum) +BOOL mangle_is_8_3(const char *fname, BOOL check_case, + const struct share_params *p) { - return mangle_fns->is_8_3(fname, check_case, False, snum); + return mangle_fns->is_8_3(fname, check_case, False, p); } -BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case, int snum) +BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case, + const struct share_params *p) { - return mangle_fns->is_8_3(fname, check_case, True, snum); + return mangle_fns->is_8_3(fname, check_case, True, p); } /* @@ -105,20 +107,22 @@ BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case, int snum) looking for a matching name if it doesn't. It should succeed most of the time or there will be a huge performance penalty */ -BOOL mangle_check_cache(char *s, size_t maxlen, int snum) +BOOL mangle_check_cache(char *s, size_t maxlen, + const struct share_params *p) { - return mangle_fns->check_cache(s, maxlen, snum); + return mangle_fns->check_cache(s, maxlen, p); } /* map a long filename to a 8.3 name. */ -void mangle_map(pstring OutName, BOOL need83, BOOL cache83, int snum) +void mangle_map(pstring OutName, BOOL need83, BOOL cache83, + const struct share_params *p) { /* name mangling can be disabled for speed, in which case we just truncate the string */ - if (!lp_manglednames(snum)) { + if (!lp_manglednames(p)) { if (need83) { string_truncate(OutName, 12); } @@ -126,6 +130,6 @@ void mangle_map(pstring OutName, BOOL need83, BOOL cache83, int snum) } /* invoke the inane "mangled map" code */ - mangle_map_filename(OutName, snum); - mangle_fns->name_map(OutName, need83, cache83, lp_defaultcase(snum), snum); + mangle_map_filename(OutName, p); + mangle_fns->name_map(OutName, need83, cache83, lp_defaultcase(p->service), p); } diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c index 2092f430c0..320e31ab67 100644 --- a/source3/smbd/mangle_hash.c +++ b/source3/smbd/mangle_hash.c @@ -275,14 +275,15 @@ done: return ret; } -static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, int snum) +static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, + const struct share_params *p) { const char *f; smb_ucs2_t *ucs2name; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; size_t size; - magic_char = lp_magicchar(snum); + magic_char = lp_magicchar(p); if (!fname || !*fname) return False; @@ -360,11 +361,11 @@ static void init_chartest( void ) * * ************************************************************************** ** */ -static BOOL is_mangled(const char *s, int snum) +static BOOL is_mangled(const char *s, const struct share_params *p) { char *magic; - magic_char = lp_magicchar(snum); + magic_char = lp_magicchar(p); if( !ct_initialized ) init_chartest(); @@ -460,13 +461,13 @@ static void cache_mangled_name( const char mangled_name[13], char *raw_name ) * ************************************************************************** ** */ -static BOOL check_cache( char *s, size_t maxlen, int snum ) +static BOOL check_cache( char *s, size_t maxlen, const struct share_params *p ) { TDB_DATA data_val; char *ext_start = NULL; char *saved_ext = NULL; - magic_char = lp_magicchar(snum); + magic_char = lp_magicchar(p); /* If the cache isn't initialized, give up. */ if( !tdb_mangled_cache ) @@ -606,10 +607,11 @@ static void to_8_3(char *s, int default_case) * **************************************************************************** */ -static void name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, int snum) +static void name_map(char *OutName, BOOL need83, BOOL cache83, + int default_case, const struct share_params *p) { smb_ucs2_t *OutName_ucs2; - magic_char = lp_magicchar(snum); + magic_char = lp_magicchar(p); DEBUG(5,("name_map( %s, need83 = %s, cache83 = %s)\n", OutName, need83 ? "True" : "False", cache83 ? "True" : "False")); diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c index 0a161c9e76..d1ce1af9ea 100644 --- a/source3/smbd/mangle_hash2.c +++ b/source3/smbd/mangle_hash2.c @@ -101,7 +101,7 @@ static unsigned mangle_prefix; hashing the resulting cache entry to match the known hash */ static char **prefix_cache; -static u32 *prefix_cache_hashes; +static unsigned int *prefix_cache_hashes; /* these are the characters we use in the 8.3 hash. Must be 36 chars long */ static const char *basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -119,10 +119,10 @@ static const char *reserved_names[] = this hash needs to be fast with a low collision rate (what hash doesn't?) */ -static u32 mangle_hash(const char *key, unsigned int length) +static unsigned int mangle_hash(const char *key, unsigned int length) { - u32 value; - u32 i; + unsigned int value; + unsigned int i; fstring str; /* we have to uppercase here to ensure that the mangled name @@ -139,8 +139,8 @@ static u32 mangle_hash(const char *key, unsigned int length) /* Set the initial value from the key size. */ for (value = FNV1_INIT, i=0; i < length; i++) { - value *= (u32)FNV1_PRIME; - value ^= (u32)(str[i]); + value *= (unsigned int)FNV1_PRIME; + value ^= (unsigned int)(str[i]); } /* note that we force it to a 31 bit hash, to keep within the limits @@ -162,7 +162,7 @@ static BOOL cache_init(void) return False; } - prefix_cache_hashes = SMB_CALLOC_ARRAY(u32, MANGLE_CACHE_SIZE); + prefix_cache_hashes = SMB_CALLOC_ARRAY(unsigned int, MANGLE_CACHE_SIZE); if (!prefix_cache_hashes) { return False; } @@ -173,7 +173,7 @@ static BOOL cache_init(void) /* insert an entry into the prefix cache. The string might not be null terminated */ -static void cache_insert(const char *prefix, int length, u32 hash) +static void cache_insert(const char *prefix, int length, unsigned int hash) { int i = hash % MANGLE_CACHE_SIZE; @@ -188,7 +188,7 @@ static void cache_insert(const char *prefix, int length, u32 hash) /* lookup an entry in the prefix cache. Return NULL if not found. */ -static const char *cache_lookup(u32 hash) +static const char *cache_lookup(unsigned int hash) { int i = hash % MANGLE_CACHE_SIZE; @@ -268,7 +268,7 @@ static BOOL is_mangled_component(const char *name, size_t len) directory separators. It should return true if any component is mangled */ -static BOOL is_mangled(const char *name, int snum) +static BOOL is_mangled(const char *name, const struct share_params *parm) { const char *p; const char *s; @@ -293,7 +293,7 @@ static BOOL is_mangled(const char *name, int snum) simplifies things greatly (it means that we know the string won't get larger when converted from UNIX to DOS formats) */ -static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards, int snum) +static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards, const struct share_params *p) { int len, i; char *dot_p; @@ -370,15 +370,15 @@ static void mangle_reset(void) try to find a 8.3 name in the cache, and if found then replace the string with the original long name. */ -static BOOL check_cache(char *name, size_t maxlen, int snum) +static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p) { - u32 hash, multiplier; + unsigned int hash, multiplier; unsigned int i; const char *prefix; char extension[4]; /* make sure that this is a mangled name from this cache */ - if (!is_mangled(name, snum)) { + if (!is_mangled(name, p)) { M_DEBUG(10,("check_cache: %s -> not mangled\n", name)); return False; } @@ -386,7 +386,7 @@ static BOOL check_cache(char *name, size_t maxlen, int snum) /* we need to extract the hash from the 8.3 name */ hash = base_reverse[(unsigned char)name[7]]; for (multiplier=36, i=5;i>=mangle_prefix;i--) { - u32 v = base_reverse[(unsigned char)name[i]]; + unsigned int v = base_reverse[(unsigned char)name[i]]; hash += multiplier * v; multiplier *= 36; } @@ -510,21 +510,21 @@ static BOOL is_legal_name(const char *name) the name parameter must be able to hold 13 bytes */ -static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case, int snum) +static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case, const struct share_params *p) { char *dot_p; char lead_chars[7]; char extension[4]; unsigned int extension_length, i; unsigned int prefix_len; - u32 hash, v; + unsigned int hash, v; char new_name[13]; /* reserved names are handled specially */ if (!is_reserved_name(name)) { /* if the name is already a valid 8.3 name then we don't need to do anything */ - if (is_8_3(name, False, False, snum)) { + if (is_8_3(name, False, False, p)) { return; } @@ -724,22 +724,22 @@ struct mangle_fns *mangle_hash2_init(void) static void posix_mangle_reset(void) {;} -static BOOL posix_is_mangled(const char *s, int snum) +static BOOL posix_is_mangled(const char *s, const struct share_params *p) { return False; } -static BOOL posix_is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, int snum) +static BOOL posix_is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, const struct share_params *p) { return False; } -static BOOL posix_check_cache( char *s, size_t maxlen, int snum ) +static BOOL posix_check_cache( char *s, size_t maxlen, const struct share_params *p ) { return False; } -static void posix_name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, int snum) +static void posix_name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, const struct share_params *p) { if (need83) { memset(OutName, '\0', 13); diff --git a/source3/smbd/mangle_map.c b/source3/smbd/mangle_map.c index 9e798fd41b..c5803786ec 100644 --- a/source3/smbd/mangle_map.c +++ b/source3/smbd/mangle_map.c @@ -201,11 +201,11 @@ static void mangled_map(char *s, const char *MangledMap) front end routine to the mangled map code personally I think that the whole idea of "mangled map" is completely bogus */ -void mangle_map_filename(fstring fname, int snum) +void mangle_map_filename(fstring fname, const struct share_params *p) { char *map; - map = lp_mangled_map(snum); + map = lp_mangled_map(p); if (!map || !*map) return; mangled_map(fname, map); diff --git a/source3/smbd/message.c b/source3/smbd/message.c index 31dab45844..fd53e60c14 100644 --- a/source3/smbd/message.c +++ b/source3/smbd/message.c @@ -101,7 +101,8 @@ static void msg_deliver(void) pstrcpy(s,lp_msg_command()); pstring_sub(s,"%f",alpha_strcpy(alpha_msgfrom,msgfrom,NULL,sizeof(alpha_msgfrom))); pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,NULL,sizeof(alpha_msgto))); - standard_sub_basic(current_user_info.smb_name, s, sizeof(s)); + standard_sub_basic(current_user_info.smb_name, + current_user_info.domain, s, sizeof(s)); pstring_sub(s,"%s",name); smbrun(s,NULL); } diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index b22b5674d6..69da4194fd 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -135,7 +135,6 @@ static BOOL create_conn_struct(connection_struct *conn, int snum, char *path) ZERO_STRUCTP(conn); - conn->service = snum; pstrcpy(connpath, path); pstring_sub(connpath , "%S", lp_servicename(snum)); @@ -145,6 +144,13 @@ static BOOL create_conn_struct(connection_struct *conn, int snum, char *path) DEBUG(0,("talloc_init(connection_struct) failed!\n")); return False; } + + if (!(conn->params = TALLOC_P(conn->mem_ctx, struct share_params))) { + DEBUG(0, ("TALLOC failed\n")); + return False; + } + + conn->params->service = snum; set_conn_connectpath(conn, connpath); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index aa6f79e165..0b1bdcadbb 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -321,7 +321,7 @@ static int nt_open_pipe(char *fname, connection_struct *conn, smb_np_struct *p = NULL; uint16 vuid = SVAL(inbuf, smb_uid); int i; - + DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname)); /* See if it is one we want to handle. */ @@ -350,6 +350,12 @@ static int nt_open_pipe(char *fname, connection_struct *conn, return(ERROR_DOS(ERRSRV,ERRnofids)); } + /* 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; return 0; } @@ -412,10 +418,14 @@ int reply_ntcreate_and_X_quota(connection_struct *conn, int result; char *p; uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess); - files_struct *fsp = open_fake_file(conn, fake_file_type, fname, desired_access); + files_struct *fsp; + NTSTATUS status; - if (!fsp) { - return ERROR_NT(NT_STATUS_ACCESS_DENIED); + status = open_fake_file(conn, fake_file_type, fname, desired_access, + &fsp); + + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); } set_message(outbuf,34,0,True); @@ -688,18 +698,18 @@ create_options = 0x%x root_dir_fid = 0x%x\n", return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - fsp = open_directory(conn, fname, &sbuf, + status = open_directory(conn, fname, &sbuf, access_mask, share_access, create_disposition, create_options, - &info); + &info, &fsp); restore_case_semantics(conn, file_attributes); - if(!fsp) { + if(!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntcreateX); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } else { /* @@ -719,15 +729,15 @@ create_options = 0x%x root_dir_fid = 0x%x\n", * before issuing an oplock break request to * our client. JRA. */ - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, - &info); - if (!fsp) { + &info, &fsp); + if (!NT_STATUS_IS_OK(status)) { /* We cheat here. There are two cases we * care about. One is a directory rename, * where the NT client will attempt to @@ -747,7 +757,8 @@ create_options = 0x%x root_dir_fid = 0x%x\n", * we handle in the open_file_stat case. JRA. */ - if(errno == EISDIR) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_FILE_IS_A_DIRECTORY)) { /* * Fail the open if it was explicitly a non-directory file. @@ -760,17 +771,17 @@ create_options = 0x%x root_dir_fid = 0x%x\n", } oplock_request = 0; - fsp = open_directory(conn, fname, &sbuf, + status = open_directory(conn, fname, &sbuf, access_mask, share_access, create_disposition, create_options, - &info); + &info, &fsp); - if(!fsp) { + if(!NT_STATUS_IS_OK(status)) { restore_case_semantics(conn, file_attributes); END_PROFILE(SMBntcreateX); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } else { @@ -780,7 +791,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } } @@ -1331,16 +1342,16 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o * CreateDirectory() call. */ - fsp = open_directory(conn, fname, &sbuf, + status = open_directory(conn, fname, &sbuf, access_mask, share_access, create_disposition, create_options, - &info); - if(!fsp) { + &info, &fsp); + if(!NT_STATUS_IS_OK(status)) { talloc_destroy(ctx); restore_case_semantics(conn, file_attributes); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } else { @@ -1349,17 +1360,18 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o * Ordinary file case. */ - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, - &info); + &info, &fsp); - if (!fsp) { - if(errno == EISDIR) { + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_FILE_IS_A_DIRECTORY)) { /* * Fail the open if it was explicitly a non-directory file. @@ -1371,16 +1383,16 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o } oplock_request = 0; - fsp = open_directory(conn, fname, &sbuf, + status = open_directory(conn, fname, &sbuf, access_mask, share_access, create_disposition, create_options, - &info); - if(!fsp) { + &info, &fsp); + if(!NT_STATUS_IS_OK(status)) { talloc_destroy(ctx); restore_case_semantics(conn, file_attributes); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } else { talloc_destroy(ctx); @@ -1389,7 +1401,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } } @@ -1655,39 +1667,29 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname)); - fsp1 = open_file_ntcreate(conn,oldname,&sbuf1, + status = open_file_ntcreate(conn,oldname,&sbuf1, FILE_READ_DATA, /* Read-only. */ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, /* No create options. */ FILE_ATTRIBUTE_NORMAL, NO_OPLOCK, - &info); + &info, &fsp1); - if (!fsp1) { - status = get_saved_ntstatus(); - if (NT_STATUS_IS_OK(status)) { - status = NT_STATUS_ACCESS_DENIED; - } - set_saved_ntstatus(NT_STATUS_OK); + if (!NT_STATUS_IS_OK(status)) { return status; } - fsp2 = open_file_ntcreate(conn,newname,&sbuf2, - FILE_WRITE_DATA, /* Write-only. */ + status = open_file_ntcreate(conn,newname,&sbuf2, + FILE_WRITE_DATA, /* Read-only. */ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_CREATE, 0, /* No create options. */ fattr, NO_OPLOCK, - &info); + &info, &fsp2); - if (!fsp2) { - status = get_saved_ntstatus(); - if (NT_STATUS_IS_OK(status)) { - status = NT_STATUS_ACCESS_DENIED; - } - set_saved_ntstatus(NT_STATUS_OK); + if (!NT_STATUS_IS_OK(status)) { close_file(fsp1,ERROR_CLOSE); return status; } @@ -2389,7 +2391,7 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, return ERROR_NT(NT_STATUS_INVALID_HANDLE); } - /* the NULL pointer cheking for fsp->fake_file_handle->pd + /* the NULL pointer checking for fsp->fake_file_handle->pd * is done by CHECK_NTQUOTA_HANDLE_OK() */ qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd; diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 832a8df755..7c04cdbe7c 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -38,24 +38,29 @@ struct deferred_open_record { fd support routines - attempt to do a dos_open. ****************************************************************************/ -static int fd_open(struct connection_struct *conn, +static BOOL fd_open(struct connection_struct *conn, const char *fname, + files_struct *fsp, int flags, mode_t mode) { - int fd; + int sav; + #ifdef O_NOFOLLOW if (!lp_symlinks(SNUM(conn))) { flags |= O_NOFOLLOW; } #endif - fd = SMB_VFS_OPEN(conn,fname,flags,mode); + fsp->fh->fd = SMB_VFS_OPEN(conn,fname,fsp,flags,mode); + sav = errno; - DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname, - flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" )); + DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", + fname, flags, (int)mode, fsp->fh->fd, + (fsp->fh->fd == -1) ? strerror(errno) : "" )); - return fd; + errno = sav; + return fsp->fh->fd != -1; } /**************************************************************************** @@ -179,7 +184,7 @@ void change_owner_to_parent(connection_struct *conn, Open a file. ****************************************************************************/ -static BOOL open_file(files_struct *fsp, +static NTSTATUS open_file(files_struct *fsp, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, @@ -210,7 +215,7 @@ static BOOL open_file(files_struct *fsp, /* It's a read-only share - fail if we wanted to write. */ if(accmode != O_RDONLY) { DEBUG(3,("Permission denied opening %s\n",fname)); - return False; + return NT_STATUS_ACCESS_DENIED; } else if(flags & O_CREAT) { /* We don't want to write - but we must make sure that O_CREAT doesn't create the file if we have write @@ -265,17 +270,15 @@ static BOOL open_file(files_struct *fsp, /* Don't create files with Microsoft wildcard characters. */ if ((local_flags & O_CREAT) && !file_existed && ms_has_wild(fname)) { - set_saved_ntstatus(NT_STATUS_OBJECT_NAME_INVALID); - return False; + return NT_STATUS_OBJECT_NAME_INVALID; } /* Actually do the open */ - fsp->fh->fd = fd_open(conn, fname, local_flags, unx_mode); - if (fsp->fh->fd == -1) { + if (!fd_open(conn, fname, fsp, local_flags, unx_mode)) { DEBUG(3,("Error opening file %s (%s) (local_flags=%d) " "(flags=%d)\n", fname,strerror(errno),local_flags,flags)); - return False; + return map_nt_error_from_unix(errno); } /* Inherit the ACL if the file was created. */ @@ -303,8 +306,9 @@ static BOOL open_file(files_struct *fsp, /* For a non-io open, this stat failing means file not found. JRA */ if (ret == -1) { + NTSTATUS status = map_nt_error_from_unix(errno); fd_close(conn, fsp); - return False; + return status; } } @@ -317,7 +321,7 @@ static BOOL open_file(files_struct *fsp, if(S_ISDIR(psbuf->st_mode)) { fd_close(conn, fsp); errno = EISDIR; - return False; + return NT_STATUS_FILE_IS_A_DIRECTORY; } fsp->mode = psbuf->st_mode; @@ -351,7 +355,7 @@ static BOOL open_file(files_struct *fsp, conn->num_files_open + 1)); errno = 0; - return True; + return NT_STATUS_OK; } /******************************************************************* @@ -894,8 +898,8 @@ static files_struct *fcb_or_dos_open(connection_struct *conn, } /* We need to duplicate this fsp. */ - dup_fsp = dup_file_fsp(fsp, access_mask, share_access, create_options); - if (!dup_fsp) { + if (!NT_STATUS_IS_OK(dup_file_fsp(fsp, access_mask, share_access, + create_options, &dup_fsp))) { return NULL; } @@ -1081,7 +1085,7 @@ static void schedule_defer_open(struct share_mode_lock *lck, struct timeval requ Open a file with a share mode. ****************************************************************************/ -files_struct *open_file_ntcreate(connection_struct *conn, +NTSTATUS open_file_ntcreate(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */ @@ -1091,7 +1095,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, uint32 new_dos_attributes, /* attributes used for new file. */ int oplock_request, /* internal Samba oplock codes. */ /* Information (FILE_EXISTS etc.) */ - int *pinfo) + int *pinfo, + files_struct **result) { int flags=0; int flags2=0; @@ -1099,7 +1104,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, BOOL def_acl = False; SMB_DEV_T dev = 0; SMB_INO_T inode = 0; - BOOL fsp_open = False; + NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED; files_struct *fsp = NULL; mode_t new_unx_mode = (mode_t)0; mode_t unx_mode = (mode_t)0; @@ -1123,7 +1128,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname)); - return print_fsp_open(conn, fname); + return print_fsp_open(conn, fname, &fsp); } /* We add aARCH to this as this mode is only used if the file is @@ -1162,7 +1167,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, } if (!check_name(fname,conn)) { - return NULL; + return map_nt_error_from_unix(errno); } new_dos_attributes &= SAMBA_ATTRIBUTES_MASK; @@ -1181,11 +1186,12 @@ files_struct *open_file_ntcreate(connection_struct *conn, if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) { /* OS/2 Workplace shell fix may be main code stream in a later * release. */ - set_saved_error_triple(ERRDOS, ERRcannotopen, - NT_STATUS_OBJECT_NAME_NOT_FOUND); DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not " "supported.\n")); - return NULL; + if (use_nt_status()) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + return NT_STATUS_DOS(ERRDOS, ERRcannotopen); } switch( create_disposition ) { @@ -1213,9 +1219,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(5,("open_file_ntcreate: FILE_OPEN " "requested for file %s and file " "doesn't exist.\n", fname )); - set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND); errno = ENOENT; - return NULL; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } break; @@ -1226,9 +1231,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE " "requested for file %s and file " "doesn't exist.\n", fname )); - set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND); errno = ENOENT; - return NULL; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } flags2 |= O_TRUNC; break; @@ -1245,7 +1249,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, } else { errno = EEXIST; } - return NULL; + return map_nt_error_from_unix(errno); } flags2 |= (O_CREAT|O_EXCL); break; @@ -1257,8 +1261,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, break; default: - set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER); - return NULL; + return NT_STATUS_INVALID_PARAMETER; } /* We only care about matching attributes on file exists and @@ -1277,7 +1280,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, (unsigned int)psbuf->st_mode, (unsigned int)unx_mode )); errno = EACCES; - return NULL; + return NT_STATUS_ACCESS_DENIED; } } @@ -1334,14 +1337,13 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(5,("open_file_ntcreate: write access requested for " "file %s on read only %s\n", fname, !CAN_WRITE(conn) ? "share" : "file" )); - set_saved_ntstatus(NT_STATUS_ACCESS_DENIED); errno = EACCES; - return NULL; + return NT_STATUS_ACCESS_DENIED; } - fsp = file_new(conn); - if(!fsp) { - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; } fsp->dev = psbuf->st_dev; @@ -1367,8 +1369,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, if (lck == NULL) { file_free(fsp); DEBUG(0, ("Could not get share mode lock\n")); - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } /* First pass - send break only on batch oplocks. */ @@ -1376,7 +1377,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, schedule_defer_open(lck, request_time); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } status = open_mode_check(conn, fname, lck, @@ -1390,16 +1391,15 @@ files_struct *open_file_ntcreate(connection_struct *conn, schedule_defer_open(lck, request_time); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } } if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) { /* DELETE_PENDING is not deferred for a second */ - set_saved_ntstatus(status); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return status; } if (!NT_STATUS_IS_OK(status)) { @@ -1424,7 +1424,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, *pinfo = FILE_WAS_OPENED; } conn->num_files_open++; - return fsp_dup; + *result = fsp_dup; + return NT_STATUS_OK; } } @@ -1449,13 +1450,13 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(4,("open_file_ntcreate : share_mode deny - " "calling open_file with flags=0x%X " - "flags2=0x%X mode=0%o returned %d\n", + "flags2=0x%X mode=0%o returned %s\n", flags, (flags2&~(O_TRUNC|O_CREAT)), - (unsigned int)unx_mode, (int)fsp_open )); + (unsigned int)unx_mode, nt_errstr(fsp_open))); - if (!fsp_open && errno) { + if (!NT_STATUS_IS_OK(fsp_open) && errno) { /* Default error. */ - set_saved_ntstatus(NT_STATUS_ACCESS_DENIED); + status = NT_STATUS_ACCESS_DENIED; } /* @@ -1471,7 +1472,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, /* this is a hack to speed up torture tests in 'make test' */ - timeout_usecs = lp_parm_int(conn->service, + timeout_usecs = lp_parm_int(SNUM(conn), "smbd","sharedelay", SHARING_VIOLATION_USEC_WAIT); @@ -1502,16 +1503,16 @@ files_struct *open_file_ntcreate(connection_struct *conn, } TALLOC_FREE(lck); - if (fsp_open) { + if (NT_STATUS_IS_OK(fsp_open)) { fd_close(conn, fsp); /* * We have detected a sharing violation here * so return the correct error code */ - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); + status = NT_STATUS_SHARING_VIOLATION; } file_free(fsp); - return NULL; + return status; } /* @@ -1542,12 +1543,12 @@ files_struct *open_file_ntcreate(connection_struct *conn, fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode, access_mask); - if (!fsp_open) { + if (!NT_STATUS_IS_OK(fsp_open)) { if (lck != NULL) { TALLOC_FREE(lck); } file_free(fsp); - return NULL; + return fsp_open; } if (!file_existed) { @@ -1578,8 +1579,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(0, ("open_file_ntcreate: Could not get share mode lock for %s\n", fname)); fd_close(conn, fsp); file_free(fsp); - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } status = open_mode_check(conn, fname, lck, @@ -1606,7 +1606,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, defer_open(lck, request_time, timeval_zero(), &state); TALLOC_FREE(lck); - return NULL; + return status; } /* @@ -1642,10 +1642,11 @@ files_struct *open_file_ntcreate(connection_struct *conn, */ if ((SMB_VFS_FTRUNCATE(fsp,fsp->fh->fd,0) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf)==-1)) { + status = map_nt_error_from_unix(errno); TALLOC_FREE(lck); fd_close(conn,fsp); file_free(fsp); - return NULL; + return status; } } @@ -1692,16 +1693,15 @@ files_struct *open_file_ntcreate(connection_struct *conn, /* Handle strange delete on close create semantics. */ if (create_options & FILE_DELETE_ON_CLOSE) { - NTSTATUS result = can_set_delete_on_close(fsp, True, new_dos_attributes); + status = can_set_delete_on_close(fsp, True, new_dos_attributes); - if (!NT_STATUS_IS_OK(result)) { + if (!NT_STATUS_IS_OK(status)) { /* Remember to delete the mode we just added. */ del_share_mode(lck, fsp); TALLOC_FREE(lck); fd_close(conn,fsp); file_free(fsp); - set_saved_ntstatus(result); - return NULL; + return status; } /* Note that here we set the *inital* delete on close flag, not the regular one. */ @@ -1770,31 +1770,32 @@ files_struct *open_file_ntcreate(connection_struct *conn, conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** Open a file for for write to ensure that we can fchmod it. ****************************************************************************/ -files_struct *open_file_fchmod(connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf) +NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf, files_struct **result) { files_struct *fsp = NULL; - BOOL fsp_open; + NTSTATUS status; if (!VALID_STAT(*psbuf)) { - return NULL; + return NT_STATUS_INVALID_PARAMETER; } - fsp = file_new(conn); - if(!fsp) { - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; } /* note! we must use a non-zero desired access or we don't get a real file descriptor. Oh what a twisted web we weave. */ - fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA); + status = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA); /* * This is not a user visible file open. @@ -1802,12 +1803,13 @@ files_struct *open_file_fchmod(connection_struct *conn, const char *fname, * the conn->num_files_open. */ - if (!fsp_open) { + if (!NT_STATUS_IS_OK(status)) { file_free(fsp); - return NULL; + return status; } - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** @@ -1825,14 +1827,15 @@ int close_file_fchmod(files_struct *fsp) Open a directory from an NT SMB call. ****************************************************************************/ -files_struct *open_directory(connection_struct *conn, +NTSTATUS open_directory(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 access_mask, uint32 share_access, uint32 create_disposition, uint32 create_options, - int *pinfo) + int *pinfo, + files_struct **result) { files_struct *fsp = NULL; BOOL dir_existed = VALID_STAT(*psbuf) ? True : False; @@ -1852,8 +1855,7 @@ files_struct *open_directory(connection_struct *conn, if (is_ntfs_stream_name(fname)) { DEBUG(0,("open_directory: %s is a stream name!\n", fname )); - set_saved_ntstatus(NT_STATUS_NOT_A_DIRECTORY); - return NULL; + return NT_STATUS_NOT_A_DIRECTORY; } switch( create_disposition ) { @@ -1864,8 +1866,7 @@ files_struct *open_directory(connection_struct *conn, DEBUG(5,("open_directory: FILE_OPEN requested " "for directory %s and it doesn't " "exist.\n", fname )); - set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND); - return NULL; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } info = FILE_WAS_OPENED; break; @@ -1877,9 +1878,12 @@ files_struct *open_directory(connection_struct *conn, DEBUG(5,("open_directory: FILE_CREATE " "requested for directory %s and it " "already exists.\n", fname )); - set_saved_error_triple(ERRDOS, ERRfilexists, - NT_STATUS_OBJECT_NAME_COLLISION); - return NULL; + if (use_nt_status()) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } else { + return NT_STATUS_DOS(ERRDOS, + ERRfilexists); + } } create_dir = True; info = FILE_WAS_CREATED; @@ -1903,8 +1907,7 @@ files_struct *open_directory(connection_struct *conn, DEBUG(5,("open_directory: invalid create_disposition " "0x%x for directory %s\n", (unsigned int)create_disposition, fname)); - set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER); - return NULL; + return NT_STATUS_INVALID_PARAMETER; } if (create_dir) { @@ -1921,27 +1924,26 @@ files_struct *open_directory(connection_struct *conn, "Error was %s\n", fname, strerror(errno) )); /* Ensure we return the correct NT status to the * client. */ - set_saved_error_triple(0, 0, status); - return NULL; + return status; } /* Ensure we're checking for a symlink here.... */ /* We don't want to get caught by a symlink racer. */ if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) { - return NULL; + return map_nt_error_from_unix(errno); } if(!S_ISDIR(psbuf->st_mode)) { DEBUG(0,("open_directory: %s is not a directory !\n", fname )); - return NULL; + return NT_STATUS_NOT_A_DIRECTORY; } } - fsp = file_new(conn); - if(!fsp) { - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; } /* @@ -1953,7 +1955,7 @@ files_struct *open_directory(connection_struct *conn, fsp->dev = psbuf->st_dev; fsp->vuid = current_user.vuid; fsp->file_pid = global_smbpid; - fsp->can_lock = True; + fsp->can_lock = False; fsp->can_read = False; fsp->can_write = False; @@ -1976,8 +1978,7 @@ files_struct *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); - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } status = open_mode_check(conn, fname, lck, @@ -1985,10 +1986,9 @@ files_struct *open_directory(connection_struct *conn, create_options, &dir_existed); if (!NT_STATUS_IS_OK(status)) { - set_saved_ntstatus(status); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return status; } set_share_mode(lck, fsp, current_user.ut.uid, 0, NO_OPLOCK); @@ -1998,10 +1998,9 @@ files_struct *open_directory(connection_struct *conn, if (create_options & FILE_DELETE_ON_CLOSE) { status = can_set_delete_on_close(fsp, True, 0); if (!NT_STATUS_IS_OK(status)) { - set_saved_ntstatus(status); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return status; } set_delete_on_close_token(lck, ¤t_user.ut); @@ -2022,28 +2021,33 @@ files_struct *open_directory(connection_struct *conn, conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** Open a pseudo-file (no locking checks - a 'stat' open). ****************************************************************************/ -files_struct *open_file_stat(connection_struct *conn, char *fname, - SMB_STRUCT_STAT *psbuf) +NTSTATUS open_file_stat(connection_struct *conn, char *fname, + SMB_STRUCT_STAT *psbuf, files_struct **result) { files_struct *fsp = NULL; + NTSTATUS status; - if (!VALID_STAT(*psbuf)) - return NULL; + if (!VALID_STAT(*psbuf)) { + return NT_STATUS_INVALID_PARAMETER; + } /* Can't 'stat' open directories. */ - if(S_ISDIR(psbuf->st_mode)) - return NULL; + if(S_ISDIR(psbuf->st_mode)) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } - fsp = file_new(conn); - if(!fsp) - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; + } DEBUG(5,("open_file_stat: 'opening' file %s\n", fname)); @@ -2069,7 +2073,8 @@ files_struct *open_file_stat(connection_struct *conn, char *fname, conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 73b0ebb4b3..389086e9bf 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -29,9 +29,6 @@ static user_struct *validated_users; static int next_vuid = VUID_OFFSET; static int num_validated_vuids; -extern userdom_struct current_user_info; - - /**************************************************************************** Check if a uid has been validated, and return an pointer to the user_struct if it has. NULL if not. vuid is biased by an offset. This allows us to @@ -550,9 +547,11 @@ static BOOL user_ok(const char *user, int snum) str_list_copy(&invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { - if ( invalid && - str_list_sub_basic(invalid, - current_user_info.smb_name) ) { + + /* This is used in sec=share only, so no current user + * around to pass to str_list_sub_basic() */ + + if ( invalid && str_list_sub_basic(invalid, "", "") ) { ret = !user_in_list(user, (const char **)invalid); } @@ -565,9 +564,11 @@ static BOOL user_ok(const char *user, int snum) str_list_copy(&valid, lp_valid_users(snum)); if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { - if ( valid && - str_list_sub_basic(valid, - current_user_info.smb_name) ) { + + /* This is used in sec=share only, so no current user + * around to pass to str_list_sub_basic() */ + + if ( valid && str_list_sub_basic(valid, "", "") ) { ret = user_in_list(user, (const char **)valid); } } diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2d90383706..52660da2ff 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -31,6 +31,21 @@ #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) +#define MAX_PIPE_NAME_LEN 24 + +/* PIPE/<name>/<pid>/<pnum> */ +#define PIPEDB_KEY_FORMAT "PIPE/%s/%u/%d" + +struct pipe_dbrec { + struct process_id pid; + int pnum; + uid_t uid; + + char name[MAX_PIPE_NAME_LEN]; + fstring user; +}; + + extern struct pipe_id_info pipe_names[]; /**************************************************************************** @@ -284,6 +299,8 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) if (!close_rpc_pipe_hnd(p)) { return ERROR_DOS(ERRDOS,ERRbadfid); } + + /* TODO: REMOVE PIPE FROM DB */ return(outsize); } diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 6e403dba92..73744cf26e 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3043,8 +3043,7 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_ return -1; } - fsp = open_file_fchmod(conn,fname,&st); - if (!fsp) { + if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,&st,&fsp))) { return -1; } @@ -4236,12 +4235,19 @@ SEC_DESC* get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) pstring filename; ZERO_STRUCT( conn ); - conn.service = -1; if ( !(conn.mem_ctx = talloc_init( "novfs_get_nt_acl" )) ) { DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n")); return NULL; } + + if (!(conn.params = TALLOC_P(conn.mem_ctx, struct share_params))) { + DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n")); + TALLOC_FREE(conn.mem_ctx); + return NULL; + } + + conn.params->service = -1; pstrcpy( path, "/" ); set_conn_connectpath(&conn, path); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index b3ce49360d..ce352adfd7 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -21,7 +21,7 @@ #include "includes.h" -extern uint16 global_smbpid; +uint16 global_smbpid; extern int keepalive; extern struct auth_context *negprot_global_auth_context; extern int smb_echo_count; @@ -172,7 +172,6 @@ BOOL open_was_deferred(uint16 mid) for (pml = deferred_open_queue; pml; pml = pml->next) { if (SVAL(pml->buf.data,smb_mid) == mid) { - set_saved_ntstatus(NT_STATUS_OK); return True; } } @@ -459,11 +458,20 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout) } } - maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds); - maxfd = select_on_fd(change_notify_fd(), maxfd, &fds); - maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds); + { + int sav; + START_PROFILE(smbd_idle); + + maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds); + maxfd = select_on_fd(change_notify_fd(), maxfd, &fds); + maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds); - selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to); + selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to); + sav = errno; + + END_PROFILE(smbd_idle); + errno = sav; + } /* if we get EINTR then maybe we have received an oplock signal - treat this as select returning 1. This is ugly, but @@ -885,7 +893,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize pid = sys_getpid(); errno = 0; - set_saved_ntstatus(NT_STATUS_OK); last_message = type; @@ -954,7 +961,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize } if (!change_to_user(conn,session_tag)) { - return(ERROR_FORCE_DOS(ERRSRV,ERRbaduid)); + return(ERROR_NT(NT_STATUS_DOS(ERRSRV,ERRbaduid))); } /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index e68e8662d7..ff3c6832e4 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -427,6 +427,7 @@ size_t srvstr_get_path_wcard(char *inbuf, char *dest, const char *src, size_t de } else { *err = check_path_syntax_wcard(dest, tmppath, contains_wcard); } + return ret; } @@ -453,6 +454,7 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len } else { *err = check_path_syntax(dest, tmppath); } + return ret; } @@ -809,6 +811,14 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBchkpth); + + /* Strange DOS error code semantics only for chkpth... */ + if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) { + if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) { + /* We need to map to ERRbadpath */ + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + } return ERROR_NT(status); } @@ -1370,25 +1380,25 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask, &share_mode, &create_disposition, &create_options)) { END_PROFILE(SMBopen); - return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess)); } - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_mode, create_disposition, create_options, dos_attr, oplock_request, - &info); + &info, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBopen); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess); + return ERROR_NT(status); } size = sbuf.st_size; @@ -1493,25 +1503,25 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt &create_disposition, &create_options)) { END_PROFILE(SMBopenX); - return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess)); } - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_mode, create_disposition, create_options, smb_attr, oplock_request, - &smb_action); + &smb_action, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBopenX); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess); + return ERROR_NT(status); } size = sbuf.st_size; @@ -1672,22 +1682,22 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, } /* Open file using ntcreate. */ - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_mode, create_disposition, create_options, fattr, oplock_request, - NULL); + NULL, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcreate); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess); + return ERROR_NT(status); } outsize = set_message(outbuf,1,0,True); @@ -1756,25 +1766,25 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, SMB_VFS_STAT(conn,fname,&sbuf); /* We should fail if file does not exist. */ - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, fattr, oplock_request, - NULL); + NULL, &fsp); /* close fd from smb_mkstemp() */ close(tmpfd); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBctemp); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess); + return ERROR_NT(status); } outsize = set_message(outbuf,1,0,True); @@ -1822,6 +1832,7 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, { files_struct *fsp; uint32 fmode; + NTSTATUS status; if (!CAN_WRITE(conn)) { return NT_STATUS_MEDIA_WRITE_PROTECTED; @@ -1836,25 +1847,16 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, return NT_STATUS_OK; } - /* We need a better way to return NT status codes from open... */ - set_saved_ntstatus(NT_STATUS_OK); - - fsp = open_file_ntcreate(conn, fname, pst, + status = open_file_ntcreate(conn, fname, pst, DELETE_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, 0, - NULL); + NULL, &fsp); - if (!fsp) { - NTSTATUS ret = get_saved_ntstatus(); - if (!NT_STATUS_IS_OK(ret)) { - set_saved_ntstatus(NT_STATUS_OK); - return ret; - } - set_saved_ntstatus(NT_STATUS_OK); + if (!NT_STATUS_IS_OK(status)) { return NT_STATUS_ACCESS_DENIED; } close_file(fsp,NORMAL_CLOSE); @@ -1870,6 +1872,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b SMB_STRUCT_STAT sbuf; uint32 fattr; files_struct *fsp; + NTSTATUS status; DEBUG(10,("can_delete: %s, dirtype = %d\n", fname, dirtype )); @@ -1929,26 +1932,17 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b /* On open checks the open itself will check the share mode, so don't do it here as we'll get it wrong. */ - /* We need a better way to return NT status codes from open... */ - set_saved_ntstatus(NT_STATUS_OK); - - fsp = open_file_ntcreate(conn, fname, &sbuf, + status = open_file_ntcreate(conn, fname, &sbuf, DELETE_ACCESS, FILE_SHARE_NONE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, 0, - NULL); + NULL, &fsp); - if (!fsp) { - NTSTATUS ret = get_saved_ntstatus(); - if (!NT_STATUS_IS_OK(ret)) { - set_saved_ntstatus(NT_STATUS_OK); - return ret; - } - set_saved_ntstatus(NT_STATUS_OK); - return NT_STATUS_ACCESS_DENIED; + if (!NT_STATUS_IS_OK(status)) { + return status; } close_file(fsp,NORMAL_CLOSE); } @@ -1994,8 +1988,8 @@ NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype, char *name, B * Tine Smukavec <valentin.smukavec@hermes.si>. */ - if (!rc && mangle_is_mangled(mask,SNUM(conn))) - mangle_check_cache( mask, sizeof(pstring)-1, SNUM(conn)); + if (!rc && mangle_is_mangled(mask,conn->params)) + mangle_check_cache( mask, sizeof(pstring)-1, conn->params ); if (!has_wild) { pstrcat(directory,"/"); @@ -2331,7 +2325,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s /* ensure we don't overrun the packet size */ maxcount = MIN(65535,maxcount); - if (!is_locked(fsp,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (!is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { SMB_STRUCT_STAT st; SMB_OFF_T size = 0; @@ -2403,7 +2397,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length */ status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, @@ -2510,7 +2504,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", data = smb_buf(outbuf) + 3; - if (is_locked(fsp,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) { END_PROFILE(SMBread); return ERROR_DOS(ERRDOS,ERRlock); } @@ -2717,7 +2711,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt } - if (is_locked(fsp,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) { END_PROFILE(SMBreadX); return ERROR_DOS(ERRDOS,ERRlock); } @@ -2780,7 +2774,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, SCVAL(inbuf,smb_com,SMBwritec); SCVAL(outbuf,smb_com,SMBwritec); - if (is_locked(fsp,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwritebraw); return(ERROR_DOS(ERRDOS,ERRlock)); } @@ -2901,7 +2895,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (numtowrite && is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwriteunlock); return ERROR_DOS(ERRDOS,ERRlock); } @@ -2924,7 +2918,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, if (numtowrite) { status = do_unlock(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite, (SMB_BIG_UINT)startpos, WINDOWS_LOCK); @@ -2978,7 +2972,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwrite); return ERROR_DOS(ERRDOS,ERRlock); } @@ -3093,7 +3087,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng #endif /* LARGE_SMB_OFF_T */ } - if (is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwriteX); return ERROR_DOS(ERRDOS,ERRlock); } @@ -3368,7 +3362,7 @@ int reply_writeclose(connection_struct *conn, mtime = srv_make_unix_date3(inbuf+smb_vwv4); data = smb_buf(inbuf) + 1; - if (numtowrite && is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwriteclose); return ERROR_DOS(ERRDOS,ERRlock); } @@ -3439,7 +3433,7 @@ int reply_lock(connection_struct *conn, fsp->fh->fd, fsp->fnum, (double)offset, (double)count)); status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, @@ -3494,7 +3488,7 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3); status = do_unlock(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), count, offset, WINDOWS_LOCK); @@ -3598,6 +3592,8 @@ int reply_printopen(connection_struct *conn, { int outsize = 0; files_struct *fsp; + NTSTATUS status; + START_PROFILE(SMBsplopen); if (!CAN_PRINT(conn)) { @@ -3606,11 +3602,11 @@ int reply_printopen(connection_struct *conn, } /* Open for exclusive use, write only. */ - fsp = print_fsp_open(conn, NULL); + status = print_fsp_open(conn, NULL, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBsplopen); - return(UNIXERROR(ERRDOS,ERRnoaccess)); + return(ERROR_NT(status)); } outsize = set_message(outbuf,1,0,True); @@ -3838,6 +3834,17 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, status = mkdir_internal(conn, directory,bad_path); if (!NT_STATUS_IS_OK(status)) { + + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION) && + !use_nt_status()) { + /* + * Yes, in the DOS error code case we get a + * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR + * samba4 torture test. + */ + status = NT_STATUS_DOS(ERRDOS, ERRnoaccess); + } + END_PROFILE(SMBmkdir); return ERROR_NT(status); } @@ -4408,14 +4415,14 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui * Tine Smukavec <valentin.smukavec@hermes.si>. */ - if (!rc && mangle_is_mangled(mask,SNUM(conn))) - mangle_check_cache( mask, sizeof(pstring)-1, SNUM(conn)); + if (!rc && mangle_is_mangled(mask, conn->params)) + mangle_check_cache( mask, sizeof(pstring)-1, conn->params ); if (!has_wild) { /* * No wildcards - just process the one file. */ - BOOL is_short_name = mangle_is_8_3(name, True, SNUM(conn)); + BOOL is_short_name = mangle_is_8_3(name, True, conn->params); /* Add a terminating '/' to the directory name. */ pstrcat(directory,"/"); @@ -4739,6 +4746,7 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, pstring dest; uint32 dosattrs; uint32 new_create_disposition; + NTSTATUS status; *err_ret = 0; @@ -4767,16 +4775,16 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } } - fsp1 = open_file_ntcreate(conn,src,&src_sbuf, + status = open_file_ntcreate(conn,src,&src_sbuf, FILE_GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - NULL); + NULL, &fsp1); - if (!fsp1) { + if (!NT_STATUS_IS_OK(status)) { return(False); } @@ -4785,16 +4793,16 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, ZERO_STRUCTP(&sbuf2); } - fsp2 = open_file_ntcreate(conn,dest,&sbuf2, + status = open_file_ntcreate(conn,dest,&sbuf2, FILE_GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, new_create_disposition, 0, dosattrs, INTERNAL_OPEN_ONLY, - NULL); + NULL, &fsp2); - if (!fsp2) { + if (!NT_STATUS_IS_OK(status)) { close_file(fsp1,ERROR_CLOSE); return(False); } @@ -4926,8 +4934,8 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, * Tine Smukavec <valentin.smukavec@hermes.si>. */ - if (!rc && mangle_is_mangled(mask, SNUM(conn))) - mangle_check_cache( mask, sizeof(pstring)-1, SNUM(conn)); + if (!rc && mangle_is_mangled(mask, conn->params)) + mangle_check_cache( mask, sizeof(pstring)-1, conn->params ); has_wild = path_contains_wcard1; @@ -4995,8 +5003,12 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, END_PROFILE(SMBcopy); return ERROR_DOS(ERRDOS,error); } else { - if((errno == ENOENT) && (bad_path1 || bad_path2)) { - set_saved_error_triple(ERRDOS, ERRbadpath, NT_STATUS_OK); + if((errno == ENOENT) && (bad_path1 || bad_path2) && + !use_nt_status()) { + /* Samba 3.0.22 has ERRDOS/ERRbadpath in the + * DOS error code case + */ + return ERROR_DOS(ERRDOS, ERRbadpath); } END_PROFILE(SMBcopy); return(UNIXERROR(ERRDOS,error)); @@ -5067,12 +5079,12 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size Get a lock pid, dealing with large count requests. ****************************************************************************/ -uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format) +uint32 get_lock_pid( char *data, int data_offset, BOOL large_file_format) { if(!large_file_format) - return SVAL(data,SMB_LPID_OFFSET(data_offset)); + return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset)); else - return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset)); + return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset)); } /**************************************************************************** @@ -5209,7 +5221,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf, uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = 0, offset = 0; - uint16 lock_pid; + uint32 lock_pid; int32 lock_timeout = IVAL(inbuf,smb_vwv4); int i; char *data; @@ -5229,7 +5241,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf, /* we don't support these - and CANCEL_LOCK makes w2k and XP reboot so I don't really want to be compatible! (tridge) */ - return ERROR_FORCE_DOS(ERRDOS, ERRnoatomiclocks); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks)); } if (locktype & LOCKING_ANDX_CANCEL_LOCK) { @@ -5505,7 +5517,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, tcount = maxcount; total_read = 0; - if (is_locked(fsp,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { END_PROFILE(SMBreadBmpx); return ERROR_DOS(ERRDOS,ERRlock); } @@ -5637,7 +5649,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, not an SMBwritebmpx - set this up now so we don't forget */ SCVAL(outbuf,smb_com,SMBwritec); - if (is_locked(fsp,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) { END_PROFILE(SMBwriteBmpx); return(ERROR_DOS(ERRDOS,ERRlock)); } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 2bfeae9f54..0fba6af697 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -912,18 +912,12 @@ void build_options(BOOL screen); if (!message_init()) exit(1); - /* Initialize our global sam sid first -- quite a lot of the other - * initialization routines further down depend on it. - */ - /* Initialise the password backed before the global_sam_sid to ensure that we fetch from ldap before we make a domain sid up */ if(!initialize_password_db(False)) exit(1); - /* Fail gracefully if we can't open secrets.tdb */ - if (!secrets_init()) { DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n")); exit(1); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index cb9bfcc27a..9dcb8a354f 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -371,35 +371,38 @@ static NTSTATUS find_forced_user(int snum, BOOL vuser_is_guest, { TALLOC_CTX *mem_ctx; char *fuser, *found_username; + struct nt_user_token *tmp_token; NTSTATUS result; - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { + if (!(mem_ctx = talloc_new(NULL))) { DEBUG(0, ("talloc_new failed\n")); return NT_STATUS_NO_MEMORY; } - fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S", - lp_servicename(snum)); - if (fuser == NULL) { - result = NT_STATUS_NO_MEMORY; - goto done; + if (!(fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S", + lp_servicename(snum)))) { + TALLOC_FREE(mem_ctx); + return NT_STATUS_NO_MEMORY; + } result = create_token_from_username(mem_ctx, fuser, vuser_is_guest, uid, gid, &found_username, - token); + &tmp_token); if (!NT_STATUS_IS_OK(result)) { - goto done; + TALLOC_FREE(mem_ctx); + return result; + } + + if (!(*token = dup_nt_token(NULL, tmp_token))) { + TALLOC_FREE(mem_ctx); + return NT_STATUS_NO_MEMORY; } - talloc_steal(NULL, *token); fstrcpy(username, found_username); - result = NT_STATUS_OK; - done: TALLOC_FREE(mem_ctx); - return result; + return NT_STATUS_OK; } /* @@ -620,7 +623,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, sizeof(conn->client_address)-1); conn->num_files_open = 0; conn->lastused = conn->lastused_count = time(NULL); - conn->service = snum; + conn->params->service = snum; conn->used = True; conn->printer = (strncmp(dev,"LPT",3) == 0); conn->ipc = ( (strncmp(dev,"IPC",3) == 0) || @@ -646,7 +649,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, string_set(&conn->dirpath,""); string_set(&conn->user,user); - conn->read_only = lp_readonly(conn->service); + conn->read_only = lp_readonly(SNUM(conn)); conn->admin_user = False; /* @@ -746,7 +749,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, { pstring s; pstrcpy(s,lp_pathname(snum)); - standard_sub_conn(conn,s,sizeof(s)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + s, sizeof(s)); set_conn_connectpath(conn,s); DEBUG(3,("Connect path is '%s' for service [%s]\n",s, lp_servicename(snum))); @@ -821,7 +828,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if (*lp_rootpreexec(snum)) { pstring cmd; pstrcpy(cmd,lp_rootpreexec(snum)); - standard_sub_conn(conn,cmd,sizeof(cmd)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + cmd, sizeof(cmd)); DEBUG(5,("cmd=%s\n",cmd)); ret = smbrun(cmd,NULL); if (ret != 0 && lp_rootpreexec_close(snum)) { @@ -854,7 +865,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if (*lp_preexec(snum)) { pstring cmd; pstrcpy(cmd,lp_preexec(snum)); - standard_sub_conn(conn,cmd,sizeof(cmd)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + cmd, sizeof(cmd)); ret = smbrun(cmd,NULL); if (ret != 0 && lp_preexec_close(snum)) { DEBUG(1,("preexec gave %d - failing connection\n", @@ -1148,7 +1163,11 @@ void close_cnum(connection_struct *conn, uint16 vuid) change_to_user(conn, vuid)) { pstring cmd; pstrcpy(cmd,lp_postexec(SNUM(conn))); - standard_sub_conn(conn,cmd,sizeof(cmd)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + cmd, sizeof(cmd)); smbrun(cmd,NULL); change_to_root_user(); } @@ -1158,7 +1177,11 @@ void close_cnum(connection_struct *conn, uint16 vuid) if (*lp_rootpostexec(SNUM(conn))) { pstring cmd; pstrcpy(cmd,lp_rootpostexec(SNUM(conn))); - standard_sub_conn(conn,cmd,sizeof(cmd)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + cmd, sizeof(cmd)); smbrun(cmd,NULL); } diff --git a/source3/smbd/session.c b/source3/smbd/session.c index 41f8fd0ed4..bcb840a3fe 100644 --- a/source3/smbd/session.c +++ b/source3/smbd/session.c @@ -1,8 +1,10 @@ /* Unix SMB/CIFS implementation. session handling for utmp and PAM - Copyright (C) tridge@samba.org 2001 - Copyright (C) abartlet@pcug.org.au 2001 + + Copyright (C) tridge@samba.org 2001 + Copyright (C) abartlet@samba.org 2001 + Copyright (C) Gerald (Jerry) Carter 2006 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 @@ -29,6 +31,9 @@ static TDB_CONTEXT *tdb; +/******************************************************************** +********************************************************************/ + BOOL session_init(void) { if (tdb) @@ -44,7 +49,10 @@ BOOL session_init(void) return True; } -/* called when a session is created */ +/******************************************************************** + called when a session is created +********************************************************************/ + BOOL session_claim(user_struct *vuser) { int i = 0; @@ -126,6 +134,7 @@ BOOL session_claim(user_struct *vuser) sessionid.gid = vuser->gid; fstrcpy(sessionid.remote_machine, get_remote_machine_name()); fstrcpy(sessionid.ip_addr, client_addr()); + sessionid.connect_start = time(NULL); client_ip = client_inaddr(&sa); @@ -159,7 +168,10 @@ BOOL session_claim(user_struct *vuser) return True; } -/* called when a session is destroyed */ +/******************************************************************** + called when a session is destroyed +********************************************************************/ + void session_yield(user_struct *vuser) { TDB_DATA dbuf; @@ -198,6 +210,9 @@ void session_yield(user_struct *vuser) tdb_delete(tdb, key); } +/******************************************************************** +********************************************************************/ + BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *), void *state) { @@ -210,32 +225,40 @@ BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *), return True; } +/******************************************************************** +********************************************************************/ + struct session_list { int count; struct sessionid *sessions; }; -static int gather_sessioninfo(TDB_CONTEXT *stdb, TDB_DATA kbuf, TDB_DATA dbuf, - void *state) +static int gather_sessioninfo(TDB_CONTEXT *stdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { + uint32 i; struct session_list *sesslist = (struct session_list *) state; const struct sessionid *current = (const struct sessionid *) dbuf.dptr; - sesslist->count += 1; - sesslist->sessions = SMB_REALLOC_ARRAY(sesslist->sessions, struct sessionid, - sesslist->count); + i = sesslist->count; + + sesslist->sessions = SMB_REALLOC_ARRAY(sesslist->sessions, struct sessionid, i+1); if (!sesslist->sessions) { sesslist->count = 0; return -1; } - memcpy(&sesslist->sessions[sesslist->count - 1], current, - sizeof(struct sessionid)); + memcpy(&sesslist->sessions[i], current, sizeof(struct sessionid)); + sesslist->count++; + DEBUG(7,("gather_sessioninfo session from %s@%s\n", current->username, current->remote_machine)); + return 0; } +/******************************************************************** +********************************************************************/ + int list_sessions(struct sessionid **session_list) { struct session_list sesslist; diff --git a/source3/smbd/share_access.c b/source3/smbd/share_access.c index 468f61560b..5334976d8d 100644 --- a/source3/smbd/share_access.c +++ b/source3/smbd/share_access.c @@ -28,6 +28,8 @@ * + and & may be combined */ +extern userdom_struct current_user_info; + static BOOL do_group_checks(const char **name, const char **pattern) { if ((*name)[0] == '@') { @@ -74,7 +76,8 @@ static BOOL token_contains_name(TALLOC_CTX *mem_ctx, enum SID_NAME_USE type; if (username != NULL) { - name = talloc_sub_basic(mem_ctx, username, name); + name = talloc_sub_basic(mem_ctx, username, + current_user_info.domain, name); } if (sharename != NULL) { name = talloc_string_sub(mem_ctx, name, "%S", sharename); diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c index 548d7c4a48..b453fdd544 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -52,7 +52,7 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat if (!lp_stat_cache()) return; - if (sc_size && (tdb_stat_cache->map_size > sc_size*1024)) { + if (sc_size && (tdb_map_size(tdb_stat_cache) > sc_size*1024)) { reset_stat_cache(); } @@ -291,12 +291,12 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath, JRA. Use a djb-algorithm hash for speed. ***************************************************************/ -u32 fast_string_hash(TDB_DATA *key) +unsigned int fast_string_hash(TDB_DATA *key) { - u32 n = 0; + unsigned int n = 0; const char *p; for (p = key->dptr; *p != '\0'; p++) { - n = ((n << 5) + n) ^ (u32)(*p); + n = ((n << 5) + n) ^ (unsigned int)(*p); } return n; } diff --git a/source3/smbd/statvfs.c b/source3/smbd/statvfs.c index 8f981a6328..300b14a7c0 100644 --- a/source3/smbd/statvfs.c +++ b/source3/smbd/statvfs.c @@ -21,7 +21,7 @@ #include "includes.h" -#if defined(LINUX) +#if defined(LINUX) && defined(HAVE_FSID_INT) static int linux_statvfs(const char *path, vfs_statvfs_struct *statbuf) { struct statvfs statvfs_buf; @@ -51,7 +51,7 @@ static int linux_statvfs(const char *path, vfs_statvfs_struct *statbuf) */ int sys_statvfs(const char *path, vfs_statvfs_struct *statbuf) { -#if defined(LINUX) +#if defined(LINUX) && defined(HAVE_FSID_INT) return linux_statvfs(path, statbuf); #else /* BB change this to return invalid level */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 9030737b1b..aca1fcd70e 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -837,16 +837,16 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_mode, create_disposition, create_options, open_attr, oplock_request, - &smb_action); + &smb_action, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { talloc_destroy(ctx); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ @@ -1070,7 +1070,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, BOOL was_8_3; uint32 nt_extmode; /* Used for NT connections instead of mode */ BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); - BOOL check_mangled_names = lp_manglednames(SNUM(conn)); + BOOL check_mangled_names = lp_manglednames(conn->params); *fname = 0; *out_of_space = False; @@ -1117,7 +1117,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive))) got_match = mask_match(fname, mask, conn->case_sensitive); - if(!got_match && check_mangled_names && !mangle_is_8_3(fname, False, SNUM(conn))) { + if(!got_match && check_mangled_names && + !mangle_is_8_3(fname, False, conn->params)) { /* * It turns out that NT matches wildcards against @@ -1128,7 +1129,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, pstring newname; pstrcpy( newname, fname); - mangle_map( newname, True, False, SNUM(conn)); + mangle_map( newname, True, False, conn->params); if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive))) got_match = mask_match(newname, mask, conn->case_sensitive); } @@ -1202,7 +1203,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, } } - mangle_map(fname,False,True,SNUM(conn)); + mangle_map(fname,False,True,conn->params); p = pdata; last_entry_ptr = p; @@ -1338,7 +1339,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n")); - was_8_3 = mangle_is_8_3(fname, True, SNUM(conn)); + was_8_3 = mangle_is_8_3(fname, True, conn->params); p += 4; SIVAL(p,0,reskey); p += 4; put_long_date(p,cdate); p += 8; @@ -1361,7 +1362,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, if (!was_8_3 && check_mangled_names) { pstring mangled_name; pstrcpy(mangled_name, fname); - mangle_map(mangled_name,True,True,SNUM(conn)); + mangle_map(mangled_name,True,True, + conn->params); mangled_name[12] = 0; len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); if (len < 24) { @@ -1480,7 +1482,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, case SMB_FIND_ID_BOTH_DIRECTORY_INFO: DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n")); - was_8_3 = mangle_is_8_3(fname, True, SNUM(conn)); + was_8_3 = mangle_is_8_3(fname, True, conn->params); p += 4; SIVAL(p,0,reskey); p += 4; put_long_date(p,cdate); p += 8; @@ -1503,7 +1505,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, if (!was_8_3 && check_mangled_names) { pstring mangled_name; pstrcpy(mangled_name, fname); - mangle_map(mangled_name,True,True,SNUM(conn)); + mangle_map(mangled_name,True,True, + conn->params); mangled_name[12] = 0; len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); SSVAL(p, 0, len); @@ -1871,8 +1874,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd * (see PR#13758). JRA. */ - if(!mangle_is_8_3_wildcards( mask, False, SNUM(conn))) - mangle_map(mask, True, True, SNUM(conn)); + if(!mangle_is_8_3_wildcards( mask, False, conn->params)) + mangle_map(mask, True, True, conn->params); return(-1); } @@ -2068,8 +2071,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd * could be mangled. Ensure we check the unmangled name. */ - if (mangle_is_mangled(resume_name, SNUM(conn))) { - mangle_check_cache(resume_name, sizeof(resume_name)-1, SNUM(conn)); + if (mangle_is_mangled(resume_name, conn->params)) { + mangle_check_cache(resume_name, sizeof(resume_name)-1, + conn->params); } /* @@ -2441,17 +2445,10 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION); SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION); /* We have POSIX ACLs, pathname and locking capability. */ -#if defined(DEVELOPER) /* Not quite finished yet... */ SBIG_UINT(pdata,4,((SMB_BIG_UINT)( CIFS_UNIX_POSIX_ACLS_CAP| CIFS_UNIX_POSIX_PATHNAMES_CAP| CIFS_UNIX_FCNTL_LOCKS_CAP))); -#else - SBIG_UINT(pdata,4,((SMB_BIG_UINT)( - CIFS_UNIX_POSIX_ACLS_CAP| - CIFS_UNIX_POSIX_PATHNAMES_CAP| - 0))); -#endif break; case SMB_QUERY_POSIX_FS_INFO: @@ -2567,11 +2564,10 @@ cap_low = 0x%x, cap_high = 0x%x\n", lp_set_posix_pathnames(); mangle_change_to_posix(); } -#if defined(DEVELOPER) + if (client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) { lp_set_posix_cifsx_locktype(POSIX_LOCK); } -#endif break; } case SMB_FS_QUOTA_INFORMATION: @@ -2832,9 +2828,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char * TALLOC_CTX *data_ctx = NULL; struct ea_list *ea_list = NULL; uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ -#if defined(DEVELOPER) char *lock_data = NULL; -#endif if (!params) return ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -3006,7 +3000,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } break; } -#if defined(DEVELOPER) + case SMB_QUERY_POSIX_LOCK: { if (fsp == NULL || fsp->fh->fd == -1) { @@ -3028,7 +3022,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd return ERROR_NT(NT_STATUS_NO_MEMORY); } } -#endif default: break; } @@ -3229,8 +3222,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n")); pstrcpy(short_name,base_name); /* Mangle if not already 8.3 */ - if(!mangle_is_8_3(short_name, True, SNUM(conn))) { - mangle_map(short_name,True,True,SNUM(conn)); + if(!mangle_is_8_3(short_name, True, conn->params)) { + mangle_map(short_name,True,True,conn->params); } len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE); data_size = 4 + len; @@ -3448,7 +3441,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd { int i; - DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC")); + DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC ")); for (i=0; i<100; i++) DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); @@ -3559,13 +3552,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd #endif -#if defined(DEVELOPER) case SMB_QUERY_POSIX_LOCK: { NTSTATUS status = NT_STATUS_INVALID_LEVEL; SMB_BIG_UINT count; SMB_BIG_UINT offset; - uint16 lock_pid; + uint32 lock_pid; enum brl_type lock_type; if (total_data != POSIX_LOCK_DATA_SIZE) { @@ -3586,7 +3578,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - lock_pid = (uint16)IVAL(pdata, POSIX_LOCK_PID_OFFSET); + 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)); @@ -3632,7 +3624,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } break; } -#endif default: return ERROR_NT(NT_STATUS_INVALID_LEVEL); @@ -4030,16 +4021,16 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char if (fd == -1) { files_struct *new_fsp = NULL; - new_fsp = open_file_ntcreate(conn, fname, &sbuf, + status = open_file_ntcreate(conn, fname, &sbuf, FILE_WRITE_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, FORCE_OPLOCK_BREAK_TO_NONE, - NULL); + NULL, &new_fsp); - if (new_fsp == NULL) { + if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; @@ -4404,7 +4395,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", case SMB_FILE_RENAME_INFORMATION: { BOOL overwrite; - uint32 root_fid; + /* uint32 root_fid; */ /* Not used */ uint32 len; pstring newname; pstring base_name; @@ -4415,7 +4406,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } overwrite = (CVAL(pdata,0) ? True : False); - root_fid = IVAL(pdata,4); + /* root_fid = IVAL(pdata,4); */ len = IVAL(pdata,8); srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status); if (!NT_STATUS_IS_OK(status)) { @@ -4507,12 +4498,11 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } #endif -#if defined(DEVELOPER) case SMB_SET_POSIX_LOCK: { SMB_BIG_UINT count; SMB_BIG_UINT offset; - uint16 lock_pid; + uint32 lock_pid; BOOL lock_blocking; enum brl_type lock_type; BOOL my_lock_ctx; @@ -4551,7 +4541,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - lock_pid = (uint16)IVAL(pdata, POSIX_LOCK_PID_OFFSET); + 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)); @@ -4605,7 +4595,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); return(-1); } -#endif default: return ERROR_NT(NT_STATUS_INVALID_LEVEL); @@ -4673,16 +4662,16 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (fd == -1) { files_struct *new_fsp = NULL; - new_fsp = open_file_ntcreate(conn, fname, &sbuf, + status = open_file_ntcreate(conn, fname, &sbuf, FILE_WRITE_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, FORCE_OPLOCK_BREAK_TO_NONE, - NULL); + NULL, &new_fsp); - if (new_fsp == NULL) { + if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c62c9d928a..48d7f590c3 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -102,7 +102,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) readonly_share = is_share_read_only_for_token(vuser->user.unix_name, vuser->nt_user_token, - conn->service); + SNUM(conn)); if (!readonly_share && !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) { @@ -129,7 +129,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) ent->admin_user = token_contains_name_in_list( vuser->user.unix_name, NULL, vuser->nt_user_token, - lp_admin_users(conn->service)); + lp_admin_users(SNUM(conn))); conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c deleted file mode 100644 index ee251c17d8..0000000000 --- a/source3/smbd/vfs-wrap.c +++ /dev/null @@ -1,1104 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Wrap disk only vfs functions to sidestep dodgy compilers. - Copyright (C) Tim Potter 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 2 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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_VFS - - -/* Check for NULL pointer parameters in vfswrap_* functions */ - -/* We don't want to have NULL function pointers lying around. Someone - is sure to try and execute them. These stubs are used to prevent - this possibility. */ - -int vfswrap_dummy_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user) -{ - return 0; /* Return >= 0 for success */ -} - -void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn) -{ -} - -/* Disk operations */ - -SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, - SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) -{ - SMB_BIG_UINT result; - - result = sys_disk_free(conn, path, small_query, bsize, dfree, dsize); - return result; -} - -int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) -{ -#ifdef HAVE_SYS_QUOTAS - int result; - - START_PROFILE(syscall_get_quota); - result = sys_get_quota(conn->connectpath, qtype, id, qt); - END_PROFILE(syscall_get_quota); - return result; -#else - errno = ENOSYS; - return -1; -#endif -} - -int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) -{ -#ifdef HAVE_SYS_QUOTAS - int result; - - START_PROFILE(syscall_set_quota); - result = sys_set_quota(conn->connectpath, qtype, id, qt); - END_PROFILE(syscall_set_quota); - return result; -#else - errno = ENOSYS; - return -1; -#endif -} - -int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels) -{ - errno = ENOSYS; - return -1; /* Not implemented. */ -} - -int vfswrap_statvfs(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, vfs_statvfs_struct *statbuf) -{ - return sys_statvfs(path, statbuf); -} - -/* Directory operations */ - -SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) -{ - SMB_STRUCT_DIR *result; - - START_PROFILE(syscall_opendir); - result = sys_opendir(fname); - END_PROFILE(syscall_opendir); - return result; -} - -SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) -{ - SMB_STRUCT_DIRENT *result; - - START_PROFILE(syscall_readdir); - result = sys_readdir(dirp); - END_PROFILE(syscall_readdir); - return result; -} - -void vfswrap_seekdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp, long offset) -{ - START_PROFILE(syscall_seekdir); - sys_seekdir(dirp, offset); - END_PROFILE(syscall_seekdir); -} - -long vfswrap_telldir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) -{ - long result; - START_PROFILE(syscall_telldir); - result = sys_telldir(dirp); - END_PROFILE(syscall_telldir); - return result; -} - -void vfswrap_rewinddir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) -{ - START_PROFILE(syscall_rewinddir); - sys_rewinddir(dirp); - END_PROFILE(syscall_rewinddir); -} - -int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) -{ - int result; - BOOL has_dacl = False; - - START_PROFILE(syscall_mkdir); - - if (lp_inherit_acls(SNUM(conn)) && (has_dacl = directory_has_default_acl(conn, parent_dirname(path)))) - mode = 0777; - - result = mkdir(path, mode); - - if (result == 0 && !has_dacl) { - /* - * We need to do this as the default behavior of POSIX ACLs - * is to set the mask to be the requested group permission - * bits, not the group permission bits to be the requested - * group permission bits. This is not what we want, as it will - * mess up any inherited ACL bits that were set. JRA. - */ - int saved_errno = errno; /* We may get ENOSYS */ - if ((SMB_VFS_CHMOD_ACL(conn, path, mode) == -1) && (errno == ENOSYS)) - errno = saved_errno; - } - - END_PROFILE(syscall_mkdir); - return result; -} - -int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) -{ - int result; - - START_PROFILE(syscall_rmdir); - result = rmdir(path); - END_PROFILE(syscall_rmdir); - return result; -} - -int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) -{ - int result; - - START_PROFILE(syscall_closedir); - result = sys_closedir(dirp); - END_PROFILE(syscall_closedir); - return result; -} - -/* File operations */ - -int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) -{ - int result; - - START_PROFILE(syscall_open); - result = sys_open(fname, flags, mode); - END_PROFILE(syscall_open); - return result; -} - -int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd) -{ - int result; - - START_PROFILE(syscall_close); - - result = close(fd); - END_PROFILE(syscall_close); - return result; -} - -ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n) -{ - ssize_t result; - - START_PROFILE_BYTES(syscall_read, n); - result = sys_read(fd, data, n); - END_PROFILE(syscall_read); - return result; -} - -ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, - size_t n, SMB_OFF_T offset) -{ - ssize_t result; - -#if defined(HAVE_PREAD) || defined(HAVE_PREAD64) - START_PROFILE_BYTES(syscall_pread, n); - result = sys_pread(fd, data, n, offset); - END_PROFILE(syscall_pread); - - if (result == -1 && errno == ESPIPE) { - /* Maintain the fiction that pipes can be seeked (sought?) on. */ - result = SMB_VFS_READ(fsp, fd, data, n); - fsp->fh->pos = 0; - } - -#else /* HAVE_PREAD */ - SMB_OFF_T curr; - int lerrno; - - curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); - if (curr == -1 && errno == ESPIPE) { - /* Maintain the fiction that pipes can be seeked (sought?) on. */ - result = SMB_VFS_READ(fsp, fd, data, n); - fsp->fh->pos = 0; - return result; - } - - if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { - return -1; - } - - errno = 0; - result = SMB_VFS_READ(fsp, fd, data, n); - lerrno = errno; - - SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); - errno = lerrno; - -#endif /* HAVE_PREAD */ - - return result; -} - -ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n) -{ - ssize_t result; - - START_PROFILE_BYTES(syscall_write, n); - result = sys_write(fd, data, n); - END_PROFILE(syscall_write); - return result; -} - -ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, - size_t n, SMB_OFF_T offset) -{ - ssize_t result; - -#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64) - START_PROFILE_BYTES(syscall_pwrite, n); - result = sys_pwrite(fd, data, n, offset); - END_PROFILE(syscall_pwrite); - - if (result == -1 && errno == ESPIPE) { - /* Maintain the fiction that pipes can be sought on. */ - result = SMB_VFS_WRITE(fsp, fd, data, n); - } - -#else /* HAVE_PWRITE */ - SMB_OFF_T curr; - int lerrno; - - curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); - if (curr == -1) { - return -1; - } - - if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { - return -1; - } - - result = SMB_VFS_WRITE(fsp, fd, data, n); - lerrno = errno; - - SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); - errno = lerrno; - -#endif /* HAVE_PWRITE */ - - return result; -} - -SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) -{ - SMB_OFF_T result = 0; - - START_PROFILE(syscall_lseek); - - /* Cope with 'stat' file opens. */ - if (filedes != -1) - result = sys_lseek(filedes, offset, whence); - - /* - * We want to maintain the fiction that we can seek - * on a fifo for file system purposes. This allows - * people to set up UNIX fifo's that feed data to Windows - * applications. JRA. - */ - - if((result == -1) && (errno == ESPIPE)) { - result = 0; - errno = 0; - } - - END_PROFILE(syscall_lseek); - return result; -} - -ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr, - SMB_OFF_T offset, size_t n) -{ - ssize_t result; - - START_PROFILE_BYTES(syscall_sendfile, n); - result = sys_sendfile(tofd, fromfd, hdr, offset, n); - END_PROFILE(syscall_sendfile); - return result; -} - -/********************************************************* - For rename across filesystems Patch from Warren Birnbaum - <warrenb@hpcvscdp.cv.hp.com> -**********************************************************/ - -static int copy_reg(const char *source, const char *dest) -{ - SMB_STRUCT_STAT source_stats; - int saved_errno; - int ifd = -1; - int ofd = -1; - - if (sys_lstat (source, &source_stats) == -1) - return -1; - - if (!S_ISREG (source_stats.st_mode)) - return -1; - - if((ifd = sys_open (source, O_RDONLY, 0)) < 0) - return -1; - - if (unlink (dest) && errno != ENOENT) - return -1; - -#ifdef O_NOFOLLOW - if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 ) -#else - if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 ) -#endif - goto err; - - if (transfer_file(ifd, ofd, (size_t)-1) == -1) - goto err; - - /* - * Try to preserve ownership. For non-root it might fail, but that's ok. - * But root probably wants to know, e.g. if NFS disallows it. - */ - -#ifdef HAVE_FCHOWN - if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) -#else - if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) -#endif - goto err; - - /* - * fchown turns off set[ug]id bits for non-root, - * so do the chmod last. - */ - -#if defined(HAVE_FCHMOD) - if (fchmod (ofd, source_stats.st_mode & 07777)) -#else - if (chmod (dest, source_stats.st_mode & 07777)) -#endif - goto err; - - if (close (ifd) == -1) - goto err; - - if (close (ofd) == -1) - return -1; - - /* Try to copy the old file's modtime and access time. */ - { - struct utimbuf tv; - - tv.actime = source_stats.st_atime; - tv.modtime = source_stats.st_mtime; - utime(dest, &tv); - } - - if (unlink (source) == -1) - return -1; - - return 0; - - err: - - saved_errno = errno; - if (ifd != -1) - close(ifd); - if (ofd != -1) - close(ofd); - errno = saved_errno; - return -1; -} - -int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) -{ - int result; - - START_PROFILE(syscall_rename); - result = rename(oldname, newname); - if (errno == EXDEV) { - /* Rename across filesystems needed. */ - result = copy_reg(oldname, newname); - } - - END_PROFILE(syscall_rename); - return result; -} - -int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) -{ -#ifdef HAVE_FSYNC - int result; - - START_PROFILE(syscall_fsync); - result = fsync(fd); - END_PROFILE(syscall_fsync); - return result; -#else - return 0; -#endif -} - -int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) -{ - int result; - - START_PROFILE(syscall_stat); - result = sys_stat(fname, sbuf); - END_PROFILE(syscall_stat); - return result; -} - -int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) -{ - int result; - - START_PROFILE(syscall_fstat); - result = sys_fstat(fd, sbuf); - END_PROFILE(syscall_fstat); - return result; -} - -int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) -{ - int result; - - START_PROFILE(syscall_lstat); - result = sys_lstat(path, sbuf); - END_PROFILE(syscall_lstat); - return result; -} - -int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) -{ - int result; - - START_PROFILE(syscall_unlink); - result = unlink(path); - END_PROFILE(syscall_unlink); - return result; -} - -int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) -{ - int result; - - START_PROFILE(syscall_chmod); - - /* - * We need to do this due to the fact that the default POSIX ACL - * chmod modifies the ACL *mask* for the group owner, not the - * group owner bits directly. JRA. - */ - - - { - int saved_errno = errno; /* We might get ENOSYS */ - if ((result = SMB_VFS_CHMOD_ACL(conn, path, mode)) == 0) { - END_PROFILE(syscall_chmod); - return result; - } - /* Error - return the old errno. */ - errno = saved_errno; - } - - result = chmod(path, mode); - END_PROFILE(syscall_chmod); - return result; -} - -int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) -{ - int result; - - START_PROFILE(syscall_fchmod); - - /* - * We need to do this due to the fact that the default POSIX ACL - * chmod modifies the ACL *mask* for the group owner, not the - * group owner bits directly. JRA. - */ - - { - int saved_errno = errno; /* We might get ENOSYS */ - if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) { - END_PROFILE(syscall_fchmod); - return result; - } - /* Error - return the old errno. */ - errno = saved_errno; - } - -#if defined(HAVE_FCHMOD) - result = fchmod(fd, mode); -#else - result = -1; - errno = ENOSYS; -#endif - - END_PROFILE(syscall_fchmod); - return result; -} - -int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid) -{ - int result; - - START_PROFILE(syscall_chown); - result = sys_chown(path, uid, gid); - END_PROFILE(syscall_chown); - return result; -} - -int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid) -{ -#ifdef HAVE_FCHOWN - int result; - - START_PROFILE(syscall_fchown); - result = fchown(fd, uid, gid); - END_PROFILE(syscall_fchown); - return result; -#else - errno = ENOSYS; - return -1; -#endif -} - -int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) -{ - int result; - - START_PROFILE(syscall_chdir); - result = chdir(path); - END_PROFILE(syscall_chdir); - return result; -} - -char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path) -{ - char *result; - - START_PROFILE(syscall_getwd); - result = sys_getwd(path); - END_PROFILE(syscall_getwd); - return result; -} - -int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times) -{ - int result; - - START_PROFILE(syscall_utime); - result = utime(path, times); - END_PROFILE(syscall_utime); - return result; -} - -/********************************************************************* - A version of ftruncate that will write the space on disk if strict - allocate is set. -**********************************************************************/ - -static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) -{ - SMB_STRUCT_STAT st; - SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); - unsigned char zero_space[4096]; - SMB_OFF_T space_to_write; - - if (currpos == -1) - return -1; - - if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) - return -1; - - space_to_write = len - st.st_size; - -#ifdef S_ISFIFO - if (S_ISFIFO(st.st_mode)) - return 0; -#endif - - if (st.st_size == len) - return 0; - - /* Shrink - just ftruncate. */ - if (st.st_size > len) - return sys_ftruncate(fd, len); - - /* Write out the real space on disk. */ - if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size) - return -1; - - space_to_write = len - st.st_size; - - memset(zero_space, '\0', sizeof(zero_space)); - while ( space_to_write > 0) { - SMB_OFF_T retlen; - SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write); - - retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write); - if (retlen <= 0) - return -1; - - space_to_write -= retlen; - } - - /* Seek to where we were */ - if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) - return -1; - - return 0; -} - -int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) -{ - int result = -1; - SMB_STRUCT_STAT st; - char c = 0; - SMB_OFF_T currpos; - - START_PROFILE(syscall_ftruncate); - - if (lp_strict_allocate(SNUM(fsp->conn))) { - result = strict_allocate_ftruncate(handle, fsp, fd, len); - END_PROFILE(syscall_ftruncate); - return result; - } - - /* we used to just check HAVE_FTRUNCATE_EXTEND and only use - sys_ftruncate if the system supports it. Then I discovered that - you can have some filesystems that support ftruncate - expansion and some that don't! On Linux fat can't do - ftruncate extend but ext2 can. */ - - result = sys_ftruncate(fd, len); - if (result == 0) - goto done; - - /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot - extend a file with ftruncate. Provide alternate implementation - for this */ - currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); - if (currpos == -1) { - goto done; - } - - /* Do an fstat to see if the file is longer than the requested - size in which case the ftruncate above should have - succeeded or shorter, in which case seek to len - 1 and - write 1 byte of zero */ - if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) { - goto done; - } - -#ifdef S_ISFIFO - if (S_ISFIFO(st.st_mode)) { - result = 0; - goto done; - } -#endif - - if (st.st_size == len) { - result = 0; - goto done; - } - - if (st.st_size > len) { - /* the sys_ftruncate should have worked */ - goto done; - } - - if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1) - goto done; - - if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1) - goto done; - - /* Seek to where we were */ - if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) - goto done; - result = 0; - - done: - - END_PROFILE(syscall_ftruncate); - return result; -} - -BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) -{ - BOOL result; - - START_PROFILE(syscall_fcntl_lock); - result = fcntl_lock(fd, op, offset, count, type); - END_PROFILE(syscall_fcntl_lock); - return result; -} - -BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid) -{ - BOOL result; - - START_PROFILE(syscall_fcntl_getlock); - result = fcntl_getlock(fd, poffset, pcount, ptype, ppid); - END_PROFILE(syscall_fcntl_getlock); - return result; -} - -int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) -{ - int result; - - START_PROFILE(syscall_symlink); - result = sys_symlink(oldpath, newpath); - END_PROFILE(syscall_symlink); - return result; -} - -int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) -{ - int result; - - START_PROFILE(syscall_readlink); - result = sys_readlink(path, buf, bufsiz); - END_PROFILE(syscall_readlink); - return result; -} - -int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) -{ - int result; - - START_PROFILE(syscall_link); - result = sys_link(oldpath, newpath); - END_PROFILE(syscall_link); - return result; -} - -int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev) -{ - int result; - - START_PROFILE(syscall_mknod); - result = sys_mknod(pathname, mode, dev); - END_PROFILE(syscall_mknod); - return result; -} - -char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path) -{ - char *result; - - START_PROFILE(syscall_realpath); - result = sys_realpath(path, resolved_path); - END_PROFILE(syscall_realpath); - return result; -} - -size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc) -{ - size_t result; - - START_PROFILE(fget_nt_acl); - result = get_nt_acl(fsp, security_info, ppdesc); - END_PROFILE(fget_nt_acl); - return result; -} - -size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc) -{ - size_t result; - - START_PROFILE(get_nt_acl); - result = get_nt_acl(fsp, security_info, ppdesc); - END_PROFILE(get_nt_acl); - return result; -} - -BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) -{ - BOOL result; - - START_PROFILE(fset_nt_acl); - result = set_nt_acl(fsp, security_info_sent, psd); - END_PROFILE(fset_nt_acl); - return result; -} - -BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) -{ - BOOL result; - - START_PROFILE(set_nt_acl); - result = set_nt_acl(fsp, security_info_sent, psd); - END_PROFILE(set_nt_acl); - return result; -} - -int vfswrap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode) -{ -#ifdef HAVE_NO_ACL - errno = ENOSYS; - return -1; -#else - int result; - - START_PROFILE(chmod_acl); - result = chmod_acl(conn, name, mode); - END_PROFILE(chmod_acl); - return result; -#endif -} - -int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) -{ -#ifdef HAVE_NO_ACL - errno = ENOSYS; - return -1; -#else - int result; - - START_PROFILE(fchmod_acl); - result = fchmod_acl(fsp, fd, mode); - END_PROFILE(fchmod_acl); - return result; -#endif -} - -int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) -{ - return sys_acl_get_entry(theacl, entry_id, entry_p); -} - -int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) -{ - return sys_acl_get_tag_type(entry_d, tag_type_p); -} - -int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - return sys_acl_get_permset(entry_d, permset_p); -} - -void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d) -{ - return sys_acl_get_qualifier(entry_d); -} - -SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) -{ - return sys_acl_get_file(path_p, type); -} - -SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) -{ - return sys_acl_get_fd(fd); -} - -int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset) -{ - return sys_acl_clear_perms(permset); -} - -int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return sys_acl_add_perm(permset, perm); -} - -char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen) -{ - return sys_acl_to_text(theacl, plen); -} - -SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count) -{ - return sys_acl_init(count); -} - -int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) -{ - return sys_acl_create_entry(pacl, pentry); -} - -int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) -{ - return sys_acl_set_tag_type(entry, tagtype); -} - -int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual) -{ - return sys_acl_set_qualifier(entry, qual); -} - -int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) -{ - return sys_acl_set_permset(entry, permset); -} - -int vfswrap_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl ) -{ - return sys_acl_valid(theacl ); -} - -int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) -{ - return sys_acl_set_file(name, acltype, theacl); -} - -int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl) -{ - return sys_acl_set_fd(fd, theacl); -} - -int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path) -{ - return sys_acl_delete_def_file(path); -} - -int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return sys_acl_get_perm(permset, perm); -} - -int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text) -{ - return sys_acl_free_text(text); -} - -int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl) -{ - return sys_acl_free_acl(posix_acl); -} - -int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype) -{ - return sys_acl_free_qualifier(qualifier, tagtype); -} - -/**************************************************************** - Extended attribute operations. -*****************************************************************/ - -ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) -{ - return sys_getxattr(path, name, value, size); -} - -ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) -{ - return sys_lgetxattr(path, name, value, size); -} - -ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size) -{ - return sys_fgetxattr(fd, name, value, size); -} - -ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) -{ - return sys_listxattr(path, list, size); -} - -ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) -{ - return sys_llistxattr(path, list, size); -} - -ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size) -{ - return sys_flistxattr(fd, list, size); -} - -int vfswrap_removexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) -{ - return sys_removexattr(path, name); -} - -int vfswrap_lremovexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) -{ - return sys_lremovexattr(path, name); -} - -int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name) -{ - return sys_fremovexattr(fd, name); -} - -int vfswrap_setxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) -{ - return sys_setxattr(path, name, value, size, flags); -} - -int vfswrap_lsetxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) -{ - return sys_lsetxattr(path, name, value, size, flags); -} - -int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags) -{ - return sys_fsetxattr(fd, name, value, size, flags); -} - -int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_read(aiocb); -} - -int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_write(aiocb); -} - -ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_return(aiocb); -} - -int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_cancel(fd, aiocb); -} - -int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_error(aiocb); -} - -int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_fsync(op, aiocb); -} - -int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout) -{ - return sys_aio_suspend(aiocb, n, timeout); -} diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 2c9403a079..7bb5f798f9 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -4,6 +4,7 @@ VFS initialisation and support functions Copyright (C) Tim Potter 1999 Copyright (C) Alexander Bokovoy 2002 + Copyright (C) James Peach 2006 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 @@ -37,131 +38,6 @@ struct vfs_init_function_entry { static struct vfs_init_function_entry *backends = NULL; -/* Some structures to help us initialise the vfs operations table */ - -struct vfs_syminfo { - char *name; - void *fptr; -}; - -/* Default vfs hooks. WARNING: The order of these initialisers is - very important. They must be in the same order as defined in - vfs.h. Change at your own peril. */ - -static struct vfs_ops default_vfs = { - - { - /* Disk operations */ - - vfswrap_dummy_connect, - vfswrap_dummy_disconnect, - vfswrap_disk_free, - vfswrap_get_quota, - vfswrap_set_quota, - vfswrap_get_shadow_copy_data, - vfswrap_statvfs, - - /* Directory operations */ - - vfswrap_opendir, - vfswrap_readdir, - vfswrap_seekdir, - vfswrap_telldir, - vfswrap_rewinddir, - vfswrap_mkdir, - vfswrap_rmdir, - vfswrap_closedir, - - /* File operations */ - - vfswrap_open, - vfswrap_close, - vfswrap_read, - vfswrap_pread, - vfswrap_write, - vfswrap_pwrite, - vfswrap_lseek, - vfswrap_sendfile, - vfswrap_rename, - vfswrap_fsync, - vfswrap_stat, - vfswrap_fstat, - vfswrap_lstat, - vfswrap_unlink, - vfswrap_chmod, - vfswrap_fchmod, - vfswrap_chown, - vfswrap_fchown, - vfswrap_chdir, - vfswrap_getwd, - vfswrap_utime, - vfswrap_ftruncate, - vfswrap_lock, - vfswrap_getlock, - vfswrap_symlink, - vfswrap_readlink, - vfswrap_link, - vfswrap_mknod, - vfswrap_realpath, - - /* Windows ACL operations. */ - vfswrap_fget_nt_acl, - vfswrap_get_nt_acl, - vfswrap_fset_nt_acl, - vfswrap_set_nt_acl, - - /* POSIX ACL operations. */ - vfswrap_chmod_acl, - vfswrap_fchmod_acl, - - vfswrap_sys_acl_get_entry, - vfswrap_sys_acl_get_tag_type, - vfswrap_sys_acl_get_permset, - vfswrap_sys_acl_get_qualifier, - vfswrap_sys_acl_get_file, - vfswrap_sys_acl_get_fd, - vfswrap_sys_acl_clear_perms, - vfswrap_sys_acl_add_perm, - vfswrap_sys_acl_to_text, - vfswrap_sys_acl_init, - vfswrap_sys_acl_create_entry, - vfswrap_sys_acl_set_tag_type, - vfswrap_sys_acl_set_qualifier, - vfswrap_sys_acl_set_permset, - vfswrap_sys_acl_valid, - vfswrap_sys_acl_set_file, - vfswrap_sys_acl_set_fd, - vfswrap_sys_acl_delete_def_file, - vfswrap_sys_acl_get_perm, - vfswrap_sys_acl_free_text, - vfswrap_sys_acl_free_acl, - vfswrap_sys_acl_free_qualifier, - - /* EA operations. */ - vfswrap_getxattr, - vfswrap_lgetxattr, - vfswrap_fgetxattr, - vfswrap_listxattr, - vfswrap_llistxattr, - vfswrap_flistxattr, - vfswrap_removexattr, - vfswrap_lremovexattr, - vfswrap_fremovexattr, - vfswrap_setxattr, - vfswrap_lsetxattr, - vfswrap_fsetxattr, - - /* AIO operations. */ - vfswrap_aio_read, - vfswrap_aio_write, - vfswrap_aio_return, - vfswrap_aio_cancel, - vfswrap_aio_error, - vfswrap_aio_fsync, - vfswrap_aio_suspend - } -}; - /**************************************************************************** maintain the list of available backends ****************************************************************************/ @@ -217,15 +93,20 @@ NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tu static void vfs_init_default(connection_struct *conn) { DEBUG(3, ("Initialising default vfs hooks\n")); - - memcpy(&conn->vfs.ops, &default_vfs.ops, sizeof(default_vfs.ops)); - memcpy(&conn->vfs_opaque.ops, &default_vfs.ops, sizeof(default_vfs.ops)); + vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME); } /**************************************************************************** initialise custom vfs hooks ****************************************************************************/ +static inline void vfs_set_operation(struct vfs_ops * vfs, vfs_op_type which, + struct vfs_handle_struct * handle, void * op) +{ + ((struct vfs_handle_struct **)&vfs->handles)[which] = handle; + ((void**)&vfs->ops)[which] = op; +} + BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) { vfs_op_tuple *ops; @@ -292,18 +173,15 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) for(i=0; ops[i].op != NULL; i++) { DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { - /* Check whether this operation was already made opaque by different module */ - if(((void**)&conn->vfs_opaque.ops)[ops[i].type] == ((void**)&default_vfs.ops)[ops[i].type]) { - /* No, it isn't overloaded yet. Overload. */ - DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); - ((void**)&conn->vfs_opaque.ops)[ops[i].type] = ops[i].op; - ((vfs_handle_struct **)&conn->vfs_opaque.handles)[ops[i].type] = handle; - } + /* If this operation was already made opaque by different module, it + * will be overridded here. + */ + DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); + vfs_set_operation(&conn->vfs_opaque, ops[i].type, handle, ops[i].op); } /* Change current VFS disposition*/ DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); - ((void**)&conn->vfs.ops)[ops[i].type] = ops[i].op; - ((vfs_handle_struct **)&conn->vfs.handles)[ops[i].type] = handle; + vfs_set_operation(&conn->vfs, ops[i].type, handle, ops[i].op); } SAFE_FREE(module_name); @@ -311,6 +189,71 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) } /***************************************************************** + Allow VFS modules to extend files_struct with VFS-specific state. + This will be ok for small numbers of extensions, but might need to + be refactored if it becomes more widely used. +******************************************************************/ + +#define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data)) + +void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle, files_struct *fsp, size_t ext_size) +{ + struct vfs_fsp_data *ext; + void * ext_data; + + /* Prevent VFS modules adding multiple extensions. */ + if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) { + return ext_data; + } + + ext = TALLOC_ZERO(handle->conn->mem_ctx, + sizeof(struct vfs_fsp_data) + ext_size); + if (ext == NULL) { + return NULL; + } + + ext->owner = handle; + ext->next = fsp->vfs_extension; + fsp->vfs_extension = ext; + return EXT_DATA_AREA(ext); +} + +void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp) +{ + struct vfs_fsp_data *curr; + struct vfs_fsp_data *prev; + + for (curr = fsp->vfs_extension, prev = NULL; + curr; + prev = curr, curr = curr->next) { + if (curr->owner == handle) { + if (prev) { + prev->next = curr->next; + } else { + fsp->vfs_extension = curr->next; + } + TALLOC_FREE(curr); + return; + } + } +} + +void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp) +{ + struct vfs_fsp_data *head; + + for (head = fsp->vfs_extension; head; head = head->next) { + if (head->owner == handle) { + return EXT_DATA_AREA(head); + } + } + + return NULL; +} + +#undef EXT_DATA_AREA + +/***************************************************************** Generic VFS init. ******************************************************************/ |