summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/aio.c13
-rw-r--r--source3/smbd/avahi_register.c2
-rw-r--r--source3/smbd/blocking.c15
-rw-r--r--source3/smbd/close.c2
-rw-r--r--source3/smbd/conn.c234
-rw-r--r--source3/smbd/conn_idle.c207
-rw-r--r--source3/smbd/conn_msg.c49
-rw-r--r--source3/smbd/connection.c13
-rw-r--r--source3/smbd/dfree.c2
-rw-r--r--source3/smbd/dir.c18
-rw-r--r--source3/smbd/dmapi.c6
-rw-r--r--source3/smbd/dosmode.c90
-rw-r--r--source3/smbd/error.c12
-rw-r--r--source3/smbd/file_access.c5
-rw-r--r--source3/smbd/fileio.c6
-rw-r--r--source3/smbd/filename.c4
-rw-r--r--source3/smbd/files.c6
-rw-r--r--source3/smbd/globals.c48
-rw-r--r--source3/smbd/globals.h3
-rw-r--r--source3/smbd/ipc.c13
-rw-r--r--source3/smbd/lanman.c52
-rw-r--r--source3/smbd/mangle_hash.c16
-rw-r--r--source3/smbd/mangle_hash2.c2
-rw-r--r--source3/smbd/message.c4
-rw-r--r--source3/smbd/msdfs.c33
-rw-r--r--source3/smbd/msg_idmap.c2
-rw-r--r--source3/smbd/negprot.c17
-rw-r--r--source3/smbd/notify.c6
-rw-r--r--source3/smbd/notify_internal.c10
-rw-r--r--source3/smbd/ntquotas.c7
-rw-r--r--source3/smbd/nttrans.c35
-rw-r--r--source3/smbd/open.c247
-rw-r--r--source3/smbd/oplock.c18
-rw-r--r--source3/smbd/oplock_irix.c2
-rw-r--r--source3/smbd/oplock_linux.c2
-rw-r--r--source3/smbd/oplock_onefs.c2
-rw-r--r--source3/smbd/password.c8
-rw-r--r--source3/smbd/perfcount.c2
-rw-r--r--source3/smbd/pipes.c11
-rw-r--r--source3/smbd/posix_acls.c6
-rw-r--r--source3/smbd/process.c130
-rw-r--r--source3/smbd/proto.h83
-rw-r--r--source3/smbd/quotas.c1
-rw-r--r--source3/smbd/reply.c93
-rw-r--r--source3/smbd/seal.c5
-rw-r--r--source3/smbd/server.c85
-rw-r--r--source3/smbd/server_exit.c2
-rw-r--r--source3/smbd/server_reload.c6
-rw-r--r--source3/smbd/service.c229
-rw-r--r--source3/smbd/session.c4
-rw-r--r--source3/smbd/sesssetup.c37
-rw-r--r--source3/smbd/signing.c4
-rw-r--r--source3/smbd/smb2_break.c1
-rw-r--r--source3/smbd/smb2_create.c1
-rw-r--r--source3/smbd/smb2_find.c3
-rw-r--r--source3/smbd/smb2_flush.c1
-rw-r--r--source3/smbd/smb2_getinfo.c1
-rw-r--r--source3/smbd/smb2_ioctl.c133
-rw-r--r--source3/smbd/smb2_lock.c7
-rw-r--r--source3/smbd/smb2_negprot.c4
-rw-r--r--source3/smbd/smb2_notify.c1
-rw-r--r--source3/smbd/smb2_read.c6
-rw-r--r--source3/smbd/smb2_server.c21
-rw-r--r--source3/smbd/smb2_sesssetup.c2
-rw-r--r--source3/smbd/smb2_setinfo.c1
-rw-r--r--source3/smbd/smb2_tcon.c2
-rw-r--r--source3/smbd/smb2_write.c4
-rw-r--r--source3/smbd/srvstr.c2
-rw-r--r--source3/smbd/statcache.c5
-rw-r--r--source3/smbd/trans2.c176
-rw-r--r--source3/smbd/uid.c59
-rw-r--r--source3/smbd/vfs.c87
72 files changed, 1349 insertions, 1077 deletions
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index 682d042806..db2926b4a4 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -21,6 +21,7 @@
#include "includes.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
+#include "../lib/util/tevent_ntstatus.h"
#if defined(WITH_AIO)
@@ -80,8 +81,8 @@ static bool initialize_async_io_handler(void)
}
tried_signal_setup = true;
- aio_signal_event = tevent_add_signal(smbd_event_context(),
- smbd_event_context(),
+ aio_signal_event = tevent_add_signal(server_event_context(),
+ server_event_context(),
RT_SIGNAL_AIO, SA_SIGINFO,
smbd_aio_signal_handler,
NULL);
@@ -115,7 +116,7 @@ static struct aio_extra *create_aio_extra(TALLOC_CTX *mem_ctx,
files_struct *fsp,
size_t buflen)
{
- struct aio_extra *aio_ex = TALLOC_ZERO_P(mem_ctx, struct aio_extra);
+ struct aio_extra *aio_ex = talloc_zero(mem_ctx, struct aio_extra);
if (!aio_ex) {
return NULL;
@@ -250,7 +251,7 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
struct smb_request *smbreq,
- files_struct *fsp, char *data,
+ files_struct *fsp, const char *data,
SMB_OFF_T startpos,
size_t numtowrite)
{
@@ -328,7 +329,7 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
/* Now set up the aio record for the write call. */
a->aio_fildes = fsp->fh->fd;
- a->aio_buf = data;
+ a->aio_buf = discard_const_p(char, data);
a->aio_nbytes = numtowrite;
a->aio_offset = startpos;
a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
@@ -1029,7 +1030,7 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
struct smb_request *smbreq,
- files_struct *fsp, char *data,
+ files_struct *fsp, const char *data,
SMB_OFF_T startpos,
size_t numtowrite)
{
diff --git a/source3/smbd/avahi_register.c b/source3/smbd/avahi_register.c
index 05bd6038f4..368168d41d 100644
--- a/source3/smbd/avahi_register.c
+++ b/source3/smbd/avahi_register.c
@@ -88,7 +88,7 @@ static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
}
if (avahi_entry_group_add_service(
state->entry_group, AVAHI_IF_UNSPEC,
- AVAHI_PROTO_UNSPEC, 0, global_myname(),
+ AVAHI_PROTO_UNSPEC, 0, lp_netbios_name(),
"_smb._tcp", NULL, NULL, state->port, NULL) < 0) {
error = avahi_client_errno(c);
DEBUG(10, ("avahi_entry_group_add_service failed: "
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index c208234bdc..d9c1fb2d3b 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -139,7 +139,7 @@ static bool recalc_brl_timeout(struct smbd_server_connection *sconn)
(int)from_now.tv_sec, (int)from_now.tv_usec));
}
- sconn->smb1.locks.brl_timeout = event_add_timed(smbd_event_context(),
+ sconn->smb1.locks.brl_timeout = event_add_timed(server_event_context(),
NULL, next_timeout,
brl_timeout_fn, sconn);
if (sconn->smb1.locks.brl_timeout == NULL) {
@@ -208,8 +208,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blr->expire_time.tv_sec = 0;
blr->expire_time.tv_usec = 0; /* Never expire. */
} else {
- blr->expire_time = timeval_current_ofs(lock_timeout/1000,
- (lock_timeout % 1000) * 1000);
+ blr->expire_time = timeval_current_ofs_msec(lock_timeout);
}
blr->lock_num = lock_num;
blr->smblctx = smblctx;
@@ -337,7 +336,7 @@ static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS stat
uint8_t *data;
int i;
- data = (uint8_t *)blr->req->buf
+ data = discard_const_p(uint8_t, blr->req->buf)
+ ((large_file_format ? 20 : 10)*num_ulocks);
/*
@@ -429,7 +428,7 @@ static bool process_lockingX(struct blocking_lock_record *blr)
uint8_t *data;
NTSTATUS status = NT_STATUS_OK;
- data = (uint8_t *)blr->req->buf
+ data = discard_const_p(uint8_t, blr->req->buf)
+ ((large_file_format ? 20 : 10)*num_ulocks);
/*
@@ -575,9 +574,9 @@ static bool blocking_lock_record_process(struct blocking_lock_record *blr)
Called when a file is closed.
*****************************************************************************/
-void cancel_pending_lock_requests_by_fid(files_struct *fsp,
- struct byte_range_lock *br_lck,
- enum file_close_type close_type)
+void smbd_cancel_pending_lock_requests_by_fid(files_struct *fsp,
+ struct byte_range_lock *br_lck,
+ enum file_close_type close_type)
{
struct smbd_server_connection *sconn = fsp->conn->sconn;
struct blocking_lock_record *blr, *blr_cancelled, *next = NULL;
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index aeed4e3c9d..52cfc111fb 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -283,7 +283,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
/* Ensure any pending write time updates are done. */
if (fsp->update_write_time_event) {
- update_write_time_handler(smbd_event_context(),
+ update_write_time_handler(server_event_context(),
fsp->update_write_time_event,
timeval_current(),
(void *)fsp);
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 16a0ee053e..a3f66b36be 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -53,10 +53,9 @@ int conn_num_open(struct smbd_server_connection *sconn)
Check if a snum is in use.
****************************************************************************/
-bool conn_snum_used(int snum)
+bool conn_snum_used(struct smbd_server_connection *sconn,
+ int snum)
{
- struct smbd_server_connection *sconn = smbd_server_conn;
-
if (sconn->using_smb2) {
/* SMB2 */
struct smbd_smb2_session *sess;
@@ -134,8 +133,8 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
if (sconn->using_smb2) {
/* SMB2 */
- if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
- !(conn->params = TALLOC_P(conn, struct share_params))) {
+ if (!(conn=talloc_zero(NULL, connection_struct)) ||
+ !(conn->params = talloc(conn, struct share_params))) {
DEBUG(0,("TALLOC_ZERO() failed!\n"));
TALLOC_FREE(conn);
return NULL;
@@ -189,8 +188,8 @@ find_again:
return NULL;
}
- if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
- !(conn->params = TALLOC_P(conn, struct share_params))) {
+ if (!(conn=talloc_zero(NULL, connection_struct)) ||
+ !(conn->params = talloc(conn, struct share_params))) {
DEBUG(0,("TALLOC_ZERO() failed!\n"));
TALLOC_FREE(conn);
return NULL;
@@ -212,142 +211,52 @@ find_again:
}
/****************************************************************************
- Close all conn structures.
- Return true if any were closed.
-****************************************************************************/
-
-bool conn_close_all(struct smbd_server_connection *sconn)
-{
- bool ret = false;
- if (sconn->using_smb2) {
- /* SMB2 */
- struct smbd_smb2_session *sess;
- for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
- struct smbd_smb2_tcon *tcon, *tc_next;
-
- for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
- tc_next = tcon->next;
- TALLOC_FREE(tcon);
- ret = true;
- }
- }
- } else {
- /* SMB1 */
- connection_struct *conn, *next;
-
- for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
- next=conn->next;
- set_current_service(conn, 0, True);
- close_cnum(conn, conn->vuid);
- ret = true;
- }
- }
- return ret;
-}
-
-/****************************************************************************
- Update last used timestamps.
-****************************************************************************/
-
-static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
-{
- if (sconn->using_smb2) {
- /* SMB2 */
- struct smbd_smb2_session *sess;
- for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
- struct smbd_smb2_tcon *ptcon;
-
- for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
- connection_struct *conn = ptcon->compat_conn;
- /* Update if connection wasn't idle. */
- if (conn && conn->lastused != conn->lastused_count) {
- conn->lastused = t;
- conn->lastused_count = t;
- }
- }
- }
- } else {
- /* SMB1 */
- connection_struct *conn;
- for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
- /* Update if connection wasn't idle. */
- if (conn->lastused != conn->lastused_count) {
- conn->lastused = t;
- conn->lastused_count = t;
- }
- }
- }
-}
-
-/****************************************************************************
- Idle inactive connections.
+ Clear a vuid out of the connection's vuid cache
****************************************************************************/
-bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
+static void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
{
- int deadtime = lp_deadtime()*60;
-
- conn_lastused_update(sconn, t);
-
- if (deadtime <= 0) {
- deadtime = DEFAULT_SMBD_TIMEOUT;
- }
-
- if (sconn->using_smb2) {
- /* SMB2 */
- struct smbd_smb2_session *sess;
- for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
- struct smbd_smb2_tcon *ptcon;
-
- for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
- time_t age;
- connection_struct *conn = ptcon->compat_conn;
-
- if (conn == NULL) {
- continue;
- }
-
- age = t - conn->lastused;
- /* close dirptrs on connections that are idle */
- if (age > DPTR_IDLE_TIMEOUT) {
- dptr_idlecnum(conn);
- }
-
- if (conn->num_files_open > 0 || age < deadtime) {
- return false;
- }
- }
- }
- } else {
- /* SMB1 */
- connection_struct *conn;
- for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
- time_t age = t - conn->lastused;
-
- /* close dirptrs on connections that are idle */
- if (age > DPTR_IDLE_TIMEOUT) {
- dptr_idlecnum(conn);
- }
+ int i;
- if (conn->num_files_open > 0 || age < deadtime) {
- return false;
+ for (i=0; i<VUID_CACHE_SIZE; i++) {
+ struct vuid_cache_entry *ent;
+
+ ent = &conn->vuid_cache.array[i];
+
+ if (ent->vuid == vuid) {
+ ent->vuid = UID_FIELD_INVALID;
+ /*
+ * We need to keep conn->session_info around
+ * if it's equal to ent->session_info as a SMBulogoff
+ * is often followed by a SMBtdis (with an invalid
+ * vuid). The debug code (or regular code in
+ * vfs_full_audit) wants to refer to the
+ * conn->session_info pointer to print debug
+ * statements. Theoretically this is a bug,
+ * as once the vuid is gone the session_info
+ * on the conn struct isn't valid any more,
+ * but there's enough code that assumes
+ * conn->session_info is never null that
+ * it's easier to hold onto the old pointer
+ * until we get a new sessionsetupX.
+ * As everything is hung off the
+ * conn pointer as a talloc context we're not
+ * leaking memory here. See bug #6315. JRA.
+ */
+ if (conn->session_info == ent->session_info) {
+ ent->session_info = NULL;
+ } else {
+ TALLOC_FREE(ent->session_info);
}
+ ent->read_only = False;
}
}
-
- /*
- * Check all pipes for any open handles. We cannot
- * idle with a handle open.
- */
- if (check_open_pipes()) {
- return false;
- }
-
- return true;
}
/****************************************************************************
Clear a vuid out of the validity cache, and as the 'owner' of a connection.
+
+ Called from invalidate_vuid()
****************************************************************************/
void conn_clear_vuid_caches(struct smbd_server_connection *sconn,uint16_t vuid)
@@ -451,64 +360,3 @@ void conn_free(connection_struct *conn)
conn_free_internal(conn);
}
-
-/****************************************************************************
- Receive a smbcontrol message to forcibly unmount a share.
- The message contains just a share name and all instances of that
- share are unmounted.
- The special sharename '*' forces unmount of all shares.
-****************************************************************************/
-
-void msg_force_tdis(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
-{
- struct smbd_server_connection *sconn;
- connection_struct *conn, *next;
- fstring sharename;
-
- sconn = msg_ctx_to_sconn(msg);
- if (sconn == NULL) {
- DEBUG(1, ("could not find sconn\n"));
- return;
- }
-
- fstrcpy(sharename, (const char *)data->data);
-
- if (strcmp(sharename, "*") == 0) {
- DEBUG(1,("Forcing close of all shares\n"));
- conn_close_all(sconn);
- return;
- }
-
- if (sconn->using_smb2) {
- /* SMB2 */
- struct smbd_smb2_session *sess;
- for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
- struct smbd_smb2_tcon *tcon, *tc_next;
-
- for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
- tc_next = tcon->next;
- if (tcon->compat_conn &&
- strequal(lp_servicename(SNUM(tcon->compat_conn)),
- sharename)) {
- DEBUG(1,("Forcing close of share %s cnum=%d\n",
- sharename, tcon->compat_conn->cnum));
- TALLOC_FREE(tcon);
- }
- }
- }
- } else {
- /* SMB1 */
- for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
- next=conn->next;
- 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/conn_idle.c b/source3/smbd/conn_idle.c
new file mode 100644
index 0000000000..46f5b7b111
--- /dev/null
+++ b/source3/smbd/conn_idle.c
@@ -0,0 +1,207 @@
+/*
+ Unix SMB/CIFS implementation.
+ Manage connections_struct structures
+ Copyright (C) Andrew Tridgell 1998
+ Copyright (C) Alexander Bokovoy 2002
+ Copyright (C) Jeremy Allison 2010
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "rpc_server/rpc_ncacn_np.h"
+
+/****************************************************************************
+ Update last used timestamps.
+****************************************************************************/
+
+static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
+{
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
+
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ connection_struct *conn = ptcon->compat_conn;
+ /* Update if connection wasn't idle. */
+ if (conn && conn->lastused != conn->lastused_count) {
+ conn->lastused = t;
+ conn->lastused_count = t;
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ connection_struct *conn;
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ /* Update if connection wasn't idle. */
+ if (conn->lastused != conn->lastused_count) {
+ conn->lastused = t;
+ conn->lastused_count = t;
+ }
+ }
+ }
+}
+
+/****************************************************************************
+ Idle inactive connections.
+****************************************************************************/
+
+bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
+{
+ int deadtime = lp_deadtime()*60;
+
+ conn_lastused_update(sconn, t);
+
+ if (deadtime <= 0) {
+ deadtime = DEFAULT_SMBD_TIMEOUT;
+ }
+
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
+
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ time_t age;
+ connection_struct *conn = ptcon->compat_conn;
+
+ if (conn == NULL) {
+ continue;
+ }
+
+ age = t - conn->lastused;
+ /* close dirptrs on connections that are idle */
+ if (age > DPTR_IDLE_TIMEOUT) {
+ dptr_idlecnum(conn);
+ }
+
+ if (conn->num_files_open > 0 || age < deadtime) {
+ return false;
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ connection_struct *conn;
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ time_t age = t - conn->lastused;
+
+ /* close dirptrs on connections that are idle */
+ if (age > DPTR_IDLE_TIMEOUT) {
+ dptr_idlecnum(conn);
+ }
+
+ if (conn->num_files_open > 0 || age < deadtime) {
+ return false;
+ }
+ }
+ }
+
+ /*
+ * Check all pipes for any open handles. We cannot
+ * idle with a handle open.
+ */
+ if (check_open_pipes()) {
+ return false;
+ }
+
+ return true;
+}
+
+/****************************************************************************
+ Close all conn structures.
+ Return true if any were closed.
+****************************************************************************/
+
+bool conn_close_all(struct smbd_server_connection *sconn)
+{
+ bool ret = false;
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *tcon, *tc_next;
+
+ for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
+ tc_next = tcon->next;
+ TALLOC_FREE(tcon);
+ ret = true;
+ }
+ }
+ } else {
+ /* SMB1 */
+ connection_struct *conn, *next;
+
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
+ next=conn->next;
+ set_current_service(conn, 0, True);
+ close_cnum(conn, conn->vuid);
+ ret = true;
+ }
+ }
+ return ret;
+}
+
+
+/****************************************************************************
+ Forcibly unmount a share.
+ All instances of the parameter 'sharename' share are unmounted.
+ The special sharename '*' forces unmount of all shares.
+****************************************************************************/
+
+void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename)
+{
+ connection_struct *conn, *next;
+
+ if (strcmp(sharename, "*") == 0) {
+ DEBUG(1,("Forcing close of all shares\n"));
+ conn_close_all(sconn);
+ return;
+ }
+
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *tcon, *tc_next;
+
+ for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
+ tc_next = tcon->next;
+ if (tcon->compat_conn &&
+ strequal(lp_servicename(SNUM(tcon->compat_conn)),
+ sharename)) {
+ DEBUG(1,("Forcing close of share %s cnum=%d\n",
+ sharename, tcon->compat_conn->cnum));
+ TALLOC_FREE(tcon);
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
+ next=conn->next;
+ 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/conn_msg.c b/source3/smbd/conn_msg.c
new file mode 100644
index 0000000000..b0c968a680
--- /dev/null
+++ b/source3/smbd/conn_msg.c
@@ -0,0 +1,49 @@
+/*
+ Unix SMB/CIFS implementation.
+ Manage connections_struct structures
+ Copyright (C) Andrew Tridgell 1998
+ Copyright (C) Alexander Bokovoy 2002
+ Copyright (C) Jeremy Allison 2010
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+
+/****************************************************************************
+ Receive a smbcontrol message to forcibly unmount a share.
+ The message contains just a share name and all instances of that
+ share are unmounted.
+ The special sharename '*' forces unmount of all shares.
+****************************************************************************/
+
+void msg_force_tdis(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ struct smbd_server_connection *sconn;
+ const char *sharename = (const char *)data->data;
+
+ sconn = msg_ctx_to_sconn(msg);
+ if (sconn == NULL) {
+ DEBUG(1, ("could not find sconn\n"));
+ return;
+ }
+
+ conn_force_tdis(sconn, sharename);
+}
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 8560a5d211..7ed9518756 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -101,6 +101,7 @@ static int count_fn(struct db_record *rec,
int count_current_connections( const char *sharename, bool clear )
{
struct count_stat cs;
+ int ret;
cs.curr_connections = 0;
cs.name = sharename;
@@ -111,10 +112,18 @@ int count_current_connections( const char *sharename, bool clear )
* as it leads to deadlock.
*/
- if (connections_forall(count_fn, &cs) == -1) {
+ /*
+ * become_root() because we might have to open connections.tdb
+ * via ctdb, which is not possible without root.
+ */
+ become_root();
+ ret = connections_forall(count_fn, &cs);
+ unbecome_root();
+
+ if (ret < 0) {
DEBUG(0,("count_current_connections: traverse of "
"connections.tdb failed\n"));
- return False;
+ return 0;
}
return cs.curr_connections;
diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c
index 63c287cd41..03541880e1 100644
--- a/source3/smbd/dfree.c
+++ b/source3/smbd/dfree.c
@@ -207,7 +207,7 @@ uint64_t get_dfree_info(connection_struct *conn,
/* No cached info or time to refresh. */
if (!dfc) {
- dfc = TALLOC_P(conn, struct dfree_cached_info);
+ dfc = talloc(conn, struct dfree_cached_info);
if (!dfc) {
return dfree_ret;
}
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 5fc87a608f..fda7c34c57 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -92,7 +92,7 @@ bool make_dir_struct(TALLOC_CTX *ctx,
return False;
}
- if ((mode & aDIR) != 0) {
+ if ((mode & FILE_ATTRIBUTE_DIRECTORY) != 0) {
size = 0;
}
@@ -872,15 +872,15 @@ bool dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype)
uint32 mask;
/* Check the "may have" search bits. */
- if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
+ if (((mode & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)) != 0)
return False;
/* Check the "must have" bits, which are the may have bits shifted eight */
/* If must have bit is set, the file/dir can not be returned in search unless the matching
file attribute is set */
- mask = ((dirtype >> 8) & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM)); /* & 0x37 */
+ mask = ((dirtype >> 8) & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)); /* & 0x37 */
if(mask) {
- if((mask & (mode & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM))) == mask) /* check if matching attribute present */
+ if((mask & (mode & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) == mask) /* check if matching attribute present */
return True;
else
return False;
@@ -1342,7 +1342,7 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
const char *mask,
uint32 attr)
{
- struct smb_Dir *dirp = TALLOC_ZERO_P(mem_ctx, struct smb_Dir);
+ struct smb_Dir *dirp = talloc_zero(mem_ctx, struct smb_Dir);
struct smbd_server_connection *sconn = conn->sconn;
if (!dirp) {
@@ -1386,7 +1386,7 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
const char *mask,
uint32 attr)
{
- struct smb_Dir *dirp = TALLOC_ZERO_P(mem_ctx, struct smb_Dir);
+ struct smb_Dir *dirp = talloc_zero(mem_ctx, struct smb_Dir);
struct smbd_server_connection *sconn = conn->sconn;
if (!dirp) {
@@ -1559,7 +1559,7 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset)
}
if (dirp->name_cache == NULL) {
- dirp->name_cache = TALLOC_ZERO_ARRAY(
+ dirp->name_cache = talloc_zero_array(
dirp, struct name_cache_entry, dirp->name_cache_size);
if (dirp->name_cache == NULL) {
@@ -1625,8 +1625,8 @@ bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
Is this directory empty ?
*****************************************************************/
-NTSTATUS can_delete_directory(struct connection_struct *conn,
- const char *dirname)
+NTSTATUS smbd_can_delete_directory(struct connection_struct *conn,
+ const char *dirname)
{
NTSTATUS status = NT_STATUS_OK;
long dirpos = 0;
diff --git a/source3/smbd/dmapi.c b/source3/smbd/dmapi.c
index 2869b6d781..8e80a588c5 100644
--- a/source3/smbd/dmapi.c
+++ b/source3/smbd/dmapi.c
@@ -96,7 +96,7 @@ static int dmapi_init_session(struct smbd_dmapi_context *ctx)
do {
dm_sessid_t *new_sessions;
nsessions *= 2;
- new_sessions = TALLOC_REALLOC_ARRAY(tmp_ctx, sessions,
+ new_sessions = talloc_realloc(tmp_ctx, sessions,
dm_sessid_t, nsessions);
if (new_sessions == NULL) {
talloc_free(tmp_ctx);
@@ -289,7 +289,7 @@ uint32 dmapi_file_flags(const char * const path)
become_root();
#endif
- err = dm_path_to_handle(CONST_DISCARD(char *, path),
+ err = dm_path_to_handle(discard_const_p(char, path),
&dm_handle, &dm_handle_len);
if (err < 0) {
DEBUG(DMAPI_TRACE, ("dm_path_to_handle(%s): %s\n",
@@ -308,7 +308,7 @@ uint32 dmapi_file_flags(const char * const path)
set_effective_capability(DMAPI_ACCESS_CAPABILITY);
- err = dm_path_to_handle(CONST_DISCARD(char *, path),
+ err = dm_path_to_handle(discard_const_p(char, path),
&dm_handle, &dm_handle_len);
if (err < 0) {
DEBUG(DMAPI_TRACE,
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index a9b6dfef78..823d44d0aa 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -41,7 +41,7 @@ static int set_link_read_only_flag(const SMB_STRUCT_STAT *const sbuf)
#ifdef S_ISLNK
#if LINKS_READ_ONLY
if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
- return aRONLY;
+ return FILE_ATTRIBUTE_READONLY;
#endif
#endif
return 0;
@@ -173,36 +173,36 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn,
if (ro_opts == MAP_READONLY_YES) {
/* Original Samba method - map inverse of user "w" bit. */
if ((smb_fname->st.st_ex_mode & S_IWUSR) == 0) {
- result |= aRONLY;
+ result |= FILE_ATTRIBUTE_READONLY;
}
} else if (ro_opts == MAP_READONLY_PERMISSIONS) {
/* Check actual permissions for read-only. */
if (!can_write_to_file(conn, smb_fname)) {
- result |= aRONLY;
+ result |= FILE_ATTRIBUTE_READONLY;
}
} /* Else never set the readonly bit. */
if (MAP_ARCHIVE(conn) && ((smb_fname->st.st_ex_mode & S_IXUSR) != 0))
- result |= aARCH;
+ result |= FILE_ATTRIBUTE_ARCHIVE;
if (MAP_SYSTEM(conn) && ((smb_fname->st.st_ex_mode & S_IXGRP) != 0))
- result |= aSYSTEM;
+ result |= FILE_ATTRIBUTE_SYSTEM;
if (MAP_HIDDEN(conn) && ((smb_fname->st.st_ex_mode & S_IXOTH) != 0))
- result |= aHIDDEN;
+ result |= FILE_ATTRIBUTE_HIDDEN;
if (S_ISDIR(smb_fname->st.st_ex_mode))
- result = aDIR | (result & aRONLY);
+ result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY);
result |= set_link_read_only_flag(&smb_fname->st);
DEBUG(8,("dos_mode_from_sbuf returning "));
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
+ if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
+ if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
+ if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
+ if (result & FILE_ATTRIBUTE_DIRECTORY ) DEBUG(8, ("d"));
+ if (result & FILE_ATTRIBUTE_ARCHIVE ) DEBUG(8, ("a"));
DEBUG(8,("\n"));
return result;
@@ -318,18 +318,18 @@ static bool get_ea_dos_attribute(connection_struct *conn,
}
if (S_ISDIR(smb_fname->st.st_ex_mode)) {
- dosattr |= aDIR;
+ dosattr |= FILE_ATTRIBUTE_DIRECTORY;
}
/* FILE_ATTRIBUTE_SPARSE is valid on get but not on set. */
*pattr = (uint32)(dosattr & (SAMBA_ATTRIBUTES_MASK|FILE_ATTRIBUTE_SPARSE));
DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr));
- if (dosattr & aHIDDEN) DEBUG(8, ("h"));
- if (dosattr & aRONLY ) DEBUG(8, ("r"));
- if (dosattr & aSYSTEM) DEBUG(8, ("s"));
- if (dosattr & aDIR ) DEBUG(8, ("d"));
- if (dosattr & aARCH ) DEBUG(8, ("a"));
+ if (dosattr & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
+ if (dosattr & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
+ if (dosattr & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
+ if (dosattr & FILE_ATTRIBUTE_DIRECTORY ) DEBUG(8, ("d"));
+ if (dosattr & FILE_ATTRIBUTE_ARCHIVE ) DEBUG(8, ("a"));
DEBUG(8,("\n"));
@@ -465,7 +465,7 @@ uint32 dos_mode_msdfs(connection_struct *conn,
/* Only . and .. are not hidden. */
if (p[0] == '.' && !((p[1] == '\0') ||
(p[1] == '.' && p[2] == '\0'))) {
- result |= aHIDDEN;
+ result |= FILE_ATTRIBUTE_HIDDEN;
}
}
@@ -473,9 +473,9 @@ uint32 dos_mode_msdfs(connection_struct *conn,
/* Optimization : Only call is_hidden_path if it's not already
hidden. */
- if (!(result & aHIDDEN) &&
+ if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
- result |= aHIDDEN;
+ result |= FILE_ATTRIBUTE_HIDDEN;
}
if (result == 0) {
@@ -486,11 +486,11 @@ uint32 dos_mode_msdfs(connection_struct *conn,
DEBUG(8,("dos_mode_msdfs returning "));
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
+ if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
+ if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
+ if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
+ if (result & FILE_ATTRIBUTE_DIRECTORY ) DEBUG(8, ("d"));
+ if (result & FILE_ATTRIBUTE_ARCHIVE ) DEBUG(8, ("a"));
if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
DEBUG(8,("\n"));
@@ -507,13 +507,13 @@ int dos_attributes_to_stat_dos_flags(uint32_t dosmode)
{
uint32_t dos_stat_flags = 0;
- if (dosmode & aARCH)
+ if (dosmode & FILE_ATTRIBUTE_ARCHIVE)
dos_stat_flags |= UF_DOS_ARCHIVE;
- if (dosmode & aHIDDEN)
+ if (dosmode & FILE_ATTRIBUTE_HIDDEN)
dos_stat_flags |= UF_DOS_HIDDEN;
- if (dosmode & aRONLY)
+ if (dosmode & FILE_ATTRIBUTE_READONLY)
dos_stat_flags |= UF_DOS_RO;
- if (dosmode & aSYSTEM)
+ if (dosmode & FILE_ATTRIBUTE_SYSTEM)
dos_stat_flags |= UF_DOS_SYSTEM;
if (dosmode & FILE_ATTRIBUTE_NONINDEXED)
dos_stat_flags |= UF_DOS_NOINDEX;
@@ -540,19 +540,19 @@ static bool get_stat_dos_flags(connection_struct *conn,
smb_fname_str_dbg(smb_fname)));
if (smb_fname->st.st_ex_flags & UF_DOS_ARCHIVE)
- *dosmode |= aARCH;
+ *dosmode |= FILE_ATTRIBUTE_ARCHIVE;
if (smb_fname->st.st_ex_flags & UF_DOS_HIDDEN)
- *dosmode |= aHIDDEN;
+ *dosmode |= FILE_ATTRIBUTE_HIDDEN;
if (smb_fname->st.st_ex_flags & UF_DOS_RO)
- *dosmode |= aRONLY;
+ *dosmode |= FILE_ATTRIBUTE_READONLY;
if (smb_fname->st.st_ex_flags & UF_DOS_SYSTEM)
- *dosmode |= aSYSTEM;
+ *dosmode |= FILE_ATTRIBUTE_SYSTEM;
if (smb_fname->st.st_ex_flags & UF_DOS_NOINDEX)
*dosmode |= FILE_ATTRIBUTE_NONINDEXED;
if (smb_fname->st.st_ex_flags & FILE_ATTRIBUTE_SPARSE)
*dosmode |= FILE_ATTRIBUTE_SPARSE;
if (S_ISDIR(smb_fname->st.st_ex_mode))
- *dosmode |= aDIR;
+ *dosmode |= FILE_ATTRIBUTE_DIRECTORY;
*dosmode |= set_link_read_only_flag(&smb_fname->st);
@@ -637,7 +637,7 @@ uint32 dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
/* Only . and .. are not hidden. */
if (p[0] == '.' && !((p[1] == '\0') ||
(p[1] == '.' && p[2] == '\0'))) {
- result |= aHIDDEN;
+ result |= FILE_ATTRIBUTE_HIDDEN;
}
}
@@ -658,9 +658,9 @@ uint32 dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
/* Optimization : Only call is_hidden_path if it's not already
hidden. */
- if (!(result & aHIDDEN) &&
+ if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
- result |= aHIDDEN;
+ result |= FILE_ATTRIBUTE_HIDDEN;
}
if (result == 0) {
@@ -671,11 +671,11 @@ uint32 dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
DEBUG(8,("dos_mode returning "));
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
+ if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
+ if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
+ if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
+ if (result & FILE_ATTRIBUTE_DIRECTORY ) DEBUG(8, ("d"));
+ if (result & FILE_ATTRIBUTE_ARCHIVE ) DEBUG(8, ("a"));
if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
DEBUG(8,("\n"));
@@ -712,9 +712,9 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
&smb_fname->st.st_ex_mode);
if (S_ISDIR(smb_fname->st.st_ex_mode))
- dosmode |= aDIR;
+ dosmode |= FILE_ATTRIBUTE_DIRECTORY;
else
- dosmode &= ~aDIR;
+ dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
new_create_timespec = smb_fname->st.st_ex_btime;
diff --git a/source3/smbd/error.c b/source3/smbd/error.c
index 6655a6fb08..2fb4241968 100644
--- a/source3/smbd/error.c
+++ b/source3/smbd/error.c
@@ -21,9 +21,6 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
-/* From lib/error.c */
-extern struct unix_error_map unix_dos_nt_errmap[];
-
bool use_nt_status(void)
{
return lp_nt_status_support() && (global_client_caps & CAP_STATUS32);
@@ -80,11 +77,10 @@ void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatu
smb_fn_name(CVAL(outbuf,smb_com)),
nt_errstr(ntstatus)));
} else {
- /* We're returning a DOS error only. */
- 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)) {
+ /* We're returning a DOS error only,
+ * nt_status_to_dos() pulls DOS error codes out of the
+ * NTSTATUS */
+ if (NT_STATUS_IS_DOS(ntstatus) || (eclass == 0 && NT_STATUS_V(ntstatus))) {
ntstatus_to_dos(ntstatus, &eclass, &ecode);
}
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index 960dcb703a..74855649ea 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -92,6 +92,11 @@ bool can_delete_file_in_directory(connection_struct *conn,
return False;
}
+ if (!lp_acl_check_permissions(SNUM(conn))) {
+ /* This option means don't check. */
+ return true;
+ }
+
/* Get the parent directory permission mask and owners. */
if (!parent_dirname(ctx, smb_fname->base_name, &dname, NULL)) {
return False;
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 16d8853b54..3b317f9a86 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -240,8 +240,8 @@ void trigger_write_time_update(struct files_struct *fsp)
/* trigger the update 2 seconds later */
fsp->update_write_time_event =
- event_add_timed(smbd_event_context(), NULL,
- timeval_current_ofs(0, delay),
+ event_add_timed(server_event_context(), NULL,
+ timeval_current_ofs_usec(delay),
update_write_time_handler, fsp);
}
@@ -322,7 +322,7 @@ ssize_t write_file(struct smb_request *req,
int dosmode = dos_mode(fsp->conn, fsp->fsp_name);
if (!IS_DOS_ARCHIVE(dosmode)) {
file_set_dosmode(fsp->conn, fsp->fsp_name,
- dosmode | aARCH, NULL, false);
+ dosmode | FILE_ATTRIBUTE_ARCHIVE, NULL, false);
}
}
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 08bc79dfd2..ec8d1139fa 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -163,11 +163,11 @@ static NTSTATUS check_parent_exists(TALLOC_CTX *ctx,
* last compnent to shorten the tree walk. */
/*
- * Safe to use CONST_DISCARD
+ * Safe to use discard_const_p
* here as last_component points
* into our smb_fname->base_name.
*/
- *pp_start = CONST_DISCARD(char *,last_component);
+ *pp_start = discard_const_p(char, last_component);
/* Update dirpath. */
TALLOC_FREE(*pp_dirpath);
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index b9063ccbb8..b8a25c1d5b 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -21,6 +21,8 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "libcli/security/security.h"
+#include "util_tdb.h"
+#include <ccan/hash/hash.h>
#define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < real_max_open_files))
@@ -598,7 +600,6 @@ NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
NTSTATUS file_name_hash(connection_struct *conn,
const char *name, uint32_t *p_name_hash)
{
- TDB_DATA key;
char *fullpath = NULL;
/* Set the hash of the full pathname. */
@@ -609,8 +610,7 @@ NTSTATUS file_name_hash(connection_struct *conn,
if (!fullpath) {
return NT_STATUS_NO_MEMORY;
}
- key = string_term_tdb_data(fullpath);
- *p_name_hash = tdb_jenkins_hash(&key);
+ *p_name_hash = hash(fullpath, strlen(fullpath) + 1, 0);
DEBUG(10,("file_name_hash: %s hash 0x%x\n",
fullpath,
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 63c1f5dcb5..2736fa69d0 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -20,8 +20,10 @@
#include "includes.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
+#include "lib/smbd_shim.h"
#include "memcache.h"
#include "messages.h"
+#include "tdb_compat.h"
#if defined(WITH_AIO)
struct aio_extra *aio_list_head = NULL;
@@ -144,14 +146,29 @@ struct memcache *smbd_memcache(void)
return smbd_memcache_ctx;
}
+static const struct smbd_shim smbd_shim_fns =
+{
+ .cancel_pending_lock_requests_by_fid = smbd_cancel_pending_lock_requests_by_fid,
+ .send_stat_cache_delete_message = smbd_send_stat_cache_delete_message,
+ .can_delete_directory = smbd_can_delete_directory,
+ .change_to_root_user = smbd_change_to_root_user,
+
+ .contend_level2_oplocks_begin = smbd_contend_level2_oplocks_begin,
+ .contend_level2_oplocks_end = smbd_contend_level2_oplocks_end,
+
+ .become_root = smbd_become_root,
+ .unbecome_root = smbd_unbecome_root
+};
void smbd_init_globals(void)
{
+ set_smbd_shim(&smbd_shim_fns);
+
ZERO_STRUCT(conn_ctx_stack);
ZERO_STRUCT(sec_ctx_stack);
- smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
+ smbd_server_conn = talloc_zero(server_event_context(), struct smbd_server_connection);
if (!smbd_server_conn) {
exit_server("failed to create smbd_server_connection");
}
@@ -159,3 +176,32 @@ void smbd_init_globals(void)
smbd_server_conn->smb1.echo_handler.trusted_fd = -1;
smbd_server_conn->smb1.echo_handler.socket_lock_fd = -1;
}
+
+void smbd_set_server_fd(int fd)
+{
+ struct smbd_server_connection *sconn = smbd_server_conn;
+ char addr[INET6_ADDRSTRLEN];
+ const char *name;
+
+ sconn->sock = fd;
+
+ /*
+ * Initialize sconn->client_id: If we can't find the client's
+ * name, default to its address.
+ */
+
+ client_addr(fd, sconn->client_id.addr, sizeof(sconn->client_id.addr));
+
+ name = client_name(sconn->sock);
+ if (strcmp(name, "UNKNOWN") != 0) {
+ name = talloc_strdup(sconn, name);
+ } else {
+ name = NULL;
+ }
+ sconn->client_id.name =
+ (name != NULL) ? name : sconn->client_id.addr;
+
+ sub_set_socket_ids(sconn->client_id.addr, sconn->client_id.name,
+ client_socket_addr(sconn->sock, addr,
+ sizeof(addr)));
+}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 01be31a57f..97d75fd413 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -47,7 +47,8 @@ struct fsp_singleton_cache {
extern const struct mangle_fns *mangle_fns;
extern unsigned char *chartest;
-extern TDB_CONTEXT *tdb_mangled_cache;
+struct tdb_context;
+extern struct tdb_context *tdb_mangled_cache;
/*
this determines how many characters are used from the original filename
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 4f2fea5265..669e28e715 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -28,6 +28,7 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "smbprofile.h"
+#include "rpc_server/srv_pipe_hnd.h"
#define NERR_notsupported 50
@@ -267,7 +268,7 @@ static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
state->num_data = length;
state->max_read = max_read;
- subreq = np_write_send(state, smbd_event_context(), state->handle,
+ subreq = np_write_send(state, server_event_context(), state->handle,
state->data, length);
if (subreq == NULL) {
TALLOC_FREE(state);
@@ -297,14 +298,14 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
goto send;
}
- state->data = TALLOC_REALLOC_ARRAY(state, state->data, uint8_t,
+ state->data = talloc_realloc(state, state->data, uint8_t,
state->max_read);
if (state->data == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto send;
}
- subreq = np_read_send(req->conn, smbd_event_context(),
+ subreq = np_read_send(req->conn, server_event_context(),
state->handle, state->data, state->max_read);
if (subreq == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -644,7 +645,7 @@ void reply_trans(struct smb_request *req)
return;
}
- if ((state = TALLOC_P(conn, struct trans_state)) == NULL) {
+ if ((state = talloc(conn, struct trans_state)) == NULL) {
DEBUG(0, ("talloc failed\n"));
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtrans);
@@ -741,7 +742,7 @@ void reply_trans(struct smb_request *req)
goto bad_param;
}
- if((state->setup = TALLOC_ARRAY(
+ if((state->setup = talloc_array(
state, uint16, state->setup_count)) == NULL) {
DEBUG(0,("reply_trans: setup malloc fail for %u "
"bytes !\n", (unsigned int)
@@ -807,7 +808,7 @@ void reply_transs(struct smb_request *req)
START_PROFILE(SMBtranss);
- show_msg((char *)req->inbuf);
+ show_msg((const char *)req->inbuf);
if (req->wct < 8) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 13297c0222..dac91b2a40 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -34,17 +34,15 @@
#include "rpc_client/cli_spoolss.h"
#include "rpc_client/init_spoolss.h"
#include "../librpc/gen_ndr/ndr_srvsvc_c.h"
-#include "../librpc/gen_ndr/srv_samr.h"
-#include "../librpc/gen_ndr/srv_srvsvc.h"
#include "../librpc/gen_ndr/rap.h"
#include "../lib/util/binsearch.h"
#include "../libcli/auth/libcli_auth.h"
#include "rpc_client/init_lsa.h"
-#include "rpc_server/rpc_ncacn_np.h"
#include "../libcli/security/security.h"
#include "printing.h"
#include "passdb/machine_sid.h"
#include "auth.h"
+#include "rpc_server/rpc_ncacn_np.h"
#ifdef CHECK_TYPES
#undef CHECK_TYPES
@@ -614,9 +612,9 @@ static void fill_printq_info_52(struct spoolss_DriverInfo3 *driver,
{
int i;
fstring location;
- trim_string((char *)driver->driver_path, "\\print$\\WIN40\\0\\", 0);
- trim_string((char *)driver->data_file, "\\print$\\WIN40\\0\\", 0);
- trim_string((char *)driver->help_file, "\\print$\\WIN40\\0\\", 0);
+ trim_string(discard_const_p(char, driver->driver_path), "\\print$\\WIN40\\0\\", 0);
+ trim_string(discard_const_p(char, driver->data_file), "\\print$\\WIN40\\0\\", 0);
+ trim_string(discard_const_p(char, driver->help_file), "\\print$\\WIN40\\0\\", 0);
PACKI(desc, "W", 0x0400); /* don't know */
PACKS(desc, "z", driver->driver_name); /* long printer name */
@@ -643,7 +641,7 @@ static void fill_printq_info_52(struct spoolss_DriverInfo3 *driver,
for ( i=0; i<count && driver->dependent_files && *driver->dependent_files[i]; i++)
{
- trim_string((char *)driver->dependent_files[i], "\\print$\\WIN40\\0\\", 0);
+ trim_string(discard_const_p(char, driver->dependent_files[i]), "\\print$\\WIN40\\0\\", 0);
PACKS(desc,"z",driver->dependent_files[i]); /* driver files to copy */
DEBUG(3,("Dependent File: %s:\n", driver->dependent_files[i]));
}
@@ -1429,7 +1427,7 @@ static int fill_srv_info(struct srv_info_struct *service,
static int srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
{
- return StrCaseCmp(s1->name,s2->name);
+ return strcasecmp_m(s1->name,s2->name);
}
/****************************************************************************
@@ -1598,7 +1596,7 @@ static int srv_name_match(const char *n1, const char *n2)
* the server will return a list of servers that exist on
* the network greater than or equal to the FirstNameToReturn.
*/
- int ret = StrCaseCmp(n1, n2);
+ int ret = strcasecmp_m(n1, n2);
if (ret <= 0) {
return 0;
@@ -1710,7 +1708,7 @@ static bool api_RNetServerEnum3(struct smbd_server_connection *sconn,
*/
for (;first > 0;) {
int ret;
- ret = StrCaseCmp(first_name,
+ ret = strcasecmp_m(first_name,
servers[first-1].name);
if (ret > 0) {
break;
@@ -2094,7 +2092,7 @@ static bool api_RNetShareEnum(struct smbd_server_connection *sconn,
/* Ensure all the usershares are loaded. */
become_root();
load_registry_shares();
- count = load_usershare_shares();
+ count = load_usershare_shares(sconn);
unbecome_root();
data_len = fixed_len = string_len = 0;
@@ -2256,7 +2254,7 @@ static bool api_RNetShareAdd(struct smbd_server_connection *sconn,
return false;
}
- status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
+ status = rpc_pipe_open_interface(mem_ctx, &ndr_table_srvsvc.syntax_id,
conn->session_info,
&conn->sconn->client_id,
conn->sconn->msg_ctx,
@@ -2367,7 +2365,7 @@ static bool api_RNetGroupEnum(struct smbd_server_connection *sconn,
return False;
}
- status = rpc_pipe_open_internal(
+ status = rpc_pipe_open_interface(
talloc_tos(), &ndr_table_samr.syntax_id,
conn->session_info, &conn->sconn->client_id,
conn->sconn->msg_ctx, &samr_pipe);
@@ -2379,7 +2377,7 @@ static bool api_RNetGroupEnum(struct smbd_server_connection *sconn,
b = samr_pipe->binding_handle;
- status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+ status = dcerpc_samr_Connect2(b, talloc_tos(), lp_netbios_name(),
SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
&result);
if (!NT_STATUS_IS_OK(status)) {
@@ -2573,7 +2571,7 @@ static bool api_NetUserGetGroups(struct smbd_server_connection *sconn,
p = *rdata;
endp = *rdata + *rdata_len;
- status = rpc_pipe_open_internal(
+ status = rpc_pipe_open_interface(
talloc_tos(), &ndr_table_samr.syntax_id,
conn->session_info, &conn->sconn->client_id,
conn->sconn->msg_ctx, &samr_pipe);
@@ -2585,7 +2583,7 @@ static bool api_NetUserGetGroups(struct smbd_server_connection *sconn,
b = samr_pipe->binding_handle;
- status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+ status = dcerpc_samr_Connect2(b, talloc_tos(), lp_netbios_name(),
SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
&result);
if (!NT_STATUS_IS_OK(status)) {
@@ -2765,7 +2763,7 @@ static bool api_RNetUserEnum(struct smbd_server_connection *sconn,
p = *rdata;
endp = *rdata + *rdata_len;
- status = rpc_pipe_open_internal(
+ status = rpc_pipe_open_interface(
talloc_tos(), &ndr_table_samr.syntax_id,
conn->session_info, &conn->sconn->client_id,
conn->sconn->msg_ctx, &samr_pipe);
@@ -2777,7 +2775,7 @@ static bool api_RNetUserEnum(struct smbd_server_connection *sconn,
b = samr_pipe->binding_handle;
- status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+ status = dcerpc_samr_Connect2(b, talloc_tos(), lp_netbios_name(),
SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
&result);
if (!NT_STATUS_IS_OK(status)) {
@@ -3031,7 +3029,7 @@ static bool api_SetUserPassword(struct smbd_server_connection *sconn,
ZERO_STRUCT(domain_handle);
ZERO_STRUCT(user_handle);
- status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+ status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id,
conn->session_info,
&conn->sconn->client_id,
conn->sconn->msg_ctx,
@@ -3046,7 +3044,7 @@ static bool api_SetUserPassword(struct smbd_server_connection *sconn,
b = cli->binding_handle;
status = dcerpc_samr_Connect2(b, mem_ctx,
- global_myname(),
+ lp_netbios_name(),
SAMR_ACCESS_CONNECT_TO_SERVER |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_LOOKUP_DOMAIN,
@@ -3282,7 +3280,7 @@ static bool api_SamOEMChangePassword(struct smbd_server_connection *sconn,
memcpy(password.data, data, 516);
memcpy(hash.hash, data+516, 16);
- status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+ status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id,
conn->session_info,
&conn->sconn->client_id,
conn->sconn->msg_ctx,
@@ -3296,7 +3294,7 @@ static bool api_SamOEMChangePassword(struct smbd_server_connection *sconn,
b = cli->binding_handle;
- init_lsa_AsciiString(&server, global_myname());
+ init_lsa_AsciiString(&server, lp_netbios_name());
init_lsa_AsciiString(&account, user);
status = dcerpc_samr_OemChangePasswordUser2(b, mem_ctx,
@@ -3866,7 +3864,7 @@ static bool api_RNetServerGetInfo(struct smbd_server_connection *sconn,
p = *rdata;
p2 = p + struct_len;
- status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
+ status = rpc_pipe_open_interface(mem_ctx, &ndr_table_srvsvc.syntax_id,
conn->session_info,
&conn->sconn->client_id,
conn->sconn->msg_ctx,
@@ -4029,8 +4027,8 @@ static bool api_NetWkstaGetInfo(struct smbd_server_connection *sconn,
}
p += 4;
- SCVAL(p,0,lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
- SCVAL(p,1,lp_minor_announce_version()); /* system version - e.g .1 in 4.1 */
+ SCVAL(p,0,SAMBA_MAJOR_NBT_ANNOUNCE_VERSION); /* system version - e.g 4 in 4.1 */
+ SCVAL(p,1,SAMBA_MINOR_NBT_ANNOUNCE_VERSION); /* system version - e.g .1 in 4.1 */
p += 2;
SIVAL(p,0,PTR_DIFF(p2,*rdata));
@@ -4293,7 +4291,7 @@ static bool api_RNetUserGetInfo(struct smbd_server_connection *sconn,
ZERO_STRUCT(domain_handle);
ZERO_STRUCT(user_handle);
- status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+ status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id,
conn->session_info,
&conn->sconn->client_id,
conn->sconn->msg_ctx,
@@ -4308,7 +4306,7 @@ static bool api_RNetUserGetInfo(struct smbd_server_connection *sconn,
b = cli->binding_handle;
status = dcerpc_samr_Connect2(b, mem_ctx,
- global_myname(),
+ lp_netbios_name(),
SAMR_ACCESS_CONNECT_TO_SERVER |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_LOOKUP_DOMAIN,
diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c
index d98b350a37..c196a13ed0 100644
--- a/source3/smbd/mangle_hash.c
+++ b/source3/smbd/mangle_hash.c
@@ -25,6 +25,7 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "mangle.h"
+#include "util_tdb.h"
/* -------------------------------------------------------------------------- **
* Other stuff...
@@ -86,7 +87,7 @@ static void init_valid_table(void)
return;
}
- valid_table = (uint8 *)map_file(data_path("valid.dat"), 0x10000);
+ valid_table = (uint8 *)map_file(data_path(talloc_tos(), "valid.dat"), 0x10000);
if (!valid_table) {
smb_panic("Could not load valid.dat file required for mangle method=hash");
return;
@@ -473,7 +474,7 @@ static void cache_mangled_name( const char mangled_name[13],
return;
/* Init the string lengths. */
- safe_strcpy(mangled_name_key, mangled_name, sizeof(mangled_name_key)-1);
+ strlcpy(mangled_name_key, mangled_name, sizeof(mangled_name_key));
/* See if the extensions are unmangled. If so, store the entry
* without the extension, thus creating a "group" reverse map.
@@ -638,7 +639,7 @@ static bool to_8_3(char magic_char, const char *in, char out[13], int default_ca
if( p ) {
if( p == s )
- safe_strcpy( extension, "___", 3 );
+ strlcpy( extension, "___", 4);
else {
*p++ = 0;
while( *p && extlen < 3 ) {
@@ -670,7 +671,7 @@ static bool to_8_3(char magic_char, const char *in, char out[13], int default_ca
if( *extension ) {
out[baselen+3] = '.';
- safe_strcpy(&out[baselen+4], extension, 3);
+ strlcpy(&out[baselen+4], extension, 4);
}
SAFE_FREE(s);
@@ -738,7 +739,7 @@ static bool hash_name_to_8_3(const char *in,
if (NT_STATUS_IS_OK(is_valid_name(in_ucs2, False, False)) &&
NT_STATUS_IS_OK(is_8_3_w(in_ucs2, False))) {
TALLOC_FREE(in_ucs2);
- safe_strcpy(out, in, 12);
+ strlcpy(out, in, 13);
return True;
}
@@ -772,8 +773,13 @@ const struct mangle_fns *mangle_hash_init(void)
mangle_reset();
/* Create the in-memory tdb using our custom hash function. */
+#ifndef BUILD_TDB2
tdb_mangled_cache = tdb_open_ex("mangled_cache", 1031, TDB_INTERNAL,
(O_RDWR|O_CREAT), 0644, NULL, fast_string_hash);
+#else
+ /* FIXME: We should *never* open a tdb without logging! */
+ tdb_mangled_cache = tdb_open("mangled_cache", TDB_INTERNAL, 0, 0, NULL);
+#endif
return &mangle_hash_fns;
}
diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c
index a39bb895c2..4de80cbe31 100644
--- a/source3/smbd/mangle_hash2.c
+++ b/source3/smbd/mangle_hash2.c
@@ -705,7 +705,7 @@ static bool hash2_name_to_8_3(const char *name,
/* if the name is already a valid 8.3 name then we don't need to
* change anything */
if (is_legal_name(name) && is_8_3(name, False, False, p)) {
- safe_strcpy(new_name, name, 12);
+ strlcpy(new_name, name, 13);
return True;
}
}
diff --git a/source3/smbd/message.c b/source3/smbd/message.c
index 34997a13dc..63b08e1262 100644
--- a/source3/smbd/message.c
+++ b/source3/smbd/message.c
@@ -202,7 +202,7 @@ void reply_sendstrt(struct smb_request *req)
TALLOC_FREE(smbd_msg_state);
- smbd_msg_state = TALLOC_ZERO_P(NULL, struct msg_state);
+ smbd_msg_state = talloc_zero(NULL, struct msg_state);
if (smbd_msg_state == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -259,7 +259,7 @@ void reply_sendtxt(struct smb_request *req)
len = MIN(SVAL(msg, 0), smbreq_bufrem(req, msg+2));
- tmp = TALLOC_REALLOC_ARRAY(smbd_msg_state, smbd_msg_state->msg,
+ tmp = talloc_realloc(smbd_msg_state, smbd_msg_state->msg,
char, old_len + len);
if (tmp == NULL) {
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index ab67ac8596..47c2b1ee78 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -231,7 +231,7 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
char *oldcwd;
const char *vfs_user;
- conn = TALLOC_ZERO_P(ctx, connection_struct);
+ conn = talloc_zero(ctx, connection_struct);
if (conn == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -252,7 +252,7 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
/* needed for smbd_vfs_init() */
- if (!(conn->params = TALLOC_ZERO_P(conn, struct share_params))) {
+ if (!(conn->params = talloc_zero(conn, struct share_params))) {
DEBUG(0, ("TALLOC failed\n"));
TALLOC_FREE(conn);
return NT_STATUS_NO_MEMORY;
@@ -364,7 +364,7 @@ static bool parse_msdfs_symlink(TALLOC_CTX *ctx,
return False;
}
- alt_path = TALLOC_ARRAY(ctx, char *, MAX_REFERRAL_COUNT);
+ alt_path = talloc_array(ctx, char *, MAX_REFERRAL_COUNT);
if (!alt_path) {
return False;
}
@@ -378,7 +378,7 @@ static bool parse_msdfs_symlink(TALLOC_CTX *ctx,
DEBUG(10,("parse_msdfs_symlink: count=%d\n", count));
if (count) {
- reflist = *preflist = TALLOC_ZERO_ARRAY(ctx,
+ reflist = *preflist = talloc_zero_array(ctx,
struct referral, count);
if(reflist == NULL) {
TALLOC_FREE(alt_path);
@@ -443,7 +443,7 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
if (pp_link_target) {
bufsize = 1024;
- link_target = TALLOC_ARRAY(ctx, char, bufsize);
+ link_target = talloc_array(ctx, char, bufsize);
if (!link_target) {
return False;
}
@@ -692,7 +692,7 @@ static NTSTATUS dfs_redirect(TALLOC_CTX *ctx,
bool *ppath_contains_wcard)
{
NTSTATUS status;
- struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);
+ struct dfs_path *pdp = talloc(ctx, struct dfs_path);
if (!pdp) {
return NT_STATUS_NO_MEMORY;
@@ -794,7 +794,7 @@ static NTSTATUS self_ref(TALLOC_CTX *ctx,
*self_referralp = True;
jucn->referral_count = 1;
- if((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
+ if((ref = talloc_zero(ctx, struct referral)) == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -825,7 +825,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
int snum;
NTSTATUS status = NT_STATUS_NOT_FOUND;
bool dummy;
- struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);
+ struct dfs_path *pdp = talloc(ctx, struct dfs_path);
char *oldpath;
if (!pdp) {
@@ -899,7 +899,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
*/
jucn->referral_count = 1;
- if ((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
+ if ((ref = talloc_zero(ctx, struct referral)) == NULL) {
TALLOC_FREE(pdp);
return NT_STATUS_NO_MEMORY;
}
@@ -1233,7 +1233,7 @@ int setup_dfs_referral(connection_struct *orig_conn,
pathnamep++;
}
- junction = TALLOC_ZERO_P(ctx, struct junction_map);
+ junction = talloc_zero(ctx, struct junction_map);
if (!junction) {
*pstatus = NT_STATUS_NO_MEMORY;
talloc_destroy(ctx);
@@ -1318,7 +1318,7 @@ bool create_junction(TALLOC_CTX *ctx,
{
int snum;
bool dummy;
- struct dfs_path *pdp = TALLOC_P(ctx,struct dfs_path);
+ struct dfs_path *pdp = talloc(ctx,struct dfs_path);
NTSTATUS status;
if (!pdp) {
@@ -1630,7 +1630,7 @@ static int form_junctions(TALLOC_CTX *ctx,
jucn[cnt].comment = "";
jucn[cnt].referral_count = 1;
- ref = jucn[cnt].referral_list = TALLOC_ZERO_P(ctx, struct referral);
+ ref = jucn[cnt].referral_list = talloc_zero(ctx, struct referral);
if (jucn[cnt].referral_list == NULL) {
goto out;
}
@@ -1709,7 +1709,8 @@ out:
return cnt;
}
-struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn)
+struct junction_map *enum_msdfs_links(struct smbd_server_connection *sconn,
+ TALLOC_CTX *ctx, size_t *p_num_jn)
{
struct junction_map *jn = NULL;
int i=0;
@@ -1724,7 +1725,7 @@ struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn)
/* Ensure all the usershares are loaded. */
become_root();
load_registry_shares();
- sharecount = load_usershare_shares();
+ sharecount = load_usershare_shares(sconn);
unbecome_root();
for(i=0;i < sharecount;i++) {
@@ -1735,7 +1736,7 @@ struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn)
if (jn_count == 0) {
return NULL;
}
- jn = TALLOC_ARRAY(ctx, struct junction_map, jn_count);
+ jn = talloc_array(ctx, struct junction_map, jn_count);
if (!jn) {
return NULL;
}
@@ -1786,7 +1787,7 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx,
* Once srvstr_get_path() uses talloc it'll
* be a talloced ptr anyway.
*/
- *pp_name_out = CONST_DISCARD(char *,name_in);
+ *pp_name_out = discard_const_p(char, name_in);
}
return status;
}
diff --git a/source3/smbd/msg_idmap.c b/source3/smbd/msg_idmap.c
index b1ee60ff7f..2a00f1bbb9 100644
--- a/source3/smbd/msg_idmap.c
+++ b/source3/smbd/msg_idmap.c
@@ -27,10 +27,8 @@
#include "includes.h"
#include "smbd/smbd.h"
-#include "memcache.h"
#include "globals.h"
#include "../libcli/security/dom_sid.h"
-#include "../librpc/gen_ndr/ndr_security.h"
#include "idmap_cache.h"
#include "passdb/lookup_sid.h"
#include "auth.h"
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 6877ccc861..a6d7cc0ab3 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -224,7 +224,7 @@ DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn)
} else {
fstring myname;
char *host_princ_s = NULL;
- name_to_fqdn(myname, global_myname());
+ name_to_fqdn(myname, lp_netbios_name());
strlower_m(myname);
if (asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm())
== -1) {
@@ -234,6 +234,10 @@ DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn)
SAFE_FREE(host_princ_s);
}
+ if (blob.length == 0 || blob.data == NULL) {
+ return data_blob_null;
+ }
+
blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length);
if (blob_out.data == NULL) {
data_blob_free(&blob);
@@ -242,10 +246,10 @@ DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn)
memset(blob_out.data, '\0', 16);
- checked_strlcpy(unix_name, global_myname(), sizeof(unix_name));
+ checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name));
strlower_m(unix_name);
push_ascii_nstring(dos_name, unix_name);
- safe_strcpy((char *)blob_out.data, dos_name, 16);
+ strlcpy((char *)blob_out.data, dos_name, 17);
#ifdef DEVELOPER
/* Fix valgrind 'uninitialized bytes' issue. */
@@ -569,7 +573,7 @@ void reply_negprot(struct smb_request *req)
char **tmp;
- tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), cliprotos, char *,
+ tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
num_cliprotos+1);
if (tmp == NULL) {
DEBUG(0, ("talloc failed\n"));
@@ -712,6 +716,11 @@ void reply_negprot(struct smb_request *req)
}
TALLOC_FREE(cliprotos);
+
+ if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
+ exit_server("Failed to fork echo handler");
+ }
+
END_PROFILE(SMBnegprot);
return;
}
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index 24385c94a0..8160d5ac63 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -183,7 +183,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
SMB_ASSERT(fsp->notify == NULL);
- if (!(fsp->notify = TALLOC_ZERO_P(NULL, struct notify_change_buf))) {
+ if (!(fsp->notify = talloc_zero(NULL, struct notify_change_buf))) {
DEBUG(0, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -424,7 +424,7 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name)
return;
}
- if (!(changes = TALLOC_REALLOC_ARRAY(
+ if (!(changes = talloc_realloc(
fsp->notify, fsp->notify->changes,
struct notify_change, fsp->notify->num_changes+1))) {
DEBUG(0, ("talloc_realloc failed\n"));
@@ -520,7 +520,7 @@ struct sys_notify_context *sys_notify_context_create(connection_struct *conn,
{
struct sys_notify_context *ctx;
- if (!(ctx = TALLOC_P(mem_ctx, struct sys_notify_context))) {
+ if (!(ctx = talloc(mem_ctx, struct sys_notify_context))) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c
index a8eaf79392..a0193a4467 100644
--- a/source3/smbd/notify_internal.c
+++ b/source3/smbd/notify_internal.c
@@ -29,6 +29,8 @@
#include "dbwrap.h"
#include "smbd/smbd.h"
#include "messages.h"
+#include "lib/util/tdb_wrap.h"
+#include "util_tdb.h"
struct notify_context {
struct db_context *db_recursive;
@@ -196,7 +198,7 @@ static NTSTATUS notify_load(struct notify_context *notify, struct db_record *rec
notify->seqnum = seqnum;
talloc_free(notify->array);
- notify->array = TALLOC_ZERO_P(notify, struct notify_array);
+ notify->array = talloc_zero(notify, struct notify_array);
NT_STATUS_HAVE_NO_MEMORY(notify->array);
if (!rec) {
@@ -529,7 +531,7 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0,
depth = count_chars(e.path, '/');
- listel = TALLOC_ZERO_P(notify, struct notify_list);
+ listel = talloc_zero(notify, struct notify_list);
if (listel == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
@@ -597,7 +599,7 @@ NTSTATUS notify_remove_onelevel(struct notify_context *notify,
rec = notify->db_onelevel->fetch_locked(
notify->db_onelevel, array,
- make_tdb_data((uint8_t *)fid, sizeof(*fid)));
+ make_tdb_data((const uint8_t *)fid, sizeof(*fid)));
if (rec == NULL) {
DEBUG(10, ("notify_remove_onelevel: fetch_locked for %s failed"
"\n", file_id_string_tos(fid)));
@@ -841,7 +843,7 @@ void notify_onelevel(struct notify_context *notify, uint32_t action,
if (notify->db_onelevel->fetch(
notify->db_onelevel, array,
make_tdb_data((uint8_t *)&fid, sizeof(fid)),
- &dbuf) == -1) {
+ &dbuf) != 0) {
TALLOC_FREE(array);
return;
}
diff --git a/source3/smbd/ntquotas.c b/source3/smbd/ntquotas.c
index d0056756ac..1f4fc2d0a2 100644
--- a/source3/smbd/ntquotas.c
+++ b/source3/smbd/ntquotas.c
@@ -22,6 +22,7 @@
#include "../lib/util/util_pw.h"
#include "system/passwd.h"
#include "passdb/lookup_sid.h"
+#include "libsmb/libsmb.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_QUOTA
@@ -200,14 +201,14 @@ int vfs_get_user_ntquota_list(files_struct *fsp, SMB_NTQUOTA_LIST **qt_list)
DEBUG(15,("quota entry for id[%s] path[%s]\n",
sid_string_dbg(&sid), fsp->conn->connectpath));
- if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
+ if ((tmp_list_ent=talloc_zero(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
DEBUG(0,("TALLOC_ZERO() failed\n"));
*qt_list = NULL;
talloc_destroy(mem_ctx);
return (-1);
}
- if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
+ if ((tmp_list_ent->quotas=talloc_zero(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
DEBUG(0,("TALLOC_ZERO() failed\n"));
*qt_list = NULL;
talloc_destroy(mem_ctx);
@@ -240,7 +241,7 @@ void *init_quota_handle(TALLOC_CTX *mem_ctx)
if (!mem_ctx)
return False;
- qt_handle = TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_HANDLE);
+ qt_handle = talloc_zero(mem_ctx,SMB_NTQUOTA_HANDLE);
if (qt_handle==NULL) {
DEBUG(0,("TALLOC_ZERO() failed\n"));
return NULL;
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 71f20ac77e..5fdb07d769 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -29,6 +29,7 @@
#include "auth.h"
#include "ntioctl.h"
#include "smbprofile.h"
+#include "libsmb/libsmb.h"
extern const struct generic_mapping file_generic_mapping;
@@ -1363,7 +1364,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
/* Ensure attributes match. */
fattr = dos_mode(conn, smb_fname_src);
- if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) {
+ if ((fattr & ~attrs) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
status = NT_STATUS_NO_SUCH_FILE;
goto out;
}
@@ -1450,7 +1451,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
status = close_file(NULL, fsp2, NORMAL_CLOSE);
- /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it
+ /* Grrr. We have to do this as open_file_ntcreate adds FILE_ATTRIBUTE_ARCHIVE when it
creates the file. This isn't the correct thing to do in the copy
case. JRA */
if (!parent_dirname(talloc_tos(), smb_fname_dst->base_name, &parent,
@@ -2213,8 +2214,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
* Allocate the correct amount and return the pointer to let
* it be deallocated when we return.
*/
- SHADOW_COPY_DATA *shadow_data = NULL;
- TALLOC_CTX *shadow_mem_ctx = NULL;
+ struct shadow_copy_data *shadow_data = NULL;
bool labels = False;
uint32 labels_data_count = 0;
uint32 i;
@@ -2235,28 +2235,19 @@ static void call_nt_transact_ioctl(connection_struct *conn,
labels = True;
}
- shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
- if (shadow_mem_ctx == NULL) {
- DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
-
- shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);
+ shadow_data = talloc_zero(talloc_tos(),
+ struct shadow_copy_data);
if (shadow_data == NULL) {
DEBUG(0,("TALLOC_ZERO() failed!\n"));
- talloc_destroy(shadow_mem_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- shadow_data->mem_ctx = shadow_mem_ctx;
-
/*
* Call the VFS routine to actually do the work.
*/
if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
- talloc_destroy(shadow_data->mem_ctx);
+ TALLOC_FREE(shadow_data);
if (errno == ENOSYS) {
DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
conn->connectpath));
@@ -2281,14 +2272,14 @@ static void call_nt_transact_ioctl(connection_struct *conn,
if (max_data_count<data_count) {
DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
max_data_count,data_count));
- talloc_destroy(shadow_data->mem_ctx);
+ TALLOC_FREE(shadow_data);
reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
return;
}
pdata = nttrans_realloc(ppdata, data_count);
if (pdata == NULL) {
- talloc_destroy(shadow_data->mem_ctx);
+ TALLOC_FREE(shadow_data);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -2321,7 +2312,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
}
}
- talloc_destroy(shadow_data->mem_ctx);
+ TALLOC_FREE(shadow_data);
send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
pdata, data_count);
@@ -2861,7 +2852,7 @@ static void handle_nttrans(connection_struct *conn,
{
if (get_Protocol() >= PROTOCOL_NT1) {
req->flags2 |= 0x40; /* IS_LONG_NAME */
- SSVAL(req->inbuf,smb_flg2,req->flags2);
+ SSVAL(discard_const_p(uint8_t, req->inbuf),smb_flg2,req->flags2);
}
@@ -3029,7 +3020,7 @@ void reply_nttrans(struct smb_request *req)
return;
}
- if ((state = TALLOC_P(conn, struct trans_state)) == NULL) {
+ if ((state = talloc(conn, struct trans_state)) == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBnttrans);
return;
@@ -3203,7 +3194,7 @@ void reply_nttranss(struct smb_request *req)
START_PROFILE(SMBnttranss);
- show_msg((char *)req->inbuf);
+ show_msg((const char *)req->inbuf);
if (req->wct < 18) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 14e6bf9b4e..86a5924f16 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -77,6 +77,16 @@ NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
NTSTATUS status;
struct security_descriptor *sd = NULL;
+ if ((access_mask & DELETE_ACCESS) && !lp_acl_check_permissions(SNUM(conn))) {
+ *access_granted = access_mask;
+
+ DEBUG(10,("smbd_check_open_rights: not checking ACL "
+ "on DELETE_ACCESS on file %s. Granting 0x%x\n",
+ smb_fname_str_dbg(smb_fname),
+ (unsigned int)*access_granted ));
+ return NT_STATUS_OK;
+ }
+
status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
(SECINFO_OWNER |
SECINFO_GROUP |
@@ -241,6 +251,8 @@ void change_file_owner_to_parent(connection_struct *conn,
DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
"parent directory uid %u.\n", fsp_str_dbg(fsp),
(unsigned int)smb_fname_parent->st.st_ex_uid));
+ /* Ensure the uid entry is updated. */
+ fsp->fsp_name->st.st_ex_uid = smb_fname_parent->st.st_ex_uid;
}
TALLOC_FREE(smb_fname_parent);
@@ -316,10 +328,9 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
/* Ensure we're pointing at the same place. */
if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
- smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino ||
- smb_fname_cwd->st.st_ex_mode != psbuf->st_ex_mode ) {
+ smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino) {
DEBUG(0,("change_dir_owner_to_parent: "
- "device/inode/mode on directory %s changed. "
+ "device/inode on directory %s changed. "
"Refusing to chown !\n", fname ));
status = NT_STATUS_ACCESS_DENIED;
goto chdir;
@@ -350,6 +361,8 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
"directory %s to parent directory uid %u.\n",
fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
+ /* Ensure the uid entry is updated. */
+ psbuf->st_ex_uid = smb_fname_parent->st.st_ex_uid;
}
chdir:
@@ -378,6 +391,7 @@ static NTSTATUS open_file(files_struct *fsp,
int accmode = (flags & O_ACCMODE);
int local_flags = flags;
bool file_existed = VALID_STAT(fsp->fsp_name->st);
+ bool file_created = false;
fsp->fh->fd = -1;
errno = EPERM;
@@ -477,23 +491,7 @@ static NTSTATUS open_file(files_struct *fsp,
}
if ((local_flags & O_CREAT) && !file_existed) {
-
- /* Inherit the ACL if required */
- if (lp_inherit_perms(SNUM(conn))) {
- inherit_access_posix_acl(conn, parent_dir,
- smb_fname->base_name,
- unx_mode);
- }
-
- /* Change the owner if required. */
- if (lp_inherit_owner(SNUM(conn))) {
- change_file_owner_to_parent(conn, parent_dir,
- fsp);
- }
-
- notify_fname(conn, NOTIFY_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- smb_fname->base_name);
+ file_created = true;
}
} else {
@@ -603,6 +601,47 @@ static NTSTATUS open_file(files_struct *fsp,
fd_close(fsp);
return status;
}
+
+ if (file_created) {
+ bool need_re_stat = false;
+ /* Do all inheritance work after we've
+ done a successful stat call and filled
+ in the stat struct in fsp->fsp_name. */
+
+ /* Inherit the ACL if required */
+ if (lp_inherit_perms(SNUM(conn))) {
+ inherit_access_posix_acl(conn, parent_dir,
+ smb_fname->base_name,
+ unx_mode);
+ need_re_stat = true;
+ }
+
+ /* Change the owner if required. */
+ if (lp_inherit_owner(SNUM(conn))) {
+ change_file_owner_to_parent(conn, parent_dir,
+ fsp);
+ need_re_stat = true;
+ }
+
+ if (need_re_stat) {
+ if (fsp->fh->fd == -1) {
+ ret = SMB_VFS_STAT(conn, smb_fname);
+ } else {
+ ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+ /* If we have an fd, this stat should succeed. */
+ if (ret == -1) {
+ DEBUG(0,("Error doing fstat on open file %s "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno) ));
+ }
+ }
+ }
+
+ notify_fname(conn, NOTIFY_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ smb_fname->base_name);
+ }
}
/*
@@ -949,7 +988,9 @@ static NTSTATUS send_break_message(files_struct *fsp,
* Do internal consistency checks on the share mode for a file.
*/
-static void find_oplock_types(struct share_mode_lock *lck,
+static void find_oplock_types(files_struct *fsp,
+ int oplock_request,
+ struct share_mode_lock *lck,
struct share_mode_entry **pp_batch,
struct share_mode_entry **pp_ex_or_batch,
bool *got_level2,
@@ -962,11 +1003,27 @@ static void find_oplock_types(struct share_mode_lock *lck,
*got_level2 = false;
*got_no_oplock = false;
+ /* Ignore stat or internal opens, as is done in
+ delay_for_batch_oplocks() and
+ delay_for_exclusive_oplocks().
+ */
+ if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
+ return;
+ }
+
for (i=0; i<lck->num_share_modes; i++) {
if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
continue;
}
+ if (lck->share_modes[i].op_type == NO_OPLOCK &&
+ is_stat_open(lck->share_modes[i].access_mask)) {
+ /* We ignore stat opens in the table - they
+ always have NO_OPLOCK and never get or
+ cause breaks. JRA. */
+ continue;
+ }
+
if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
/* batch - can only be one. */
if (*pp_ex_or_batch || *pp_batch || *got_level2 || *got_no_oplock) {
@@ -1037,18 +1094,8 @@ static bool delay_for_exclusive_oplocks(files_struct *fsp,
return false;
}
-static bool file_has_brlocks(files_struct *fsp)
-{
- struct byte_range_lock *br_lck;
-
- br_lck = brl_get_locks_readonly(fsp);
- if (!br_lck)
- return false;
-
- return br_lck->num_locks > 0 ? true : false;
-}
-
static void grant_fsp_oplock_type(files_struct *fsp,
+ const struct byte_range_lock *br_lck,
int oplock_request,
bool got_level2_oplock,
bool got_a_none_oplock)
@@ -1066,7 +1113,7 @@ static void grant_fsp_oplock_type(files_struct *fsp,
DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n",
fsp->oplock_type, fsp_str_dbg(fsp)));
return;
- } else if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
+ } else if (br_lck && br_lck->num_locks > 0) {
DEBUG(10,("grant_fsp_oplock_type: file %s has byte range locks\n",
fsp_str_dbg(fsp)));
fsp->oplock_type = NO_OPLOCK;
@@ -1544,6 +1591,55 @@ void remove_deferred_open_entry(struct file_id id, uint64_t mid,
}
}
+/****************************************************************
+ Ensure we get the brlock lock followed by the share mode lock
+ in the correct order to prevent deadlocks if other smbd's are
+ using the brlock database on this file simultaneously with this open
+ (that code also gets the locks in brlock -> share mode lock order).
+****************************************************************/
+
+static bool acquire_ordered_locks(TALLOC_CTX *mem_ctx,
+ files_struct *fsp,
+ const struct file_id id,
+ const char *connectpath,
+ const struct smb_filename *smb_fname,
+ const struct timespec *p_old_write_time,
+ struct share_mode_lock **p_lck,
+ struct byte_range_lock **p_br_lck)
+{
+ /* Ordering - we must get the br_lck for this
+ file before the share mode. */
+ if (lp_locking(fsp->conn->params)) {
+ *p_br_lck = brl_get_locks_readonly(fsp);
+ if (*p_br_lck == NULL) {
+ DEBUG(0, ("Could not get br_lock\n"));
+ return false;
+ }
+ /* Note - we don't need to free the returned
+ br_lck explicitly as it was allocated on talloc_tos()
+ and so will be autofreed (and release the lock)
+ once the frame context disappears.
+
+ If it was set to fsp->brlock_rec then it was
+ talloc_move'd to hang off the fsp pointer and
+ in this case is guarenteed to not be holding the
+ lock on the brlock database. */
+ }
+
+ *p_lck = get_share_mode_lock(mem_ctx,
+ id,
+ connectpath,
+ smb_fname,
+ p_old_write_time);
+
+ if (*p_lck == NULL) {
+ DEBUG(0, ("Could not get share mode lock\n"));
+ TALLOC_FREE(*p_br_lck);
+ return false;
+ }
+ return true;
+}
+
/****************************************************************************
Open a file with a share mode. Passed in an already created files_struct *.
****************************************************************************/
@@ -1622,9 +1718,9 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
new_dos_attributes = 0;
} else {
- /* We add aARCH to this as this mode is only used if the file is
+ /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
* created new. */
- unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
+ unx_mode = unix_mode(conn, new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
smb_fname, parent_dir);
}
@@ -1888,6 +1984,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
if (file_existed) {
+ struct byte_range_lock *br_lck = NULL;
struct share_mode_entry *batch_entry = NULL;
struct share_mode_entry *exclusive_entry = NULL;
bool got_level2_oplock = false;
@@ -1896,17 +1993,21 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
struct timespec old_write_time = smb_fname->st.st_ex_mtime;
id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- lck = get_share_mode_lock(talloc_tos(), id,
- conn->connectpath,
- smb_fname, &old_write_time);
-
- if (lck == NULL) {
- DEBUG(0, ("Could not get share mode lock\n"));
+ if (!acquire_ordered_locks(talloc_tos(),
+ fsp,
+ id,
+ conn->connectpath,
+ smb_fname,
+ &old_write_time,
+ &lck,
+ &br_lck)) {
return NT_STATUS_SHARING_VIOLATION;
}
/* Get the types we need to examine. */
- find_oplock_types(lck,
+ find_oplock_types(fsp,
+ oplock_request,
+ lck,
&batch_entry,
&exclusive_entry,
&got_level2_oplock,
@@ -1953,6 +2054,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
grant_fsp_oplock_type(fsp,
+ br_lck,
oplock_request,
got_level2_oplock,
got_a_none_oplock);
@@ -2109,13 +2211,12 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
open_access_mask);
if (!NT_STATUS_IS_OK(fsp_open)) {
- if (lck != NULL) {
- TALLOC_FREE(lck);
- }
+ TALLOC_FREE(lck);
return fsp_open;
}
if (!file_existed) {
+ struct byte_range_lock *br_lck = NULL;
struct share_mode_entry *batch_entry = NULL;
struct share_mode_entry *exclusive_entry = NULL;
bool got_level2_oplock = false;
@@ -2138,20 +2239,21 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
id = fsp->file_id;
- lck = get_share_mode_lock(talloc_tos(), id,
- conn->connectpath,
- smb_fname, &old_write_time);
-
- if (lck == NULL) {
- DEBUG(0, ("open_file_ntcreate: Could not get share "
- "mode lock for %s\n",
- smb_fname_str_dbg(smb_fname)));
- fd_close(fsp);
+ if (!acquire_ordered_locks(talloc_tos(),
+ fsp,
+ id,
+ conn->connectpath,
+ smb_fname,
+ &old_write_time,
+ &lck,
+ &br_lck)) {
return NT_STATUS_SHARING_VIOLATION;
}
/* Get the types we need to examine. */
- find_oplock_types(lck,
+ find_oplock_types(fsp,
+ oplock_request,
+ lck,
&batch_entry,
&exclusive_entry,
&got_level2_oplock,
@@ -2194,8 +2296,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
if (!NT_STATUS_IS_OK(status)) {
struct deferred_open_record state;
- fd_close(fsp);
-
state.delayed_for_oplocks = False;
state.id = id;
@@ -2211,10 +2311,12 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
req, &state);
}
TALLOC_FREE(lck);
+ fd_close(fsp);
return status;
}
grant_fsp_oplock_type(fsp,
+ br_lck,
oplock_request,
got_level2_oplock,
got_a_none_oplock);
@@ -2335,7 +2437,8 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
new_file_created = True;
}
- set_share_mode(lck, fsp, get_current_uid(conn), 0,
+ set_share_mode(lck, fsp, get_current_uid(conn),
+ req ? req->mid : 0,
fsp->oplock_type);
/* Handle strange delete on close create semantics. */
@@ -2361,7 +2464,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
lp_store_dos_attributes(SNUM(conn))) {
if (!posix_open) {
if (file_set_dosmode(conn, smb_fname,
- new_dos_attributes | aARCH,
+ new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
parent_dir, true) == 0) {
unx_mode = smb_fname->st.st_ex_mode;
}
@@ -2475,6 +2578,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
char *parent_dir;
NTSTATUS status;
bool posix_open = false;
+ bool need_re_stat = false;
if(!CAN_WRITE(conn)) {
DEBUG(5,("mkdir_internal: failing create on read-only share "
@@ -2496,7 +2600,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
posix_open = true;
mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
} else {
- mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
+ mode = unix_mode(conn, FILE_ATTRIBUTE_DIRECTORY, smb_dname, parent_dir);
}
if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
@@ -2521,7 +2625,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
if (lp_store_dos_attributes(SNUM(conn))) {
if (!posix_open) {
file_set_dosmode(conn, smb_dname,
- file_attributes | aDIR,
+ file_attributes | FILE_ATTRIBUTE_DIRECTORY,
parent_dir, true);
}
}
@@ -2529,6 +2633,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
if (lp_inherit_perms(SNUM(conn))) {
inherit_access_posix_acl(conn, parent_dir,
smb_dname->base_name, mode);
+ need_re_stat = true;
}
if (!posix_open) {
@@ -2543,6 +2648,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
SMB_VFS_CHMOD(conn, smb_dname->base_name,
(smb_dname->st.st_ex_mode |
(mode & ~smb_dname->st.st_ex_mode)));
+ need_re_stat = true;
}
}
@@ -2551,6 +2657,15 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
change_dir_owner_to_parent(conn, parent_dir,
smb_dname->base_name,
&smb_dname->st);
+ need_re_stat = true;
+ }
+
+ if (need_re_stat) {
+ if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
+ DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
+ smb_fname_str_dbg(smb_dname), strerror(errno)));
+ return map_nt_error_from_unix(errno);
+ }
}
notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
@@ -2828,7 +2943,8 @@ static NTSTATUS open_directory(connection_struct *conn,
return status;
}
- set_share_mode(lck, fsp, get_current_uid(conn), 0, NO_OPLOCK);
+ set_share_mode(lck, fsp, get_current_uid(conn),
+ req ? req->mid : 0, NO_OPLOCK);
/* For directories the delete on close bit at open time seems
always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
@@ -3018,7 +3134,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn,
return NT_STATUS_OK;
}
- streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
+ streams = talloc_array(talloc_tos(), files_struct *, num_streams);
if (streams == NULL) {
DEBUG(0, ("talloc failed\n"));
status = NT_STATUS_NO_MEMORY;
@@ -3172,8 +3288,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
/* Setting FILE_SHARE_DELETE is the hint. */
- if (lp_acl_check_permissions(SNUM(conn))
- && (create_disposition != FILE_CREATE)
+ if ((create_disposition != FILE_CREATE)
&& (access_mask & DELETE_ACCESS)
&& (!(can_delete_file_in_directory(conn, smb_fname) ||
can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
@@ -3531,7 +3646,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
* Copy in the base directory name.
*/
- parent_fname = TALLOC_ARRAY(talloc_tos(), char,
+ parent_fname = talloc_array(talloc_tos(), char,
dir_name_len+2);
if (parent_fname == NULL) {
status = NT_STATUS_NO_MEMORY;
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 087d6ef045..284b0321aa 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -224,7 +224,7 @@ bool should_notify_deferred_opens()
static char *new_break_message_smb1(TALLOC_CTX *mem_ctx,
files_struct *fsp, int cmd)
{
- char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0);
+ char *result = talloc_array(mem_ctx, char, smb_size + 8*2 + 0);
if (result == NULL) {
DEBUG(0, ("talloc failed\n"));
@@ -353,7 +353,7 @@ static void add_oplock_timeout_handler(files_struct *fsp)
}
fsp->oplock_timeout =
- event_add_timed(smbd_event_context(), fsp,
+ event_add_timed(server_event_context(), fsp,
timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
oplock_timeout_handler, fsp);
@@ -459,7 +459,7 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
message_to_share_mode_entry(&msg, (char *)data->data);
DEBUG(10, ("Got oplock async level 2 break message from pid %s: "
- "%s/%lu\n", procid_str(talloc_tos(), &src),
+ "%s/%lu\n", server_id_str(talloc_tos(), &src),
file_id_string_tos(&msg.id), msg.share_file_id));
fsp = initial_break_processing(sconn, msg.id, msg.share_file_id);
@@ -510,7 +510,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
message_to_share_mode_entry(&msg, (char *)data->data);
DEBUG(10, ("Got oplock break message from pid %s: %s/%lu\n",
- procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
+ server_id_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
msg.share_file_id));
fsp = initial_break_processing(sconn, msg.id, msg.share_file_id);
@@ -617,7 +617,7 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
file_id = (unsigned long)IVAL(data->data, 24);
DEBUG(10, ("Got kernel oplock break message from pid %s: %s/%u\n",
- procid_str(talloc_tos(), &src), file_id_string_tos(&id),
+ server_id_str(talloc_tos(), &src), file_id_string_tos(&id),
(unsigned int)file_id));
fsp = initial_break_processing(sconn, id, file_id);
@@ -704,7 +704,7 @@ static void process_oplock_break_response(struct messaging_context *msg_ctx,
message_to_share_mode_entry(&msg, (char *)data->data);
DEBUG(10, ("Got oplock break response from pid %s: %s/%lu mid %llu\n",
- procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
+ server_id_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
msg.share_file_id, (unsigned long long)msg.op_mid));
schedule_deferred_open_message_smb(msg.op_mid);
@@ -732,7 +732,7 @@ static void process_open_retry_message(struct messaging_context *msg_ctx,
message_to_share_mode_entry(&msg, (char *)data->data);
DEBUG(10, ("Got open retry msg from pid %s: %s mid %llu\n",
- procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
+ server_id_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
(unsigned long long)msg.op_mid));
schedule_deferred_open_message_smb(msg.op_mid);
@@ -849,7 +849,7 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp,
TALLOC_FREE(lck);
}
-void contend_level2_oplocks_begin(files_struct *fsp,
+void smbd_contend_level2_oplocks_begin(files_struct *fsp,
enum level2_contention_type type)
{
if (koplocks && koplocks->ops->contend_level2_oplocks_begin) {
@@ -860,7 +860,7 @@ void contend_level2_oplocks_begin(files_struct *fsp,
contend_level2_oplocks_begin_default(fsp, type);
}
-void contend_level2_oplocks_end(files_struct *fsp,
+void smbd_contend_level2_oplocks_end(files_struct *fsp,
enum level2_contention_type type)
{
/* Only kernel oplocks implement this so far */
diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c
index 207952d040..ef737efd22 100644
--- a/source3/smbd/oplock_irix.c
+++ b/source3/smbd/oplock_irix.c
@@ -332,7 +332,7 @@ struct kernel_oplocks *irix_init_kernel_oplocks(TALLOC_CTX *mem_ctx)
ctx->read_fd = pfd[0];
ctx->write_fd = pfd[1];
- ctx->read_fde = event_add_fd(smbd_event_context(),
+ ctx->read_fde = event_add_fd(server_event_context(),
ctx,
ctx->read_fd,
EVENT_FD_READ,
diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index 4f243e2e9f..19f4d6e06d 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -210,7 +210,7 @@ struct kernel_oplocks *linux_init_kernel_oplocks(TALLOC_CTX *mem_ctx)
ctx->ops = &linux_koplocks;
- se = tevent_add_signal(smbd_event_context(),
+ se = tevent_add_signal(server_event_context(),
ctx,
RT_SIGNAL_LEASE, SA_SIGINFO,
linux_oplock_signal_handler,
diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c
index dbf465ca63..4717b1faf7 100644
--- a/source3/smbd/oplock_onefs.c
+++ b/source3/smbd/oplock_onefs.c
@@ -709,7 +709,7 @@ struct kernel_oplocks *onefs_init_kernel_oplocks(TALLOC_CTX *mem_ctx)
DEBUG(10, ("oplock event_fd = %d\n", ctx->onefs_event_fd));
/* Register the oplock event_fd with samba's event system */
- ctx->read_fde = event_add_fd(smbd_event_context(),
+ ctx->read_fde = event_add_fd(server_event_context(),
ctx,
ctx->onefs_event_fd,
EVENT_FD_READ,
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 720b1bf4c2..69b37596c5 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -549,7 +549,7 @@ static char *validate_group(struct smbd_server_connection *sconn,
DEBUG(10,("validate_group: = gr_mem = "
"%s\n", gptr->gr_mem[i]));
- safe_strcpy(member, gptr->gr_mem[i],
+ strlcpy(member, gptr->gr_mem[i],
list_len - (member-member_list));
member += member_len;
}
@@ -644,7 +644,7 @@ bool authorise_login(struct smbd_server_connection *sconn,
get_session_workgroup(sconn),
user2,password)) {
ok = True;
- fstrcpy(user,user2);
+ strlcpy(user,user2,sizeof(fstring));
DEBUG(3,("authorise_login: ACCEPTED: session "
"list username (%s) and given "
"password ok\n", user));
@@ -695,7 +695,7 @@ bool authorise_login(struct smbd_server_connection *sconn,
get_session_workgroup(sconn),
user2,password)) {
ok = True;
- fstrcpy(user,user2);
+ strlcpy(user,user2,sizeof(fstring));
DEBUG(3,("authorise_login: ACCEPTED: "
"user list username and "
"given password ok (%s)\n",
@@ -714,7 +714,7 @@ bool authorise_login(struct smbd_server_connection *sconn,
fstrcpy(guestname,lp_guestaccount());
guest_pw = Get_Pwnam_alloc(talloc_tos(), guestname);
if (guest_pw != NULL) {
- fstrcpy(user,guestname);
+ strlcpy(user,guestname,sizeof(fstring));
ok = True;
DEBUG(3,("authorise_login: ACCEPTED: guest account "
"and guest ok (%s)\n", user));
diff --git a/source3/smbd/perfcount.c b/source3/smbd/perfcount.c
index 3bc83b98d5..1561893758 100644
--- a/source3/smbd/perfcount.c
+++ b/source3/smbd/perfcount.c
@@ -85,7 +85,7 @@ NTSTATUS smb_register_perfcounter(int interface_version, const char *name,
entry = SMB_XMALLOC_P(struct smb_perfcount_module);
entry->name = smb_xstrdup(name);
- entry->handlers = (struct smb_perfcount_handlers*) handlers;
+ entry->handlers = discard_const_p(struct smb_perfcount_handlers, handlers);
DLIST_ADD(modules, entry);
DEBUG(3, ("Successfully added perfcounter module '%s'\n", name));
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 89d6c8dfca..2de48adcbc 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -29,6 +29,7 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "libcli/security/security.h"
+#include "rpc_server/srv_pipe_hnd.h"
#define PIPE "\\PIPE\\"
#define PIPELEN strlen(PIPE)
@@ -202,7 +203,7 @@ void reply_pipe_write(struct smb_request *req)
DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", (int)fsp->fnum,
fsp_str_dbg(fsp), (int)state->numtowrite));
- subreq = np_write_send(state, smbd_event_context(),
+ subreq = np_write_send(state, server_event_context(),
fsp->fake_file_handle, data, state->numtowrite);
if (subreq == NULL) {
TALLOC_FREE(state);
@@ -269,7 +270,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
{
files_struct *fsp = file_fsp(req, SVAL(req->vwv+2, 0));
int smb_doff = SVAL(req->vwv+11, 0);
- uint8_t *data;
+ const uint8_t *data;
struct pipe_write_andx_state *state;
struct tevent_req *subreq;
@@ -298,7 +299,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n",
(int)fsp->fnum, fsp_str_dbg(fsp), (int)state->numtowrite));
- data = (uint8_t *)smb_base(req->inbuf) + smb_doff;
+ data = (const uint8_t *)smb_base(req->inbuf) + smb_doff;
if (state->pipe_start_message_raw) {
/*
@@ -318,7 +319,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
state->numtowrite -= 2;
}
- subreq = np_write_send(state, smbd_event_context(),
+ subreq = np_write_send(state, server_event_context(),
fsp->fake_file_handle, data, state->numtowrite);
if (subreq == NULL) {
TALLOC_FREE(state);
@@ -425,7 +426,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
state->outbuf = req->outbuf;
req->outbuf = NULL;
- subreq = np_read_send(state, smbd_event_context(),
+ subreq = np_read_send(state, server_event_context(),
fsp->fake_file_handle, data,
state->smb_maxcnt);
if (subreq == NULL) {
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 9252ee639f..da25a52b8d 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -3687,7 +3687,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
num_aces += parent_sd->dacl->num_aces;
- if((new_ace = TALLOC_ZERO_ARRAY(mem_ctx, struct security_ace,
+ if((new_ace = talloc_zero_array(mem_ctx, struct security_ace,
num_aces)) == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -4744,13 +4744,13 @@ struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fna
struct fd_handle fh;
NTSTATUS status;
- conn = TALLOC_ZERO_P(ctx, connection_struct);
+ conn = talloc_zero(ctx, connection_struct);
if (conn == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
- if (!(conn->params = TALLOC_P(conn, struct share_params))) {
+ if (!(conn->params = talloc(conn, struct share_params))) {
DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n"));
TALLOC_FREE(conn);
return NULL;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 248b3e403d..f3f532fbae 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -19,6 +19,7 @@
*/
#include "includes.h"
+#include "../lib/tsocket/tsocket.h"
#include "system/filesys.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
@@ -32,6 +33,8 @@
#include "auth.h"
#include "messages.h"
#include "smbprofile.h"
+#include "rpc_server/spoolss/srv_spoolss_nt.h"
+#include "libsmb/libsmb.h"
extern bool global_machine_password_needs_changing;
@@ -318,7 +321,7 @@ static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
/* Copy the header we've written. */
- *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
+ *buffer = (char *)talloc_memdup(mem_ctx,
writeX_header,
sizeof(writeX_header));
@@ -343,7 +346,7 @@ static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
* talloc and return.
*/
- *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
+ *buffer = talloc_array(mem_ctx, char, len+4);
if (*buffer == NULL) {
DEBUG(0, ("Could not allocate inbuf of length %d\n",
@@ -412,7 +415,7 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
* The +4 here can't wrap, we've checked the length above already.
*/
- *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
+ *buffer = talloc_array(mem_ctx, char, len+4);
if (*buffer == NULL) {
DEBUG(0, ("Could not allocate inbuf of length %d\n",
@@ -501,9 +504,9 @@ static bool init_smb_request(struct smb_request *req,
req->vuid = SVAL(inbuf, smb_uid);
req->tid = SVAL(inbuf, smb_tid);
req->wct = CVAL(inbuf, smb_wct);
- req->vwv = (uint16_t *)(inbuf+smb_vwv);
+ req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
req->buflen = smb_buflen(inbuf);
- req->buf = (const uint8_t *)smb_buf(inbuf);
+ req->buf = (const uint8_t *)smb_buf_const(inbuf);
req->unread_bytes = unread_bytes;
req->encrypted = encrypted;
req->sconn = sconn;
@@ -522,7 +525,7 @@ static bool init_smb_request(struct smb_request *req,
return false;
}
/* Ensure bcc is correct. */
- if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
+ if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
DEBUG(0,("init_smb_request: invalid bcc number %u "
"(wct = %u, size %u)\n",
(unsigned int)req->buflen,
@@ -591,7 +594,7 @@ static bool push_queued_message(struct smb_request *req,
int msg_len = smb_len(req->inbuf) + 4;
struct pending_message_list *msg;
- msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
+ msg = talloc_zero(NULL, struct pending_message_list);
if(msg == NULL) {
DEBUG(0,("push_message: malloc fail (1)\n"));
@@ -621,7 +624,7 @@ static bool push_queued_message(struct smb_request *req,
}
}
- msg->te = event_add_timed(smbd_event_context(),
+ msg->te = event_add_timed(server_event_context(),
msg,
end_time,
smbd_deferred_open_timer,
@@ -705,7 +708,7 @@ void schedule_deferred_open_message_smb(uint64_t mid)
"scheduling mid %llu\n",
(unsigned long long)mid ));
- te = event_add_timed(smbd_event_context(),
+ te = event_add_timed(server_event_context(),
pml,
timeval_zero(),
smbd_deferred_open_timer,
@@ -888,7 +891,7 @@ struct idle_event *event_add_idle(struct event_context *event_ctx,
struct idle_event *result;
struct timeval now = timeval_current();
- result = TALLOC_P(mem_ctx, struct idle_event);
+ result = talloc(mem_ctx, struct idle_event);
if (result == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
@@ -931,8 +934,8 @@ void smbd_setup_sig_term_handler(void)
{
struct tevent_signal *se;
- se = tevent_add_signal(smbd_event_context(),
- smbd_event_context(),
+ se = tevent_add_signal(server_event_context(),
+ server_event_context(),
SIGTERM, 0,
smbd_sig_term_handler,
NULL);
@@ -984,11 +987,11 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
* select for longer than it would take to wait for them.
*/
- event_add_to_poll_args(smbd_event_context(), conn,
+ event_add_to_poll_args(server_event_context(), conn,
&conn->pfds, &num_pfds, &timeout);
/* Process a signal and timed events now... */
- if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
+ if (run_events_poll(server_event_context(), 0, NULL, 0)) {
return NT_STATUS_RETRY;
}
@@ -1003,11 +1006,14 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
errno = sav;
}
- if (ret == -1 && errno != EINTR) {
+ if (ret == -1) {
+ if (errno == EINTR) {
+ return NT_STATUS_RETRY;
+ }
return map_nt_error_from_unix(errno);
}
- retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
+ retry = run_events_poll(server_event_context(), ret, conn->pfds,
num_pfds);
if (retry) {
return NT_STATUS_RETRY;
@@ -1345,12 +1351,12 @@ static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
char *msg;
if (asprintf(&msg, "num_bytes too large: %u",
(unsigned)num_bytes) == -1) {
- msg = CONST_DISCARD(char *, "num_bytes too large");
+ msg = discard_const_p(char, "num_bytes too large");
}
smb_panic(msg);
}
- *outbuf = TALLOC_ARRAY(mem_ctx, char,
+ *outbuf = talloc_array(mem_ctx, char,
smb_size + num_words*2 + num_bytes);
if (*outbuf == NULL) {
return false;
@@ -1372,7 +1378,7 @@ static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
{
char *outbuf;
- if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
+ if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
num_bytes)) {
smb_panic("could not allocate output buffer\n");
}
@@ -1444,7 +1450,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
if (smb_messages[type].fn == NULL) {
DEBUG(0,("Unknown message type %d!\n",type));
- smb_dump("Unknown", 1, (char *)req->inbuf, size);
+ smb_dump("Unknown", 1, (const char *)req->inbuf, size);
reply_unknown_new(req, type);
return NULL;
}
@@ -1459,10 +1465,10 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
(int)sys_getpid(), (unsigned long)conn));
- smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
+ smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
/* Ensure this value is replaced in the incoming packet. */
- SSVAL(req->inbuf,smb_uid,session_tag);
+ SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
/*
* Ensure the correct username is in current_user_info. This is a
@@ -1748,7 +1754,7 @@ static void construct_reply_common(struct smb_request *req, const char *inbuf,
void construct_reply_common_req(struct smb_request *req, char *outbuf)
{
- construct_reply_common(req, (char *)req->inbuf, outbuf);
+ construct_reply_common(req, (const char *)req->inbuf, outbuf);
}
/*
@@ -1888,7 +1894,7 @@ static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
return false;
}
- outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
+ outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
if (outbuf == NULL) {
DEBUG(0, ("talloc failed\n"));
return false;
@@ -1902,7 +1908,7 @@ static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
DEBUG(1, ("invalid command chain\n"));
- *poutbuf = TALLOC_REALLOC_ARRAY(
+ *poutbuf = talloc_realloc(
NULL, *poutbuf, uint8_t, old_size);
return false;
}
@@ -1971,9 +1977,9 @@ void chain_reply(struct smb_request *req)
uint32_t chain_offset; /* uint32_t to avoid overflow */
uint8_t wct;
- uint16_t *vwv;
+ const uint16_t *vwv;
uint16_t buflen;
- uint8_t *buf;
+ const uint8_t *buf;
if (IVAL(req->outbuf, smb_rcls) != 0) {
fixup_chain_error_packet(req);
@@ -1990,7 +1996,7 @@ void chain_reply(struct smb_request *req)
if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
if (req->chain_outbuf == NULL) {
- req->chain_outbuf = TALLOC_REALLOC_ARRAY(
+ req->chain_outbuf = talloc_realloc(
req, req->outbuf, uint8_t,
smb_len(req->outbuf) + 4);
if (req->chain_outbuf == NULL) {
@@ -2022,7 +2028,7 @@ void chain_reply(struct smb_request *req)
* over-allocated (reply_pipe_read_and_X used to be such an
* example).
*/
- req->chain_outbuf = TALLOC_REALLOC_ARRAY(
+ req->chain_outbuf = talloc_realloc(
req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
if (req->chain_outbuf == NULL) {
smb_panic("talloc failed");
@@ -2122,7 +2128,7 @@ void chain_reply(struct smb_request *req)
if (length_needed > smblen) {
goto error;
}
- vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
+ vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
/*
* Now grab the new byte buffer....
@@ -2138,11 +2144,11 @@ void chain_reply(struct smb_request *req)
if (length_needed > smblen) {
goto error;
}
- buf = (uint8_t *)(vwv+wct+1);
+ buf = (const uint8_t *)(vwv+wct+1);
req->cmd = chain_cmd;
req->wct = wct;
- req->vwv = vwv;
+ req->vwv = discard_const_p(uint16_t, vwv);
req->buflen = buflen;
req->buf = buf;
@@ -2240,13 +2246,14 @@ static bool fd_is_readable(int fd)
}
-static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
+static void smbd_server_connection_write_handler(
+ struct smbd_server_connection *sconn)
{
/* TODO: make write nonblocking */
}
static void smbd_server_connection_read_handler(
- struct smbd_server_connection *conn, int fd)
+ struct smbd_server_connection *sconn, int fd)
{
uint8_t *inbuf = NULL;
size_t inbuf_len = 0;
@@ -2256,29 +2263,29 @@ static void smbd_server_connection_read_handler(
NTSTATUS status;
uint32_t seqnum;
- bool from_client = (conn->sock == fd);
+ bool from_client = (sconn->sock == fd);
if (from_client) {
- smbd_lock_socket(conn);
+ smbd_lock_socket(sconn);
if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
DEBUG(10,("the echo listener was faster\n"));
- smbd_unlock_socket(conn);
+ smbd_unlock_socket(sconn);
return;
}
/* TODO: make this completely nonblocking */
- status = receive_smb_talloc(mem_ctx, conn, fd,
+ status = receive_smb_talloc(mem_ctx, sconn, fd,
(char **)(void *)&inbuf,
0, /* timeout */
&unread_bytes,
&encrypted,
&inbuf_len, &seqnum,
false /* trusted channel */);
- smbd_unlock_socket(conn);
+ smbd_unlock_socket(sconn);
} else {
/* TODO: make this completely nonblocking */
- status = receive_smb_talloc(mem_ctx, conn, fd,
+ status = receive_smb_talloc(mem_ctx, sconn, fd,
(char **)(void *)&inbuf,
0, /* timeout */
&unread_bytes,
@@ -2298,7 +2305,7 @@ static void smbd_server_connection_read_handler(
}
process:
- process_smb(conn, inbuf, inbuf_len, unread_bytes,
+ process_smb(sconn, inbuf, inbuf_len, unread_bytes,
seqnum, encrypted, NULL);
}
@@ -2339,6 +2346,7 @@ static void smbd_server_echo_handler(struct event_context *ev,
}
}
+#ifdef CLUSTER_SUPPORT
/****************************************************************************
received when we should release a specific IP
****************************************************************************/
@@ -2351,6 +2359,9 @@ static void release_ip(const char *ip, void *priv)
p = addr + 7;
}
+ DEBUG(10, ("Got release IP message for %s, "
+ "our address is %s\n", ip, p));
+
if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
/* we can't afford to do a clean exit - that involves
database writes, which would potentially mean we
@@ -2365,16 +2376,6 @@ static void release_ip(const char *ip, void *priv)
}
}
-static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
- uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
-{
- struct smbd_server_connection *sconn = talloc_get_type_abort(
- private_data, struct smbd_server_connection);
-
- release_ip((char *)data->data, sconn->client_id.addr);
-}
-
-#ifdef CLUSTER_SUPPORT
static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
struct sockaddr_storage *client)
{
@@ -2608,7 +2609,7 @@ static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
return false;
}
- if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
+ if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
1, req.buflen)) {
DEBUG(10, ("create_outbuf failed\n"));
return false;
@@ -2788,7 +2789,7 @@ static void smbd_echo_loop(struct smbd_server_connection *sconn,
/*
* Handle SMBecho requests in a forked child process
*/
-static bool fork_echo_handler(struct smbd_server_connection *sconn)
+bool fork_echo_handler(struct smbd_server_connection *sconn)
{
int listener_pipe[2];
int res;
@@ -2813,7 +2814,7 @@ static bool fork_echo_handler(struct smbd_server_connection *sconn)
set_blocking(listener_pipe[1], false);
status = reinit_after_fork(sconn->msg_ctx,
- smbd_event_context(),
+ server_event_context(),
procid_self(), false);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("reinit_after_fork failed: %s\n",
@@ -2833,7 +2834,7 @@ static bool fork_echo_handler(struct smbd_server_connection *sconn)
* Without smb signing this is the same as the normal smbd
* listener. This needs to change once signing comes in.
*/
- sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
+ sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
sconn,
sconn->smb1.echo_handler.trusted_fd,
EVENT_FD_READ,
@@ -2902,8 +2903,7 @@ void smbd_process(struct smbd_server_connection *sconn)
const char *remaddr = NULL;
int ret;
- if (lp_maxprotocol() == PROTOCOL_SMB2 &&
- !lp_async_smb_echo_handler()) {
+ if (lp_maxprotocol() == PROTOCOL_SMB2) {
/*
* We're not making the decision here,
* we're just allowing the client
@@ -3024,10 +3024,6 @@ void smbd_process(struct smbd_server_connection *sconn)
exit_server("Failed to init smb_signing");
}
- if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
- exit_server("Failed to fork echo handler");
- }
-
/* Setup oplocks */
if (!init_oplocks(sconn->msg_ctx))
exit_server("Failed to init oplocks");
@@ -3035,8 +3031,6 @@ void smbd_process(struct smbd_server_connection *sconn)
/* register our message handlers */
messaging_register(sconn->msg_ctx, NULL,
MSG_SMB_FORCE_TDIS, msg_force_tdis);
- messaging_register(sconn->msg_ctx, sconn,
- MSG_SMB_RELEASE_IP, msg_release_ip);
messaging_register(sconn->msg_ctx, NULL,
MSG_SMB_CLOSE_FILE, msg_close_file);
@@ -3050,7 +3044,7 @@ void smbd_process(struct smbd_server_connection *sconn)
MSG_DEBUG, debug_message);
if ((lp_keepalive() != 0)
- && !(event_add_idle(smbd_event_context(), NULL,
+ && !(event_add_idle(server_event_context(), NULL,
timeval_set(lp_keepalive(), 0),
"keepalive", keepalive_fn,
NULL))) {
@@ -3058,14 +3052,14 @@ void smbd_process(struct smbd_server_connection *sconn)
exit(1);
}
- if (!(event_add_idle(smbd_event_context(), NULL,
+ if (!(event_add_idle(server_event_context(), NULL,
timeval_set(IDLE_CLOSED_TIMEOUT, 0),
"deadtime", deadtime_fn, sconn))) {
DEBUG(0, ("Could not add deadtime event\n"));
exit(1);
}
- if (!(event_add_idle(smbd_event_context(), NULL,
+ if (!(event_add_idle(server_event_context(), NULL,
timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
"housekeeping", housekeeping_fn, sconn))) {
DEBUG(0, ("Could not add housekeeping event\n"));
@@ -3122,7 +3116,7 @@ void smbd_process(struct smbd_server_connection *sconn)
exit_server("init_dptrs() failed");
}
- sconn->smb1.fde = event_add_fd(smbd_event_context(),
+ sconn->smb1.fde = event_add_fd(server_event_context(),
sconn,
sconn->sock,
EVENT_FD_READ,
@@ -3157,7 +3151,7 @@ void smbd_process(struct smbd_server_connection *sconn)
bool req_is_in_chain(struct smb_request *req)
{
- if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
+ if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
/*
* We're right now handling a subsequent request, so we must
* be in a chain
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 36eea5e16e..adeaf68899 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1,3 +1,50 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Main SMB server routines
+ *
+ * Copyright (C) Andrew Tridgell 1992-2002,2006
+ * Copyright (C) Jeremy Allison 1992-2010
+ * Copyright (C) Volker Lendecke 1993-2009
+ * Copyright (C) John H Terpstra 1995-1998
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+ * Copyright (C) Paul Ashton 1997-1998
+ * Copyright (C) Tim Potter 1999-2000
+ * Copyright (C) T.D.Lee@durham.ac.uk 1999
+ * Copyright (C) Ying Chen 2000
+ * Copyright (C) Shirish Kalele 2000
+ * Copyright (C) Andrew Bartlett 2001-2003
+ * Copyright (C) Alexander Bokovoy 2002,2005
+ * Copyright (C) Simo Sorce 2001-2002,2009
+ * Copyright (C) Andreas Gruenbacher 2002
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
+ * Copyright (C) Martin Pool 2002
+ * Copyright (C) Luke Howard 2003
+ * Copyright (C) Stefan (metze) Metzmacher 2003,2009
+ * Copyright (C) Steve French 2005
+ * Copyright (C) Gerald (Jerry) Carter 2006
+ * Copyright (C) James Peach 2006-2007
+ * Copyright (C) Jelmer Vernooij 2002-2003
+ * Copyright (C) Michael Adam 2007
+ * Copyright (C) Rishi Srivatsavai 2007
+ * Copyright (C) Tim Prouty 2009
+ * Copyright (C) Gregor Beck 2011
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SMBD_PROTO_H_
+#define _SMBD_PROTO_H_
/* The following definitions come from smbd/signing.c */
@@ -23,7 +70,7 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
size_t smb_maxcnt);
NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
struct smb_request *req,
- files_struct *fsp, char *data,
+ files_struct *fsp, const char *data,
SMB_OFF_T startpos,
size_t numtowrite);
NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
@@ -63,6 +110,9 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
uint64_t offset,
uint64_t count,
uint64_t blocking_smblctx);
+void smbd_cancel_pending_lock_requests_by_fid(files_struct *fsp,
+ struct byte_range_lock *br_lck,
+ enum file_close_type close_type);
void cancel_pending_lock_requests_by_fid(files_struct *fsp,
struct byte_range_lock *br_lck,
enum file_close_type close_type);
@@ -94,7 +144,7 @@ NTSTATUS delete_all_streams(connection_struct *conn, const char *fname);
void conn_init(struct smbd_server_connection *sconn);
int conn_num_open(struct smbd_server_connection *sconn);
-bool conn_snum_used(int snum);
+bool conn_snum_used(struct smbd_server_connection *sconn, int snum);
connection_struct *conn_find(struct smbd_server_connection *sconn,
unsigned cnum);
connection_struct *conn_new(struct smbd_server_connection *sconn);
@@ -102,6 +152,7 @@ bool conn_close_all(struct smbd_server_connection *sconn);
bool conn_idle_all(struct smbd_server_connection *sconn, time_t t);
void conn_clear_vuid_caches(struct smbd_server_connection *sconn, uint16 vuid);
void conn_free(connection_struct *conn);
+void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename);
void msg_force_tdis(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
@@ -188,6 +239,8 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset);
bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset);
NTSTATUS can_delete_directory(struct connection_struct *conn,
const char *dirname);
+NTSTATUS smbd_can_delete_directory(struct connection_struct *conn,
+ const char *dirname);
/* The following definitions come from smbd/dmapi.c */
@@ -407,7 +460,8 @@ bool create_junction(TALLOC_CTX *ctx,
struct junction_map *jucn);
bool create_msdfs_link(const struct junction_map *jucn);
bool remove_msdfs_link(const struct junction_map *jucn);
-struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn);
+struct junction_map *enum_msdfs_links(struct smbd_server_connection *sconn,
+ TALLOC_CTX *ctx, size_t *p_num_jn);
NTSTATUS resolve_dfspath(TALLOC_CTX *ctx,
connection_struct *conn,
bool dfs_pathnames,
@@ -621,6 +675,10 @@ void contend_level2_oplocks_begin(files_struct *fsp,
enum level2_contention_type type);
void contend_level2_oplocks_end(files_struct *fsp,
enum level2_contention_type type);
+void smbd_contend_level2_oplocks_begin(files_struct *fsp,
+ enum level2_contention_type type);
+void smbd_contend_level2_oplocks_end(files_struct *fsp,
+ enum level2_contention_type type);
void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e);
void message_to_share_mode_entry(struct share_mode_entry *e, char *msg);
bool init_oplocks(struct messaging_context *msg_ctx);
@@ -750,6 +808,7 @@ size_t req_wct_ofs(struct smb_request *req);
void chain_reply(struct smb_request *req);
bool req_is_in_chain(struct smb_request *req);
void smbd_process(struct smbd_server_connection *sconn);
+bool fork_echo_handler(struct smbd_server_connection *sconn);
/* The following definitions come from smbd/quotas.c */
@@ -996,10 +1055,18 @@ bool stat_cache_lookup(connection_struct *conn,
char **pp_dirpath,
char **pp_start,
SMB_STRUCT_STAT *pst);
+void smbd_send_stat_cache_delete_message(struct messaging_context *msg_ctx,
+ const char *name);
void send_stat_cache_delete_message(struct messaging_context *msg_ctx,
const char *name);
void stat_cache_delete(const char *name);
-unsigned int fast_string_hash(TDB_DATA *key);
+#if BUILD_TDB2
+struct tdb_data;
+unsigned int fast_string_hash(struct tdb_data *key);
+#else
+struct TDB_DATA;
+unsigned int fast_string_hash(struct TDB_DATA *key);
+#endif
bool reset_stat_cache( void );
/* The following definitions come from smbd/statvfs.c */
@@ -1046,15 +1113,17 @@ void reply_transs2(struct smb_request *req);
/* The following definitions come from smbd/uid.c */
bool change_to_guest(void);
-void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid);
bool change_to_user(connection_struct *conn, uint16 vuid);
bool change_to_user_by_session(connection_struct *conn,
const struct auth_serversupplied_info *session_info);
bool change_to_root_user(void);
-bool become_authenticated_pipe_user(struct pipes_struct *p);
+bool smbd_change_to_root_user(void);
+bool become_authenticated_pipe_user(struct auth_serversupplied_info *session_info);
bool unbecome_authenticated_pipe_user(void);
void become_root(void);
void unbecome_root(void);
+void smbd_become_root(void);
+void smbd_unbecome_root(void);
bool become_user(connection_struct *conn, uint16 vuid);
bool become_user_by_session(connection_struct *conn,
const struct auth_serversupplied_info *session_info);
@@ -1130,3 +1199,5 @@ void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
/* The following definitions come from smbd/msg_idmap.c */
void msg_idmap_register_msgs(struct messaging_context *ctx);
+
+#endif /* _SMBD_PROTO_H_ */
diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c
index c9f85b6ad0..41516621f0 100644
--- a/source3/smbd/quotas.c
+++ b/source3/smbd/quotas.c
@@ -26,6 +26,7 @@
#include "includes.h"
#include "smbd/smbd.h"
+#include "system/filesys.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_QUOTA
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 01d4332b7e..a804884ef7 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -314,7 +314,7 @@ size_t srvstr_get_path_req_wcard(TALLOC_CTX *mem_ctx, struct smb_request *req,
char **pp_dest, const char *src, int flags,
NTSTATUS *err, bool *contains_wcard)
{
- return srvstr_get_path_wcard(mem_ctx, (char *)req->inbuf, req->flags2,
+ return srvstr_get_path_wcard(mem_ctx, (const char *)req->inbuf, req->flags2,
pp_dest, src, smbreq_bufrem(req, src),
flags, err, contains_wcard);
}
@@ -491,6 +491,13 @@ static bool netbios_session_retarget(struct smbd_server_connection *sconn,
return ret;
}
+static void reply_called_name_not_present(char *outbuf)
+{
+ smb_setlen(outbuf, 1);
+ SCVAL(outbuf, 0, 0x83);
+ SCVAL(outbuf, 4, 0x82);
+}
+
/****************************************************************************
Reply to a (netbios-level) special message.
****************************************************************************/
@@ -531,11 +538,13 @@ void reply_special(struct smbd_server_connection *sconn, char *inbuf, size_t inb
name_len1 = name_len((unsigned char *)(inbuf+4),inbuf_size - 4);
if (name_len1 <= 0 || name_len1 > inbuf_size - 4) {
DEBUG(0,("Invalid name length in session request\n"));
+ reply_called_name_not_present(outbuf);
break;
}
name_len2 = name_len((unsigned char *)(inbuf+4+name_len1),inbuf_size - 4 - name_len1);
if (name_len2 <= 0 || name_len2 > inbuf_size - 4 - name_len1) {
DEBUG(0,("Invalid name length in session request\n"));
+ reply_called_name_not_present(outbuf);
break;
}
@@ -546,6 +555,7 @@ void reply_special(struct smbd_server_connection *sconn, char *inbuf, size_t inb
if (name_type1 == -1 || name_type2 == -1) {
DEBUG(0,("Invalid name type in session request\n"));
+ reply_called_name_not_present(outbuf);
break;
}
@@ -575,7 +585,7 @@ void reply_special(struct smbd_server_connection *sconn, char *inbuf, size_t inb
if (name_type2 == 'R') {
/* We are being asked for a pathworks session ---
no thanks! */
- SCVAL(outbuf, 0,0x83);
+ reply_called_name_not_present(outbuf);
break;
}
@@ -614,6 +624,10 @@ void reply_special(struct smbd_server_connection *sconn, char *inbuf, size_t inb
msg_type, msg_flags));
srv_send_smb(sconn, outbuf, false, 0, false, NULL);
+
+ if (CVAL(outbuf, 0) != 0x82) {
+ exit_server_cleanly("invalid netbios session");
+ }
return;
}
@@ -873,7 +887,7 @@ void reply_tcon_and_X(struct smb_request *req)
service));
/* set the incoming and outgoing tid to the just created one */
- SSVAL(req->inbuf,smb_tid,conn->cnum);
+ SSVAL(discard_const_p(uint8_t, req->inbuf),smb_tid,conn->cnum);
SSVAL(req->outbuf,smb_tid,conn->cnum);
END_PROFILE(SMBtconX);
@@ -958,7 +972,7 @@ void reply_ioctl(struct smb_request *req)
SSVAL(p, 0, 0);
}
srvstr_push((char *)req->outbuf, req->flags2, p+2,
- global_myname(), 15,
+ lp_netbios_name(), 15,
STR_TERMINATE|STR_ASCII);
if (conn) {
srvstr_push((char *)req->outbuf, req->flags2,
@@ -1108,9 +1122,9 @@ void reply_getatr(struct smb_request *req)
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
if (*fname == '\0') {
- mode = aHIDDEN | aDIR;
+ mode = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
if (!CAN_WRITE(conn)) {
- mode |= aRONLY;
+ mode |= FILE_ATTRIBUTE_READONLY;
}
size = 0;
mtime = 0;
@@ -1156,7 +1170,7 @@ void reply_getatr(struct smb_request *req)
}
mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
- if (mode & aDIR) {
+ if (mode & FILE_ATTRIBUTE_DIRECTORY) {
size = 0;
}
}
@@ -1257,9 +1271,9 @@ void reply_setatr(struct smb_request *req)
if (mode != FILE_ATTRIBUTE_NORMAL) {
if (VALID_STAT_OF_DIR(smb_fname->st))
- mode |= aDIR;
+ mode |= FILE_ATTRIBUTE_DIRECTORY;
else
- mode &= ~aDIR;
+ mode &= ~FILE_ATTRIBUTE_DIRECTORY;
if (file_set_dosmode(conn, smb_fname, mode, NULL,
false) != 0) {
@@ -1428,7 +1442,7 @@ void reply_search(struct smb_request *req)
status_len = SVAL(p, 0);
p += 2;
- /* dirtype &= ~aDIR; */
+ /* dirtype &= ~FILE_ATTRIBUTE_DIRECTORY; */
if (status_len == 0) {
nt_status = filename_convert(ctx, conn,
@@ -1520,11 +1534,11 @@ void reply_search(struct smb_request *req)
/* Initialize per SMBsearch/SMBffirst/SMBfunique operation data */
dptr_init_search_op(dirptr);
- if ((dirtype&0x1F) == aVOLID) {
+ if ((dirtype&0x1F) == FILE_ATTRIBUTE_VOLUME) {
char buf[DIR_STRUCT_SIZE];
memcpy(buf,status,21);
if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
- 0,aVOLID,0,!allow_long_path_components)) {
+ 0,FILE_ATTRIBUTE_VOLUME,0,!allow_long_path_components)) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
@@ -1820,7 +1834,7 @@ void reply_open(struct smb_request *req)
mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
- if (fattr & aDIR) {
+ if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
DEBUG(3,("attempt to open a directory %s\n",
fsp_str_dbg(fsp)));
close_file(req, fsp, ERROR_CLOSE);
@@ -2004,7 +2018,7 @@ void reply_open_and_X(struct smb_request *req)
fattr = dos_mode(conn, fsp->fsp_name);
mtime = convert_timespec_to_time_t(fsp->fsp_name->st.st_ex_mtime);
- if (fattr & aDIR) {
+ if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
close_file(req, fsp, ERROR_CLOSE);
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
goto out;
@@ -2160,7 +2174,7 @@ void reply_mknew(struct smb_request *req)
goto out;
}
- if (fattr & aVOLID) {
+ if (fattr & FILE_ATTRIBUTE_VOLUME) {
DEBUG(0,("Attempt to create file (%s) with volid set - "
"please report this\n",
smb_fname_str_dbg(smb_fname)));
@@ -2381,15 +2395,18 @@ void reply_ctemp(struct smb_request *req)
static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
uint16 dirtype)
{
- uint32 fmode;
-
if (!CAN_WRITE(conn)) {
return NT_STATUS_MEDIA_WRITE_PROTECTED;
}
- fmode = dos_mode(conn, fsp->fsp_name);
- if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
- return NT_STATUS_NO_SUCH_FILE;
+ if ((dirtype & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) !=
+ (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
+ /* Only bother to read the DOS attribute if we might deny the
+ rename on the grounds of attribute missmatch. */
+ uint32_t fmode = dos_mode(conn, fsp->fsp_name);
+ if ((fmode & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
+ return NT_STATUS_NO_SUCH_FILE;
+ }
}
if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
@@ -2449,16 +2466,16 @@ static NTSTATUS do_unlink(connection_struct *conn,
fattr = dos_mode(conn, smb_fname);
if (dirtype & FILE_ATTRIBUTE_NORMAL) {
- dirtype = aDIR|aARCH|aRONLY;
+ dirtype = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY;
}
- dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
+ dirtype &= (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
if (!dirtype) {
return NT_STATUS_NO_SUCH_FILE;
}
if (!dir_check_ftype(conn, fattr, dirtype)) {
- if (fattr & aDIR) {
+ if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
return NT_STATUS_NO_SUCH_FILE;
@@ -2489,13 +2506,13 @@ static NTSTATUS do_unlink(connection_struct *conn,
}
/* Can't delete a directory. */
- if (fattr & aDIR) {
+ if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
#endif
#if 0 /* JRATEST */
- else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
+ else if (dirtype & FILE_ATTRIBUTE_DIRECTORY) /* Asked for a directory and it isn't. */
return NT_STATUS_OBJECT_NAME_INVALID;
#endif /* JRATEST */
@@ -2632,7 +2649,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
const char *dname = NULL;
char *talloced = NULL;
- if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
+ if ((dirtype & SAMBA_ATTRIBUTES_MASK) == FILE_ATTRIBUTE_DIRECTORY) {
status = NT_STATUS_OBJECT_NAME_INVALID;
goto out;
}
@@ -3077,9 +3094,9 @@ static void send_file_readbraw(connection_struct *conn,
normal_readbraw:
- outbuf = TALLOC_ARRAY(NULL, char, nread+4);
+ outbuf = talloc_array(NULL, char, nread+4);
if (!outbuf) {
- DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
+ DEBUG(0,("send_file_readbraw: talloc_array failed for size %u.\n",
(unsigned)(nread+4)));
reply_readbraw_error(sconn);
return;
@@ -3213,7 +3230,7 @@ void reply_readbraw(struct smb_request *req)
"(%x << 32) used and we don't support "
"64 bit offsets.\n",
(unsigned int)IVAL(req->vwv+8, 0) ));
- reply_readbraw_error();
+ reply_readbraw_error(sconn);
END_PROFILE(SMBreadbraw);
return;
}
@@ -3896,7 +3913,7 @@ void reply_writebraw(struct smb_request *req)
size_t numtowrite=0;
size_t tcount;
SMB_OFF_T startpos;
- char *data=NULL;
+ const char *data=NULL;
bool write_through;
files_struct *fsp;
struct lock_struct lock;
@@ -3909,7 +3926,7 @@ void reply_writebraw(struct smb_request *req)
* type of SMBwritec, not SMBwriteBraw, as this tells the client
* we're finished.
*/
- SCVAL(req->inbuf,smb_com,SMBwritec);
+ SCVAL(discard_const_p(uint8_t, req->inbuf),smb_com,SMBwritec);
if (srv_is_signing_active(req->sconn)) {
END_PROFILE(SMBwritebraw);
@@ -3955,8 +3972,8 @@ void reply_writebraw(struct smb_request *req)
on whether we are using the core+ or lanman1.0 protocol */
if(get_Protocol() <= PROTOCOL_COREPLUS) {
- numtowrite = SVAL(smb_buf(req->inbuf),-2);
- data = smb_buf(req->inbuf);
+ numtowrite = SVAL(smb_buf_const(req->inbuf),-2);
+ data = smb_buf_const(req->inbuf);
} else {
numtowrite = SVAL(req->vwv+10, 0);
data = smb_base(req->inbuf) + SVAL(req->vwv+11, 0);
@@ -4001,7 +4018,7 @@ void reply_writebraw(struct smb_request *req)
total_written = nwritten;
/* Allocate a buffer of 64k + length. */
- buf = TALLOC_ARRAY(NULL, char, 65540);
+ buf = talloc_array(NULL, char, 65540);
if (!buf) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
error_to_writebrawerr(req);
@@ -4474,7 +4491,7 @@ void reply_write_and_X(struct smb_request *req)
ssize_t nwritten;
unsigned int smb_doff;
unsigned int smblen;
- char *data;
+ const char *data;
NTSTATUS status;
int saved_errno = 0;
@@ -5815,7 +5832,7 @@ static void rename_open_files(connection_struct *conn,
files_struct *fsp;
bool did_rename = False;
NTSTATUS status;
- uint32_t new_name_hash;
+ uint32_t new_name_hash = 0;
for(fsp = file_find_di_first(conn->sconn, lck->id); fsp;
fsp = file_find_di_next(fsp)) {
@@ -6405,7 +6422,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
/* Quick check for "." and ".." */
if (ISDOT(dname) || ISDOTDOT(dname)) {
- if (attrs & aDIR) {
+ if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
sysdir_entry = True;
} else {
TALLOC_FREE(talloced);
@@ -7971,7 +7988,7 @@ void reply_getattrE(struct smb_request *req)
srv_put_dos_date2((char *)req->outbuf, smb_vwv4,
convert_timespec_to_time_t(fsp->fsp_name->st.st_ex_mtime));
- if (mode & aDIR) {
+ if (mode & FILE_ATTRIBUTE_DIRECTORY) {
SIVAL(req->outbuf, smb_vwv6, 0);
SIVAL(req->outbuf, smb_vwv8, 0);
} else {
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c
index b3dd84264a..26185062a6 100644
--- a/source3/smbd/seal.c
+++ b/source3/smbd/seal.c
@@ -26,6 +26,7 @@
#include "smb_crypt.h"
#include "../lib/util/asn1.h"
#include "auth.h"
+#include "libsmb/libsmb.h"
/******************************************************************************
Server side encryption.
@@ -133,7 +134,7 @@ static NTSTATUS get_srv_gss_creds(const char *service,
NTSTATUS status = NT_STATUS_OK;
gss_OID_desc nt_hostbased_service =
- {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")};
+ {10, discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")};
if (asprintf(&host_princ_s, "%s@%s", service, name) == -1) {
return NT_STATUS_NO_MEMORY;
@@ -195,7 +196,7 @@ static NTSTATUS make_auth_gss(struct smb_srv_trans_enc_ctx *ec)
gss_cred_id_t srv_cred;
fstring fqdn;
- name_to_fqdn(fqdn, global_myname());
+ name_to_fqdn(fqdn, lp_netbios_name());
strlower_m(fqdn);
status = get_srv_gss_creds("cifs", fqdn, GSS_C_ACCEPT, &srv_cred);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index d3c6c1884f..5aa3ddbdc9 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -26,7 +26,6 @@
#include "popt_common.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
-#include "registry.h"
#include "registry/reg_init_full.h"
#include "libcli/auth/schannel.h"
#include "secrets.h"
@@ -52,40 +51,6 @@ extern void start_spoolssd(struct event_context *ev_ctx,
extern int dcelogin_atmost_once;
#endif /* WITH_DFS */
-static void smbd_set_server_fd(int fd)
-{
- struct smbd_server_connection *sconn = smbd_server_conn;
- char addr[INET6_ADDRSTRLEN];
- const char *name;
-
- sconn->sock = fd;
-
- /*
- * Initialize sconn->client_id: If we can't find the client's
- * name, default to its address.
- */
-
- client_addr(fd, sconn->client_id.addr, sizeof(sconn->client_id.addr));
-
- name = client_name(sconn->sock);
- if (strcmp(name, "UNKNOWN") != 0) {
- name = talloc_strdup(sconn, name);
- } else {
- name = NULL;
- }
- sconn->client_id.name =
- (name != NULL) ? name : sconn->client_id.addr;
-
- sub_set_socket_ids(sconn->client_id.addr, sconn->client_id.name,
- client_socket_addr(sconn->sock, addr,
- sizeof(addr)));
-}
-
-struct event_context *smbd_event_context(void)
-{
- return server_event_context();
-}
-
/*******************************************************************
What to do when smb.conf is updated.
********************************************************************/
@@ -288,7 +253,7 @@ static void remove_child_pid(pid_t pid, bool unclean_shutdown)
if (!cleanup_te) {
/* call the cleanup timer, but not too often */
int cleanup_time = lp_parm_int(-1, "smbd", "cleanuptime", 20);
- cleanup_te = event_add_timed(smbd_event_context(), NULL,
+ cleanup_te = event_add_timed(server_event_context(), NULL,
timeval_current_ofs(cleanup_time, 0),
cleanup_timeout_fn,
&cleanup_te);
@@ -366,8 +331,8 @@ static void smbd_setup_sig_chld_handler(void)
{
struct tevent_signal *se;
- se = tevent_add_signal(smbd_event_context(),
- smbd_event_context(),
+ se = tevent_add_signal(server_event_context(),
+ server_event_context(),
SIGCHLD, 0,
smbd_sig_chld_handler,
NULL);
@@ -469,7 +434,7 @@ static void smbd_accept_connection(struct tevent_context *ev,
s = NULL;
status = reinit_after_fork(smbd_messaging_context(),
- smbd_event_context(), procid_self(),
+ server_event_context(), procid_self(),
true);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,
@@ -582,7 +547,7 @@ static bool smbd_open_one_socket(struct smbd_parent_context *parent,
return false;
}
- s->fde = tevent_add_fd(smbd_event_context(),
+ s->fde = tevent_add_fd(server_event_context(),
s,
s->fd, TEVENT_FD_READ,
smbd_accept_connection,
@@ -632,7 +597,7 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
{
int num_interfaces = iface_count();
int i;
- char *ports;
+ const char *ports;
unsigned dns_port = 0;
#ifdef HAVE_ATEXIT
@@ -763,7 +728,7 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
return false;
}
- if (!(event_add_idle(smbd_event_context(), NULL,
+ if (!(event_add_idle(server_event_context(), NULL,
timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
"parent_housekeeping", smbd_parent_housekeeping,
NULL))) {
@@ -801,14 +766,14 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
if (lp_multicast_dns_register() && (dns_port != 0)) {
#ifdef WITH_DNSSD_SUPPORT
- smbd_setup_mdns_registration(smbd_event_context(),
+ smbd_setup_mdns_registration(server_event_context(),
parent, dns_port);
#endif
#ifdef WITH_AVAHI_SUPPORT
void *avahi_conn;
avahi_conn = avahi_start_register(
- smbd_event_context(), smbd_event_context(), dns_port);
+ server_event_context(), server_event_context(), dns_port);
if (avahi_conn == NULL) {
DEBUG(10, ("avahi_start_register failed\n"));
}
@@ -827,7 +792,7 @@ static void smbd_parent_loop(struct smbd_parent_context *parent)
int ret;
TALLOC_CTX *frame = talloc_stackframe();
- ret = tevent_loop_once(smbd_event_context());
+ ret = tevent_loop_once(server_event_context());
if (ret != 0) {
exit_server_cleanly("tevent_loop_once() error");
}
@@ -917,7 +882,7 @@ extern void build_options(bool screen);
load_case_tables();
/* Initialize the event context, it will panic on error */
- smbd_event_context();
+ server_event_context();
smbd_init_globals();
@@ -1063,7 +1028,7 @@ extern void build_options(bool screen);
* Reloading of the printers will not work here as we don't have a
* server info and rpc services set up. It will be called later.
*/
- if (!reload_services(smbd_messaging_context(), -1, False)) {
+ if (!reload_services(NULL, -1, False)) {
exit(1);
}
@@ -1124,7 +1089,7 @@ extern void build_options(bool screen);
pidfile_create("smbd");
status = reinit_after_fork(smbd_messaging_context(),
- smbd_event_context(),
+ server_event_context(),
procid_self(), false);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("reinit_after_fork() failed\n"));
@@ -1134,7 +1099,7 @@ extern void build_options(bool screen);
smbd_server_conn->msg_ctx = smbd_messaging_context();
smbd_setup_sig_term_handler();
- smbd_setup_sig_hup_handler(smbd_event_context(),
+ smbd_setup_sig_hup_handler(server_event_context(),
smbd_server_conn->msg_ctx);
/* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
@@ -1148,7 +1113,7 @@ extern void build_options(bool screen);
/* 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, smbd_event_context()))
+ if(!initialize_password_db(False, server_event_context()))
exit(1);
if (!secrets_init()) {
@@ -1178,15 +1143,15 @@ extern void build_options(bool screen);
if (!locking_init())
exit(1);
- if (!messaging_tdb_parent_init(smbd_event_context())) {
+ if (!messaging_tdb_parent_init(server_event_context())) {
exit(1);
}
- if (!notify_internal_parent_init(smbd_event_context())) {
+ if (!notify_internal_parent_init(server_event_context())) {
exit(1);
}
- if (!serverid_parent_init(smbd_event_context())) {
+ if (!serverid_parent_init(server_event_context())) {
exit(1);
}
@@ -1232,13 +1197,13 @@ extern void build_options(bool screen);
rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
"rpc_server", "epmapper",
"none");
- if (StrCaseCmp(rpcsrv_type, "daemon") == 0) {
- start_epmd(smbd_event_context(),
+ if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
+ start_epmd(server_event_context(),
smbd_server_conn->msg_ctx);
}
}
- if (!dcesrv_ep_setup(smbd_event_context(), smbd_server_conn->msg_ctx)) {
+ if (!dcesrv_ep_setup(server_event_context(), smbd_server_conn->msg_ctx)) {
exit(1);
}
@@ -1253,7 +1218,7 @@ extern void build_options(bool screen);
if (is_daemon && !interactive
&& lp_parm_bool(-1, "smbd", "backgroundqueue", true)) {
- start_background_queue(smbd_event_context(),
+ start_background_queue(server_event_context(),
smbd_messaging_context());
}
@@ -1265,8 +1230,8 @@ extern void build_options(bool screen);
rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
"rpc_server", "spoolss",
"embedded");
- if (StrCaseCmp(rpcsrv_type, "daemon") == 0) {
- start_spoolssd(smbd_event_context(),
+ if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
+ start_spoolssd(server_event_context(),
smbd_messaging_context());
}
}
@@ -1296,7 +1261,7 @@ extern void build_options(bool screen);
return(0);
}
- parent = talloc_zero(smbd_event_context(), struct smbd_parent_context);
+ parent = talloc_zero(server_event_context(), struct smbd_parent_context);
if (!parent) {
exit_server("talloc(struct smbd_parent_context) failed");
}
diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c
index 554affc984..c7a318d891 100644
--- a/source3/smbd/server_exit.c
+++ b/source3/smbd/server_exit.c
@@ -25,7 +25,7 @@
#include "includes.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
-
+#include "ntdomain.h"
#include "../librpc/gen_ndr/srv_dfs.h"
#include "../librpc/gen_ndr/srv_dssetup.h"
#include "../librpc/gen_ndr/srv_echo.h"
diff --git a/source3/smbd/server_reload.c b/source3/smbd/server_reload.c
index 82b0cb03e9..fef66dac6a 100644
--- a/source3/smbd/server_reload.c
+++ b/source3/smbd/server_reload.c
@@ -113,7 +113,11 @@ bool reload_services(struct messaging_context *msg_ctx, int smb_sock,
if (test && !lp_file_list_changed())
return(True);
- lp_killunused(conn_snum_used);
+ if (msg_ctx) {
+ lp_killunused(msg_ctx_to_sconn(msg_ctx), conn_snum_used);
+ } else {
+ lp_killunused(NULL, NULL);
+ }
ret = lp_load(get_dyn_CONFIGFILE(), False, False, True, True);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index b29713d21d..0857645d1c 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -19,6 +19,7 @@
#include "includes.h"
#include "system/filesys.h"
+#include "../lib/tsocket/tsocket.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../librpc/gen_ndr/netlogon.h"
@@ -221,232 +222,6 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir)
return(True);
}
-static int load_registry_service(const char *servicename)
-{
- if (!lp_registry_shares()) {
- return -1;
- }
-
- if ((servicename == NULL) || (*servicename == '\0')) {
- return -1;
- }
-
- if (strequal(servicename, GLOBAL_NAME)) {
- return -2;
- }
-
- if (!process_registry_service(servicename)) {
- return -1;
- }
-
- return lp_servicenumber(servicename);
-}
-
-void load_registry_shares(void)
-{
- DEBUG(8, ("load_registry_shares()\n"));
- if (!lp_registry_shares()) {
- return;
- }
-
- process_registry_shares();
-
- return;
-}
-
-/****************************************************************************
- Add a home service. Returns the new service number or -1 if fail.
-****************************************************************************/
-
-int add_home_service(const char *service, const char *username, const char *homedir)
-{
- int iHomeService;
-
- if (!service || !homedir || homedir[0] == '\0')
- return -1;
-
- if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
- if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {
- return -1;
- }
- }
-
- /*
- * If this is a winbindd provided username, remove
- * the domain component before adding the service.
- * Log a warning if the "path=" parameter does not
- * include any macros.
- */
-
- {
- const char *p = strchr(service,*lp_winbind_separator());
-
- /* We only want the 'user' part of the string */
- if (p) {
- service = p + 1;
- }
- }
-
- if (!lp_add_home(service, iHomeService, username, homedir)) {
- return -1;
- }
-
- return lp_servicenumber(service);
-
-}
-
-/**
- * Find a service entry.
- *
- * @param service is modified (to canonical form??)
- **/
-
-int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)
-{
- int iService;
-
- if (!service_in) {
- return -1;
- }
-
- /* First make a copy. */
- *p_service_out = talloc_strdup(ctx, service_in);
- if (!*p_service_out) {
- return -1;
- }
-
- all_string_sub(*p_service_out,"\\","/",0);
-
- iService = lp_servicenumber(*p_service_out);
-
- /* now handle the special case of a home directory */
- if (iService < 0) {
- char *phome_dir = get_user_home_dir(ctx, *p_service_out);
-
- if(!phome_dir) {
- /*
- * Try mapping the servicename, it may
- * be a Windows to unix mapped user name.
- */
- if(map_username(ctx, *p_service_out, p_service_out)) {
- if (*p_service_out == NULL) {
- /* Out of memory. */
- return -1;
- }
- phome_dir = get_user_home_dir(
- ctx, *p_service_out);
- }
- }
-
- DEBUG(3,("checking for home directory %s gave %s\n",*p_service_out,
- phome_dir?phome_dir:"(NULL)"));
-
- iService = add_home_service(*p_service_out,*p_service_out /* 'username' */, phome_dir);
- }
-
- /* If we still don't have a service, attempt to add it as a printer. */
- if (iService < 0) {
- int iPrinterService;
-
- if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {
- iPrinterService = load_registry_service(PRINTERS_NAME);
- }
- if (iPrinterService >= 0) {
- DEBUG(3,("checking whether %s is a valid printer name...\n",
- *p_service_out));
- if (pcap_printername_ok(*p_service_out)) {
- DEBUG(3,("%s is a valid printer name\n",
- *p_service_out));
- DEBUG(3,("adding %s as a printer service\n",
- *p_service_out));
- lp_add_printer(*p_service_out, iPrinterService);
- iService = lp_servicenumber(*p_service_out);
- if (iService < 0) {
- DEBUG(0,("failed to add %s as a printer service!\n",
- *p_service_out));
- }
- } else {
- DEBUG(3,("%s is not a valid printer name\n",
- *p_service_out));
- }
- }
- }
-
- /* Check for default vfs service? Unsure whether to implement this */
- if (iService < 0) {
- }
-
- if (iService < 0) {
- iService = load_registry_service(*p_service_out);
- }
-
- /* Is it a usershare service ? */
- if (iService < 0 && *lp_usershare_path()) {
- /* Ensure the name is canonicalized. */
- strlower_m(*p_service_out);
- iService = load_usershare_service(*p_service_out);
- }
-
- /* just possibly it's a default service? */
- if (iService < 0) {
- char *pdefservice = lp_defaultservice();
- if (pdefservice &&
- *pdefservice &&
- !strequal(pdefservice, *p_service_out)
- && !strstr_m(*p_service_out,"..")) {
- /*
- * We need to do a local copy here as lp_defaultservice()
- * returns one of the rotating lp_string buffers that
- * could get overwritten by the recursive find_service() call
- * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
- */
- char *defservice = talloc_strdup(ctx, pdefservice);
-
- if (!defservice) {
- goto fail;
- }
-
- /* Disallow anything except explicit share names. */
- if (strequal(defservice,HOMES_NAME) ||
- strequal(defservice, PRINTERS_NAME) ||
- strequal(defservice, "IPC$")) {
- TALLOC_FREE(defservice);
- goto fail;
- }
-
- iService = find_service(ctx, defservice, p_service_out);
- if (!*p_service_out) {
- TALLOC_FREE(defservice);
- iService = -1;
- goto fail;
- }
- if (iService >= 0) {
- all_string_sub(*p_service_out, "_","/",0);
- iService = lp_add_service(*p_service_out, iService);
- }
- TALLOC_FREE(defservice);
- }
- }
-
- if (iService >= 0) {
- if (!VALID_SNUM(iService)) {
- DEBUG(0,("Invalid snum %d for %s\n",iService,
- *p_service_out));
- iService = -1;
- }
- }
-
- fail:
-
- if (iService < 0) {
- DEBUG(3,("find_service() failed to find service %s\n",
- *p_service_out));
- }
-
- return (iService);
-}
-
-
/****************************************************************************
do some basic sainity checks on the share.
This function modifies dev, ecode.
@@ -930,7 +705,7 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
conn->notify_ctx = notify_init(conn,
sconn_server_id(sconn),
sconn->msg_ctx,
- smbd_event_context(),
+ server_event_context(),
conn);
}
diff --git a/source3/smbd/session.c b/source3/smbd/session.c
index f3a678b205..48afb5389f 100644
--- a/source3/smbd/session.c
+++ b/source3/smbd/session.c
@@ -231,7 +231,7 @@ static int gather_sessioninfo(const char *key, struct sessionid *session,
{
struct session_list *sesslist = (struct session_list *)private_data;
- sesslist->sessions = TALLOC_REALLOC_ARRAY(
+ sesslist->sessions = talloc_realloc(
sesslist->mem_ctx, sesslist->sessions, struct sessionid,
sesslist->count+1);
@@ -264,7 +264,7 @@ int list_sessions(TALLOC_CTX *mem_ctx, struct sessionid **session_list)
sesslist.sessions = NULL;
ret = sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist);
- if (ret == -1) {
+ if (ret < 0) {
DEBUG(3, ("Session traverse failed\n"));
SAFE_FREE(sesslist.sessions);
*session_list = NULL;
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 3cf6758e29..dda4ef296e 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -23,6 +23,7 @@
*/
#include "includes.h"
+#include "../lib/tsocket/tsocket.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/auth/spnego.h"
@@ -193,7 +194,7 @@ static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
return False;
}
/* Create server principal. */
- asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
+ asprintf(&host_princ_s, "%s$@%s", lp_netbios_name(), lp_realm());
if (!host_princ_s) {
goto out;
}
@@ -929,13 +930,28 @@ static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
}
asn1_load(data, *pblob);
- asn1_start_tag(data, pblob->data[0]);
- if (data->has_error || data->nesting == NULL) {
+ if (asn1_start_tag(data, pblob->data[0])) {
+ /* asn1_start_tag checks if the given
+ length of the blob is enough to complete
+ the tag. If it returns true we know
+ there is nothing to do - the blob is
+ complete. */
asn1_free(data);
- /* Let caller catch. */
return NT_STATUS_OK;
}
+ if (data->nesting == NULL) {
+ /* Incorrect tag, allocation failed,
+ or reading the tag length failed.
+ Let the caller catch. */
+ asn1_free(data);
+ return NT_STATUS_OK;
+ }
+
+ /* Here we know asn1_start_tag() has set data->has_error to true.
+ asn1_tag_remaining() will have failed due to the given blob
+ being too short. We need to work out how short. */
+
/* Integer wrap paranoia.... */
if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
@@ -964,6 +980,13 @@ static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
if (needed_len <= pblob->length) {
/* Nothing to do - blob is complete. */
+ /* THIS SHOULD NOT HAPPEN - asn1_start_tag()
+ above should have caught this !!! */
+ DEBUG(0,("check_spnego_blob_complete: logic "
+ "error (needed_len = %u, "
+ "pblob->length = %u).\n",
+ (unsigned int)needed_len,
+ (unsigned int)pblob->length ));
return NT_STATUS_OK;
}
@@ -1042,7 +1065,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
file_save("negotiate.dat", blob1.data, blob1.length);
#endif
- p2 = (char *)req->buf + blob1.length;
+ p2 = (const char *)req->buf + blob1.length;
p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
STR_TERMINATE);
@@ -1200,7 +1223,7 @@ static int shutdown_other_smbds(const struct connections_key *key,
struct shutdown_state *state = (struct shutdown_state *)private_data;
DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
- procid_str(talloc_tos(), &crec->pid), crec->addr));
+ server_id_str(talloc_tos(), &crec->pid), crec->addr));
if (!process_exists(crec->pid)) {
DEBUG(10, ("process does not exist\n"));
@@ -1684,7 +1707,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
data_blob_free(&lm_resp);
SSVAL(req->outbuf,smb_uid,sess_vuid);
- SSVAL(req->inbuf,smb_uid,sess_vuid);
+ SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
req->vuid = sess_vuid;
if (!sconn->smb1.sessions.done_sesssetup) {
diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c
index bea2409883..25b3c40d7d 100644
--- a/source3/smbd/signing.c
+++ b/source3/smbd/signing.c
@@ -176,7 +176,7 @@ bool srv_init_signing(struct smbd_server_connection *conn)
struct smbd_shm_signing *s;
/* setup the signing state in shared memory */
- s = talloc_zero(smbd_event_context(), struct smbd_shm_signing);
+ s = talloc_zero(server_event_context(), struct smbd_shm_signing);
if (s == NULL) {
return false;
}
@@ -198,7 +198,7 @@ bool srv_init_signing(struct smbd_server_connection *conn)
return true;
}
- conn->smb1.signing_state = smb_signing_init(smbd_event_context(),
+ conn->smb1.signing_state = smb_signing_init(server_event_context(),
allowed, mandatory);
if (!conn->smb1.signing_state) {
return false;
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index 925384c3bf..5d5ab4139d 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -23,6 +23,7 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
+#include "../lib/util/tevent_ntstatus.h"
static struct tevent_req *smbd_smb2_oplock_break_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 6e292468f9..73b8ade5bd 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -25,6 +25,7 @@
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
#include "../librpc/gen_ndr/ndr_security.h"
+#include "../lib/util/tevent_ntstatus.h"
int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level)
{
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index 3ac573c213..9fc8f1fef2 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -23,6 +23,7 @@
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
#include "trans2.h"
+#include "../lib/util/tevent_ntstatus.h"
static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -228,7 +229,7 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
int last_entry_off = 0;
int off = 0;
uint32_t num = 0;
- uint32_t dirtype = aHIDDEN | aSYSTEM | aDIR;
+ uint32_t dirtype = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY;
bool dont_descend = false;
bool ask_sharemode = true;
diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c
index 9395592907..c3f5a30129 100644
--- a/source3/smbd/smb2_flush.c
+++ b/source3/smbd/smb2_flush.c
@@ -22,6 +22,7 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
+#include "../lib/util/tevent_ntstatus.h"
static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 1d6b862d6a..3c8c690342 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -24,6 +24,7 @@
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
#include "trans2.h"
+#include "../lib/util/tevent_ntstatus.h"
static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index 6ee9318212..bce02b0a3a 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -22,6 +22,9 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
+#include "../lib/util/tevent_ntstatus.h"
+#include "rpc_server/srv_pipe_hnd.h"
+#include "include/ntioctl.h"
static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -242,8 +245,9 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
state->in_max_output = in_max_output;
state->out_output = data_blob_null;
- DEBUG(10,("smbd_smb2_ioctl: file_id[0x%016llX]\n",
- (unsigned long long)in_file_id_volatile));
+ DEBUG(10, ("smbd_smb2_ioctl: ctl_code[0x%08x] file_id[0x%016llX]\n",
+ (unsigned)in_ctl_code,
+ (unsigned long long)in_file_id_volatile));
smbreq = smbd_smb2_fake_smb_request(smb2req);
if (tevent_req_nomem(smbreq, req)) {
@@ -375,6 +379,131 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
req);
return req;
+ case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */
+ {
+ /*
+ * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
+ * and return their volume names. If max_data_count is 16, then it is just
+ * asking for the number of volumes and length of the combined names.
+ *
+ * pdata is the data allocated by our caller, but that uses
+ * total_data_count (which is 0 in our case) rather than max_data_count.
+ * Allocate the correct amount and return the pointer to let
+ * it be deallocated when we return.
+ */
+ struct shadow_copy_data *shadow_data = NULL;
+ bool labels = False;
+ uint32_t labels_data_count = 0;
+ uint32_t data_count;
+ uint32_t i;
+ char *pdata;
+ NTSTATUS status;
+
+ if (fsp == NULL) {
+ tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
+ return tevent_req_post(req, ev);
+ }
+
+ if (in_max_output < 16) {
+ DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: "
+ "in_max_output(%u) < 16 is invalid!\n",
+ in_max_output));
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ if (in_max_output > 16) {
+ labels = True;
+ }
+
+ shadow_data = talloc_zero(talloc_tos(),
+ struct shadow_copy_data);
+ if (tevent_req_nomem(shadow_data, req)) {
+ DEBUG(0,("TALLOC_ZERO() failed!\n"));
+ return tevent_req_post(req, ev);
+ }
+
+ /*
+ * Call the VFS routine to actually do the work.
+ */
+ if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)
+ != 0) {
+ if (errno == ENOSYS) {
+ DEBUG(5, ("FSCTL_GET_SHADOW_COPY_DATA: "
+ "connectpath %s, not supported.\n",
+ smbreq->conn->connectpath));
+ status = NT_STATUS_NOT_SUPPORTED;
+ } else {
+ DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: "
+ "connectpath %s, failed.\n",
+ smbreq->conn->connectpath));
+ status = map_nt_error_from_unix(errno);
+ }
+ TALLOC_FREE(shadow_data);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ labels_data_count =
+ (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))
+ + 2;
+
+ if (labels) {
+ data_count = 12+labels_data_count+4;
+ } else {
+ data_count = 16;
+ }
+
+ if (labels && (in_max_output < data_count)) {
+ DEBUG(0, ("FSCTL_GET_SHADOW_COPY_DATA: "
+ "in_max_output(%u) too small (%u) bytes "
+ "needed!\n", in_max_output, data_count));
+ TALLOC_FREE(shadow_data);
+ tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
+ return tevent_req_post(req, ev);
+ }
+
+ state->out_output = data_blob_talloc(state, NULL, data_count);
+ if (tevent_req_nomem(state->out_output.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ pdata = (char *)state->out_output.data;
+
+ /* num_volumes 4 bytes */
+ SIVAL(pdata, 0, shadow_data->num_volumes);
+
+ if (labels) {
+ /* num_labels 4 bytes */
+ SIVAL(pdata, 4, shadow_data->num_volumes);
+ }
+
+ /* needed_data_count 4 bytes */
+ SIVAL(pdata, 8, labels_data_count+4);
+
+ pdata += 12;
+
+ DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for "
+ "path[%s].\n",
+ shadow_data->num_volumes, fsp_str_dbg(fsp)));
+ if (labels && shadow_data->labels) {
+ for (i=0; i<shadow_data->num_volumes; i++) {
+ srvstr_push(pdata, smbreq->flags2,
+ pdata, shadow_data->labels[i],
+ 2*sizeof(SHADOW_COPY_LABEL),
+ STR_UNICODE|STR_TERMINATE);
+ pdata += 2*sizeof(SHADOW_COPY_LABEL);
+ DEBUGADD(10, ("Label[%u]: '%s'\n", i,
+ shadow_data->labels[i]));
+ }
+ }
+
+ TALLOC_FREE(shadow_data);
+
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+ }
+
default:
if (IS_IPC(smbreq->conn)) {
tevent_req_nterror(req, NT_STATUS_FS_DRIVER_REQUIRED);
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index dcf1e0c6a5..5d615e1bed 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -23,6 +23,7 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
+#include "../lib/util/tevent_ntstatus.h"
#include "messages.h"
struct smbd_smb2_lock_element {
@@ -567,7 +568,7 @@ static bool recalc_smb2_brl_timeout(struct smbd_server_connection *sconn)
}
sconn->smb2.locks.brl_timeout = event_add_timed(
- smbd_event_context(),
+ server_event_context(),
NULL,
next_timeout,
brl_timeout_fn,
@@ -627,9 +628,7 @@ bool push_blocking_lock_request_smb2( struct byte_range_lock *br_lck,
blr->expire_time.tv_sec = 0;
blr->expire_time.tv_usec = 0; /* Never expire. */
} else {
- blr->expire_time = timeval_current_ofs(
- lock_timeout/1000,
- (lock_timeout % 1000) * 1000);
+ blr->expire_time = timeval_current_ofs_msec(lock_timeout);
}
blr->lock_num = lock_num;
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 1e02c88d3d..f639503ad4 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -78,7 +78,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
uint16_t dialect = 0;
uint32_t capabilities;
-/* TODO: drop the connection with INVALI_PARAMETER */
+/* TODO: drop the connection with INVALID_PARAMETER */
if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
@@ -177,5 +177,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
outdyn = security_buffer;
+ req->sconn->using_smb2 = true;
+
return smbd_smb2_request_done(req, outbody, &outdyn);
}
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index d52b2878ec..9e377ceda4 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -23,6 +23,7 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
+#include "../lib/util/tevent_ntstatus.h"
struct smbd_smb2_notify_state {
struct smbd_smb2_request *smb2req;
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index bffda89010..6e686ef273 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -24,6 +24,8 @@
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
#include "libcli/security/security.h"
+#include "../lib/util/tevent_ntstatus.h"
+#include "rpc_server/srv_pipe_hnd.h"
static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -306,7 +308,7 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
/* Make a copy of state attached to the smb2req. Attach
the destructor here as this will trigger the sendfile
call when the request is destroyed. */
- state_copy = TALLOC_P(smb2req, struct smbd_smb2_read_state);
+ state_copy = talloc(smb2req, struct smbd_smb2_read_state);
if (!state_copy) {
return NT_STATUS_NO_MEMORY;
}
@@ -442,7 +444,7 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- subreq = np_read_send(state, smbd_event_context(),
+ subreq = np_read_send(state, server_event_context(),
fsp->fake_file_handle,
state->out_data.data,
state->out_data.length);
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 0004e7ca8c..65bb5b9eb0 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -24,6 +24,7 @@
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
#include "../lib/tsocket/tsocket.h"
+#include "../lib/util/tevent_ntstatus.h"
#include "smbprofile.h"
#define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
@@ -94,7 +95,7 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *sconn)
TALLOC_FREE(sconn->smb1.fde);
- sconn->smb2.event_ctx = smbd_event_context();
+ sconn->smb2.event_ctx = server_event_context();
sconn->smb2.recv_queue = tevent_queue_create(sconn, "smb2 recv queue");
if (sconn->smb2.recv_queue == NULL) {
@@ -268,15 +269,15 @@ static NTSTATUS smbd_smb2_request_create(struct smbd_server_connection *sconn,
memcpy(req->in.nbt_hdr, inbuf, 4);
ofs = 0;
- req->in.vector[0].iov_base = (void *)req->in.nbt_hdr;
+ req->in.vector[0].iov_base = discard_const_p(void, req->in.nbt_hdr);
req->in.vector[0].iov_len = 4;
ofs += req->in.vector[0].iov_len;
- req->in.vector[1].iov_base = (void *)(inbuf + ofs);
+ req->in.vector[1].iov_base = discard_const_p(void, (inbuf + ofs));
req->in.vector[1].iov_len = SMB2_HDR_BODY;
ofs += req->in.vector[1].iov_len;
- req->in.vector[2].iov_base = (void *)(inbuf + ofs);
+ req->in.vector[2].iov_base = discard_const_p(void, (inbuf + ofs));
req->in.vector[2].iov_len = SVAL(inbuf, ofs) & 0xFFFE;
ofs += req->in.vector[2].iov_len;
@@ -284,7 +285,7 @@ static NTSTATUS smbd_smb2_request_create(struct smbd_server_connection *sconn,
return NT_STATUS_INVALID_PARAMETER;
}
- req->in.vector[3].iov_base = (void *)(inbuf + ofs);
+ req->in.vector[3].iov_base = discard_const_p(void, (inbuf + ofs));
req->in.vector[3].iov_len = size - ofs;
ofs += req->in.vector[3].iov_len;
@@ -607,7 +608,7 @@ static bool dup_smb2_vec3(TALLOC_CTX *ctx,
srcvec[1].iov_base ==
((uint8_t *)srcvec[0].iov_base) +
SMB2_HDR_BODY) {
- outvec[1].iov_base = ((uint8_t *)outvec[1].iov_base) +
+ outvec[1].iov_base = ((uint8_t *)outvec[0].iov_base) +
SMB2_HDR_BODY;
outvec[1].iov_len = 8;
} else {
@@ -2017,9 +2018,11 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream,
invalid = true;
}
- if ((body_size % 2) != 0) {
- body_size -= 1;
- }
+ /*
+ * Mask out the lowest bit, the "dynamic" part
+ * of body_size.
+ */
+ body_size &= ~1;
if (body_size > (full_size - SMB2_HDR_BODY)) {
/*
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index d727ee98b0..c33d1c61be 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -844,7 +844,7 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
if (chained_fixup) {
/* Fix up our own outhdr. */
outhdr = (const uint8_t *)req->out.vector[i].iov_base;
- SBVAL(outhdr, SMB2_HDR_SESSION_ID, in_session_id);
+ SBVAL(discard_const_p(uint8_t, outhdr), SMB2_HDR_SESSION_ID, in_session_id);
}
return NT_STATUS_OK;
}
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index 39b7aee76b..e1149408d1 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -24,6 +24,7 @@
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
#include "trans2.h"
+#include "../lib/util/tevent_ntstatus.h"
static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index bdd18d5d07..1b4aa79070 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -331,7 +331,7 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
if (chained_fixup) {
/* Fix up our own outhdr. */
outhdr = (const uint8_t *)req->out.vector[i].iov_base;
- SIVAL(outhdr, SMB2_HDR_TID, in_tid);
+ SIVAL(discard_const_p(uint8_t, outhdr), SMB2_HDR_TID, in_tid);
}
return NT_STATUS_OK;
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index 413fe0c7d1..057abcc8f7 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -22,6 +22,8 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
+#include "../lib/util/tevent_ntstatus.h"
+#include "rpc_server/srv_pipe_hnd.h"
static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -281,7 +283,7 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- subreq = np_write_send(state, smbd_event_context(),
+ subreq = np_write_send(state, server_event_context(),
fsp->fake_file_handle,
in_data.data,
in_data.length);
diff --git a/source3/smbd/srvstr.c b/source3/smbd/srvstr.c
index 050de599a5..c069dd4a5e 100644
--- a/source3/smbd/srvstr.c
+++ b/source3/smbd/srvstr.c
@@ -56,7 +56,7 @@ ssize_t message_push_string(uint8 **outbuf, const char *str, int flags)
*/
grow_size = (strlen(str) + 2) * 4;
- if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8,
+ if (!(tmp = talloc_realloc(NULL, *outbuf, uint8,
buf_size + grow_size))) {
DEBUG(0, ("talloc failed\n"));
return -1;
diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c
index 5c74b92855..963b7c4bc1 100644
--- a/source3/smbd/statcache.c
+++ b/source3/smbd/statcache.c
@@ -25,6 +25,7 @@
#include "smbd/smbd.h"
#include "messages.h"
#include "smbprofile.h"
+#include "tdb_compat.h"
/****************************************************************************
Stat cache code used in unix_convert.
@@ -339,8 +340,8 @@ bool stat_cache_lookup(connection_struct *conn,
Tell all smbd's to delete an entry.
**************************************************************************/
-void send_stat_cache_delete_message(struct messaging_context *msg_ctx,
- const char *name)
+void smbd_send_stat_cache_delete_message(struct messaging_context *msg_ctx,
+ const char *name)
{
#ifdef DEVELOPER
message_send_all(msg_ctx,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 507ae9ba93..b853722eae 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -35,6 +35,7 @@
#include "trans2.h"
#include "auth.h"
#include "smbprofile.h"
+#include "rpc_server/srv_pipe_hnd.h"
#define DIR_ENTRY_SAFETY_MARGIN 4096
@@ -106,7 +107,7 @@ static bool samba_private_attr_name(const char *unix_ea_name)
if (strequal( prohibited_ea_names[i], unix_ea_name))
return true;
}
- if (StrnCaseCmp(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
+ if (strncasecmp_m(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
return true;
}
@@ -128,7 +129,7 @@ NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
again:
- val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
+ val = talloc_realloc(mem_ctx, val, char, attr_size);
if (!val) {
return NT_STATUS_NO_MEMORY;
}
@@ -191,7 +192,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
* TALLOC the result early to get the talloc hierarchy right.
*/
- names = TALLOC_ARRAY(mem_ctx, char *, 1);
+ names = talloc_array(mem_ctx, char *, 1);
if (names == NULL) {
DEBUG(0, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
@@ -199,7 +200,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
while (ea_namelist_size <= 65536) {
- ea_namelist = TALLOC_REALLOC_ARRAY(
+ ea_namelist = talloc_realloc(
names, ea_namelist, char, ea_namelist_size);
if (ea_namelist == NULL) {
DEBUG(0, ("talloc failed\n"));
@@ -258,7 +259,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
num_names += 1;
}
- tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names);
+ tmp = talloc_realloc(mem_ctx, names, char *, num_names);
if (tmp == NULL) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(names);
@@ -315,7 +316,7 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str
|| samba_private_attr_name(names[i]))
continue;
- listp = TALLOC_P(mem_ctx, struct ea_list);
+ listp = talloc(mem_ctx, struct ea_list);
if (listp == NULL) {
return NULL;
}
@@ -387,7 +388,7 @@ static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned in
SCVAL(p,0,ea_list->ea.flags);
SCVAL(p,1,dos_namelen);
SSVAL(p,2,ea_list->ea.value.length);
- fstrcpy(p+4, dos_ea_name);
+ strlcpy(p+4, dos_ea_name, dos_namelen+1);
memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
@@ -451,7 +452,7 @@ static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
SCVAL(p, 0x04, ea_list->ea.flags);
SCVAL(p, 0x05, dos_namelen);
SSVAL(p, 0x06, ea_list->ea.value.length);
- fstrcpy((char *)(p+0x08), dos_ea_name);
+ strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
total_data_size -= this_size;
@@ -490,7 +491,7 @@ static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, con
if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
&unix_ea_name[5], ea_list->ea.name));
- safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
+ strlcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-5);
break;
}
}
@@ -589,7 +590,7 @@ static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, siz
size_t converted_size, offset = 0;
while (offset + 2 < data_size) {
- struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+ struct ea_list *eal = talloc_zero(ctx, struct ea_list);
unsigned int namelen = CVAL(pdata,offset);
offset++; /* Go past the namelen byte. */
@@ -627,7 +628,7 @@ static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, siz
struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
{
- struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+ struct ea_list *eal = talloc_zero(ctx, struct ea_list);
uint16 val_len;
unsigned int namelen;
size_t converted_size;
@@ -1148,7 +1149,7 @@ static void call_trans2open(connection_struct *conn,
fattr = dos_mode(conn, smb_fname);
mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
inode = smb_fname->st.st_ex_ino;
- if (fattr & aDIR) {
+ if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
close_file(req, fsp, ERROR_CLOSE);
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
goto out;
@@ -1218,7 +1219,7 @@ static bool exact_match(bool has_wild,
if (case_sensitive) {
return strcmp(str,mask)==0;
} else {
- return StrCaseCmp(str,mask) == 0;
+ return strcasecmp_m(str,mask) == 0;
}
}
@@ -1524,7 +1525,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
ZERO_STRUCT(create_date_ts);
ZERO_STRUCT(cdate_ts);
- if (!(mode & aDIR)) {
+ if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
file_size = get_file_size_stat(&smb_fname->st);
}
allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
@@ -3733,36 +3734,10 @@ cap_low = 0x%x, cap_high = 0x%x\n",
/* unknown_1 24 NULL bytes in pdata*/
/* the soft quotas 8 bytes (uint64_t)*/
- quotas.softlim = (uint64_t)IVAL(pdata,24);
-#ifdef LARGE_SMB_OFF_T
- quotas.softlim |= (((uint64_t)IVAL(pdata,28)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,28) != 0)&&
- ((quotas.softlim != 0xFFFFFFFF)||
- (IVAL(pdata,28)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- reply_nterror(
- req,
- NT_STATUS_INVALID_PARAMETER);
- return;
- }
-#endif /* LARGE_SMB_OFF_T */
+ quotas.softlim = BVAL(pdata,24);
/* the hard quotas 8 bytes (uint64_t)*/
- quotas.hardlim = (uint64_t)IVAL(pdata,32);
-#ifdef LARGE_SMB_OFF_T
- quotas.hardlim |= (((uint64_t)IVAL(pdata,36)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,36) != 0)&&
- ((quotas.hardlim != 0xFFFFFFFF)||
- (IVAL(pdata,36)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- reply_nterror(
- req,
- NT_STATUS_INVALID_PARAMETER);
- return;
- }
-#endif /* LARGE_SMB_OFF_T */
+ quotas.hardlim = BVAL(pdata,32);
/* quota_flags 2 bytes **/
quotas.qflags = SVAL(pdata,40);
@@ -4253,7 +4228,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
mode = dos_mode(conn, smb_fname);
nlink = psbuf->st_ex_nlink;
- if (nlink && (mode&aDIR)) {
+ if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
nlink = 1;
}
@@ -4334,7 +4309,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
}
}
- if (!(mode & aDIR)) {
+ if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
file_size = get_file_size_stat(psbuf);
}
@@ -4504,7 +4479,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
SOFF_T(pdata,8,file_size);
SIVAL(pdata,16,nlink);
SCVAL(pdata,20,delete_pending?1:0);
- SCVAL(pdata,21,(mode&aDIR)?1:0);
+ SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
SSVAL(pdata,22,0); /* Padding. */
break;
@@ -4587,7 +4562,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
SOFF_T(pdata,8,file_size);
SIVAL(pdata,16,nlink);
SCVAL(pdata,20,delete_pending);
- SCVAL(pdata,21,(mode&aDIR)?1:0);
+ SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
SSVAL(pdata,22,0);
pdata += 24;
SIVAL(pdata,0,ea_size);
@@ -4618,7 +4593,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
SBVAL(pdata, 0x30, file_size);
SIVAL(pdata, 0x38, nlink);
SCVAL(pdata, 0x3C, delete_pending);
- SCVAL(pdata, 0x3D, (mode&aDIR)?1:0);
+ SCVAL(pdata, 0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
SSVAL(pdata, 0x3E, 0); /* padding */
SBVAL(pdata, 0x40, file_index);
SIVAL(pdata, 0x48, ea_size);
@@ -4793,7 +4768,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
case SMB_QUERY_FILE_UNIX_LINK:
{
int len;
- char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
+ char *buffer = talloc_array(mem_ctx, char, PATH_MAX+1);
if (!buffer) {
return NT_STATUS_NO_MEMORY;
@@ -5326,7 +5301,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
/* Copy the lock range data. */
- lock_data = (char *)TALLOC_MEMDUP(
+ lock_data = (char *)talloc_memdup(
req, pdata, total_data);
if (!lock_data) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -5580,9 +5555,9 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
if (dosmode) {
if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
- dosmode |= aDIR;
+ dosmode |= FILE_ATTRIBUTE_DIRECTORY;
} else {
- dosmode &= ~aDIR;
+ dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
}
}
@@ -6075,8 +6050,9 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
"SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
fsp->fnum, fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
- status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
- overwrite);
+ status = rename_internals_fsp(conn, fsp, smb_fname_dst,
+ (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
+ overwrite);
out:
TALLOC_FREE(smb_fname_dst);
@@ -7251,6 +7227,9 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
Open/Create a file with POSIX semantics.
****************************************************************************/
+#define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
+#define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
+
static NTSTATUS smb_posix_open(connection_struct *conn,
struct smb_request *req,
char **ppdata,
@@ -7266,7 +7245,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
uint32 mod_unixmode = 0;
uint32 create_disp = 0;
uint32 access_mask = 0;
- uint32 create_options = 0;
+ uint32 create_options = FILE_NON_DIRECTORY_FILE;
NTSTATUS status = NT_STATUS_OK;
mode_t unixmode = (mode_t)0;
files_struct *fsp = NULL;
@@ -7296,13 +7275,14 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
switch (wire_open_mode & SMB_ACCMODE) {
case SMB_O_RDONLY:
- access_mask = FILE_READ_DATA;
+ access_mask = SMB_O_RDONLY_MAPPING;
break;
case SMB_O_WRONLY:
- access_mask = FILE_WRITE_DATA;
+ access_mask = SMB_O_WRONLY_MAPPING;
break;
case SMB_O_RDWR:
- access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
+ access_mask = (SMB_O_RDONLY_MAPPING|
+ SMB_O_WRONLY_MAPPING);
break;
default:
DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
@@ -7312,18 +7292,55 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
wire_open_mode &= ~SMB_ACCMODE;
- if((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) == (SMB_O_CREAT | SMB_O_EXCL)) {
- create_disp = FILE_CREATE;
- } else if((wire_open_mode & (SMB_O_CREAT | SMB_O_TRUNC)) == (SMB_O_CREAT | SMB_O_TRUNC)) {
- create_disp = FILE_OVERWRITE_IF;
- } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
- create_disp = FILE_OPEN_IF;
- } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC)) == 0) {
- create_disp = FILE_OPEN;
- } else {
- DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
- (unsigned int)wire_open_mode ));
- return NT_STATUS_INVALID_PARAMETER;
+ /* First take care of O_CREAT|O_EXCL interactions. */
+ switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
+ case (SMB_O_CREAT | SMB_O_EXCL):
+ /* File exists fail. File not exist create. */
+ create_disp = FILE_CREATE;
+ break;
+ case SMB_O_CREAT:
+ /* File exists open. File not exist create. */
+ create_disp = FILE_OPEN_IF;
+ break;
+ case 0:
+ /* File exists open. File not exist fail. */
+ create_disp = FILE_OPEN;
+ break;
+ case SMB_O_EXCL:
+ /* O_EXCL on its own without O_CREAT is undefined. */
+ default:
+ DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
+ (unsigned int)wire_open_mode ));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Next factor in the effects of O_TRUNC. */
+ wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
+
+ if (wire_open_mode & SMB_O_TRUNC) {
+ switch (create_disp) {
+ case FILE_CREATE:
+ /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
+ /* Leave create_disp alone as
+ (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
+ */
+ /* File exists fail. File not exist create. */
+ break;
+ case FILE_OPEN_IF:
+ /* SMB_O_CREAT | SMB_O_TRUNC */
+ /* File exists overwrite. File not exist create. */
+ create_disp = FILE_OVERWRITE_IF;
+ break;
+ case FILE_OPEN:
+ /* SMB_O_TRUNC */
+ /* File exists overwrite. File not exist fail. */
+ create_disp = FILE_OVERWRITE;
+ break;
+ default:
+ /* Cannot get here. */
+ smb_panic("smb_posix_open: logic error");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
}
raw_unixmode = IVAL(pdata,8);
@@ -7350,6 +7367,15 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
mod_unixmode |= FILE_FLAG_NO_BUFFERING;
}
+ if ((wire_open_mode & SMB_O_DIRECTORY) ||
+ VALID_STAT_OF_DIR(smb_fname->st)) {
+ if (access_mask != SMB_O_RDONLY_MAPPING) {
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
+ }
+ create_options &= ~FILE_NON_DIRECTORY_FILE;
+ create_options |= FILE_DIRECTORY_FILE;
+ }
+
DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
smb_fname_str_dbg(smb_fname),
(unsigned int)wire_open_mode,
@@ -7364,7 +7390,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
(FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
FILE_SHARE_DELETE),
create_disp, /* create_disposition*/
- FILE_NON_DIRECTORY_FILE, /* create_options */
+ create_options, /* create_options */
mod_unixmode, /* file_attributes */
oplock_request, /* oplock_request */
0, /* allocation_size */
@@ -8302,7 +8328,7 @@ static void call_trans2getdfsreferral(connection_struct *conn,
return;
}
- SSVAL(req->inbuf, smb_flg2,
+ SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
@@ -8351,7 +8377,7 @@ static void call_trans2ioctl(connection_struct *conn,
SSVAL(pdata, 0, 0);
}
srvstr_push(pdata, req->flags2, pdata + 2,
- global_myname(), 15,
+ lp_netbios_name(), 15,
STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
srvstr_push(pdata, req->flags2, pdata+18,
lp_servicename(SNUM(conn)), 13,
@@ -8433,7 +8459,7 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req,
{
if (get_Protocol() >= PROTOCOL_NT1) {
req->flags2 |= 0x40; /* IS_LONG_NAME */
- SSVAL(req->inbuf,smb_flg2,req->flags2);
+ SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
}
if (conn->encrypt_level == Required && !req->encrypted) {
@@ -8646,7 +8672,7 @@ void reply_trans2(struct smb_request *req)
}
}
- if ((state = TALLOC_P(conn, struct trans_state)) == NULL) {
+ if ((state = talloc(conn, struct trans_state)) == NULL) {
DEBUG(0, ("talloc failed\n"));
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtrans2);
@@ -8792,7 +8818,7 @@ void reply_transs2(struct smb_request *req)
START_PROFILE(SMBtranss2);
- show_msg((char *)req->inbuf);
+ show_msg((const char *)req->inbuf);
if (req->wct < 8) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index b554b36054..285b158a19 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -25,7 +25,6 @@
#include "libcli/security/security.h"
#include "passdb/lookup_sid.h"
#include "auth.h"
-#include "ntdomain.h"
/* what user is current? */
extern struct current_user current_user;
@@ -183,50 +182,6 @@ static bool check_user_ok(connection_struct *conn,
}
/****************************************************************************
- Clear a vuid out of the connection's vuid cache
- This is only called on SMBulogoff.
-****************************************************************************/
-
-void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
-{
- int i;
-
- for (i=0; i<VUID_CACHE_SIZE; i++) {
- struct vuid_cache_entry *ent;
-
- ent = &conn->vuid_cache.array[i];
-
- if (ent->vuid == vuid) {
- ent->vuid = UID_FIELD_INVALID;
- /*
- * We need to keep conn->session_info around
- * if it's equal to ent->session_info as a SMBulogoff
- * is often followed by a SMBtdis (with an invalid
- * vuid). The debug code (or regular code in
- * vfs_full_audit) wants to refer to the
- * conn->session_info pointer to print debug
- * statements. Theoretically this is a bug,
- * as once the vuid is gone the session_info
- * on the conn struct isn't valid any more,
- * but there's enough code that assumes
- * conn->session_info is never null that
- * it's easier to hold onto the old pointer
- * until we get a new sessionsetupX.
- * As everything is hung off the
- * conn pointer as a talloc context we're not
- * leaking memory here. See bug #6315. JRA.
- */
- if (conn->session_info == ent->session_info) {
- ent->session_info = NULL;
- } else {
- TALLOC_FREE(ent->session_info);
- }
- ent->read_only = False;
- }
- }
-}
-
-/****************************************************************************
Become the user of a connection number without changing the security context
stack, but modify the current_user entries.
****************************************************************************/
@@ -390,7 +345,7 @@ bool change_to_user_by_session(connection_struct *conn,
but modify the current_user entries.
****************************************************************************/
-bool change_to_root_user(void)
+bool smbd_change_to_root_user(void)
{
set_root_sec_ctx();
@@ -409,14 +364,14 @@ bool change_to_root_user(void)
user. Doesn't modify current_user.
****************************************************************************/
-bool become_authenticated_pipe_user(struct pipes_struct *p)
+bool become_authenticated_pipe_user(struct auth_serversupplied_info *session_info)
{
if (!push_sec_ctx())
return False;
- set_sec_ctx(p->session_info->utok.uid, p->session_info->utok.gid,
- p->session_info->utok.ngroups, p->session_info->utok.groups,
- p->session_info->security_token);
+ set_sec_ctx(session_info->utok.uid, session_info->utok.gid,
+ session_info->utok.ngroups, session_info->utok.groups,
+ session_info->security_token);
return True;
}
@@ -486,7 +441,7 @@ static void pop_conn_ctx(void)
restores the connection context.
****************************************************************************/
-void become_root(void)
+void smbd_become_root(void)
{
/*
* no good way to handle push_sec_ctx() failing without changing
@@ -501,7 +456,7 @@ void become_root(void)
/* Unbecome the root user */
-void unbecome_root(void)
+void smbd_unbecome_root(void)
{
pop_sec_ctx();
pop_conn_ctx();
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 3b482e7f0c..7be3867267 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -183,7 +183,7 @@ bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
- handle = TALLOC_ZERO_P(conn, vfs_handle_struct);
+ handle = talloc_zero(conn, vfs_handle_struct);
if (!handle) {
DEBUG(0,("TALLOC_ZERO() failed!\n"));
goto fail;
@@ -795,7 +795,7 @@ int vfs_ChDir(connection_struct *conn, const char *path)
char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
{
- char s[PATH_MAX+1];
+ char *current_dir = NULL;
char *result = NULL;
DATA_BLOB cache_value;
struct file_id key;
@@ -803,8 +803,6 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
struct smb_filename *smb_fname_full = NULL;
NTSTATUS status;
- *s = 0;
-
if (!lp_getwd_cache()) {
goto nocache;
}
@@ -866,7 +864,8 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
* systems, or the not quite so bad getwd.
*/
- if (!SMB_VFS_GETWD(conn,s)) {
+ current_dir = SMB_VFS_GETWD(conn);
+ if (current_dir == NULL) {
DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
strerror(errno)));
goto out;
@@ -877,10 +876,11 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
memcache_add(smbd_memcache(), GETWD_CACHE,
data_blob_const(&key, sizeof(key)),
- data_blob_const(s, strlen(s)+1));
+ data_blob_const(current_dir,
+ strlen(current_dir)+1));
}
- result = talloc_strdup(ctx, s);
+ result = talloc_strdup(ctx, current_dir);
if (result == NULL) {
errno = ENOMEM;
}
@@ -888,6 +888,7 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
out:
TALLOC_FREE(smb_fname_dot);
TALLOC_FREE(smb_fname_full);
+ SAFE_FREE(current_dir);
return result;
}
@@ -899,6 +900,8 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
{
char *resolved_name = NULL;
+ bool allow_symlinks = true;
+ bool allow_widelinks = false;
DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
@@ -973,9 +976,13 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
return NT_STATUS_OBJECT_NAME_INVALID;
}
- /* Check for widelinks allowed. */
- if (!lp_widelinks(SNUM(conn))) {
+ allow_widelinks = lp_widelinks(SNUM(conn));
+ allow_symlinks = lp_symlinks(SNUM(conn));
+
+ /* Common widelinks and symlinks checks. */
+ if (!allow_widelinks || !allow_symlinks) {
const char *conn_rootdir;
+ size_t rootdir_len;
conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
if (conn_rootdir == NULL) {
@@ -985,8 +992,9 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
return NT_STATUS_ACCESS_DENIED;
}
+ rootdir_len = strlen(conn_rootdir);
if (strncmp(conn_rootdir, resolved_name,
- strlen(conn_rootdir)) != 0) {
+ rootdir_len) != 0) {
DEBUG(2, ("check_reduced_name: Bad access "
"attempt: %s is a symlink outside the "
"share path\n", fname));
@@ -995,35 +1003,38 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
SAFE_FREE(resolved_name);
return NT_STATUS_ACCESS_DENIED;
}
- }
- /* Check if we are allowing users to follow symlinks */
- /* Patch from David Clerc <David.Clerc@cui.unige.ch>
- University of Geneva */
+ /* Extra checks if all symlinks are disallowed. */
+ if (!allow_symlinks) {
+ /* fname can't have changed in resolved_path. */
+ const char *p = &resolved_name[rootdir_len];
-#ifdef S_ISLNK
- if (!lp_symlinks(SNUM(conn))) {
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
+ /* *p can be '\0' if fname was "." */
+ if (*p == '\0' && ISDOT(fname)) {
+ goto out;
+ }
- status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- SAFE_FREE(resolved_name);
- return status;
+ if (*p != '/') {
+ DEBUG(2, ("check_reduced_name: logic error (%c) "
+ "in resolved_name: %s\n",
+ *p,
+ fname));
+ SAFE_FREE(resolved_name);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ p++;
+ if (strcmp(fname, p)!=0) {
+ DEBUG(2, ("check_reduced_name: Bad access "
+ "attempt: %s is a symlink\n",
+ fname));
+ SAFE_FREE(resolved_name);
+ return NT_STATUS_ACCESS_DENIED;
+ }
}
+ }
- if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) &&
- (S_ISLNK(smb_fname->st.st_ex_mode)) ) {
- SAFE_FREE(resolved_name);
- DEBUG(3,("check_reduced_name: denied: file path name "
- "%s is a symlink\n",resolved_name));
- TALLOC_FREE(smb_fname);
- return NT_STATUS_ACCESS_DENIED;
- }
- TALLOC_FREE(smb_fname);
- }
-#endif
+ out:
DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
resolved_name));
@@ -1164,7 +1175,7 @@ int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
struct files_struct *fsp,
- SHADOW_COPY_DATA *shadow_copy_data,
+ struct shadow_copy_data *shadow_copy_data,
bool labels)
{
VFS_FIND(get_shadow_copy_data);
@@ -1496,7 +1507,7 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
}
ZERO_STRUCT(local_fname);
- local_fname.base_name = CONST_DISCARD(char *,final_component);
+ local_fname.base_name = discard_const_p(char, final_component);
/* Must use lstat here. */
ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
@@ -1543,10 +1554,10 @@ int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
return handle->fns->chdir(handle, path);
}
-char *smb_vfs_call_getwd(struct vfs_handle_struct *handle, char *buf)
+char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
{
VFS_FIND(getwd);
- return handle->fns->getwd(handle, buf);
+ return handle->fns->getwd(handle);
}
int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,