summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/blocking.c40
-rw-r--r--source3/smbd/change_trust_pw.c4
-rw-r--r--source3/smbd/conn.c8
-rw-r--r--source3/smbd/connection.c169
-rw-r--r--source3/smbd/dir.c21
-rw-r--r--source3/smbd/dosmode.c7
-rw-r--r--source3/smbd/error.c54
-rw-r--r--source3/smbd/fake_file.c23
-rw-r--r--source3/smbd/filename.c22
-rw-r--r--source3/smbd/files.c70
-rw-r--r--source3/smbd/lanman.c45
-rw-r--r--source3/smbd/mangle.c28
-rw-r--r--source3/smbd/mangle_hash.c18
-rw-r--r--source3/smbd/mangle_hash2.c44
-rw-r--r--source3/smbd/mangle_map.c4
-rw-r--r--source3/smbd/message.c3
-rw-r--r--source3/smbd/msdfs.c8
-rw-r--r--source3/smbd/nttrans.c98
-rw-r--r--source3/smbd/open.c229
-rw-r--r--source3/smbd/password.c19
-rw-r--r--source3/smbd/pipes.c17
-rw-r--r--source3/smbd/posix_acls.c12
-rw-r--r--source3/smbd/process.c23
-rw-r--r--source3/smbd/reply.c172
-rw-r--r--source3/smbd/server.c6
-rw-r--r--source3/smbd/service.c63
-rw-r--r--source3/smbd/session.c45
-rw-r--r--source3/smbd/share_access.c5
-rw-r--r--source3/smbd/statcache.c8
-rw-r--r--source3/smbd/statvfs.c4
-rw-r--r--source3/smbd/trans2.c83
-rw-r--r--source3/smbd/uid.c4
-rw-r--r--source3/smbd/vfs-wrap.c1104
-rw-r--r--source3/smbd/vfs.c217
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, &current_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.
******************************************************************/