#include "smbd/globals.h"
#include "lib/util/bitmap.h"
+static void conn_free_internal(connection_struct *conn);
+
+/****************************************************************************
+ * Remove a conn struct from conn->sconn->connections
+ * if not already done.
+****************************************************************************/
+
+static int conn_struct_destructor(connection_struct *conn)
+{
+ if (conn->sconn != NULL) {
+ DLIST_REMOVE(conn->sconn->connections, conn);
+ SMB_ASSERT(conn->sconn->num_connections > 0);
+ conn->sconn->num_connections--;
+ conn->sconn = NULL;
+ }
+ conn_free_internal(conn);
+ return 0;
+}
+
/****************************************************************************
Return the number of open connections.
****************************************************************************/
return false;
}
+enum protocol_types conn_protocol(struct smbd_server_connection *sconn)
+{
+ if ((sconn != NULL) &&
+ (sconn->client != NULL) &&
+ (sconn->client->connections != NULL)) {
+ return sconn->client->connections->protocol;
+ }
+ /*
+ * Default to what source3/lib/util.c has as default for the
+ * static Protocol variable to not change behaviour.
+ */
+ return PROTOCOL_COREPLUS;
+}
+
+bool conn_using_smb2(struct smbd_server_connection *sconn)
+{
+ enum protocol_types proto = conn_protocol(sconn);
+ return (proto >= PROTOCOL_SMB2_02);
+}
+
/****************************************************************************
Find first available connection slot, starting from a random position.
- The randomisation stops problems with the server dieing and clients
+ The randomisation stops problems with the server dying and clients
thinking the server is still available.
****************************************************************************/
connection_struct *conn_new(struct smbd_server_connection *sconn)
{
- connection_struct *conn;
+ connection_struct *conn = NULL;
- if (!(conn=talloc_zero(NULL, connection_struct)) ||
- !(conn->params = talloc(conn, struct share_params)) ||
- !(conn->vuid_cache = talloc_zero(conn, struct vuid_cache)) ||
- !(conn->connectpath = talloc_strdup(conn, "")) ||
- !(conn->origpath = talloc_strdup(conn, ""))) {
- DEBUG(0,("TALLOC_ZERO() failed!\n"));
+ conn = talloc_zero(NULL, connection_struct);
+ if (conn == NULL) {
+ DBG_ERR("talloc_zero failed\n");
+ return NULL;
+ }
+ conn->params = talloc(conn, struct share_params);
+ if (conn->params == NULL) {
+ DBG_ERR("talloc_zero failed\n");
+ TALLOC_FREE(conn);
+ return NULL;
+ }
+ conn->vuid_cache = talloc_zero(conn, struct vuid_cache);
+ if (conn->vuid_cache == NULL) {
+ DBG_ERR("talloc_zero failed\n");
+ TALLOC_FREE(conn);
+ return NULL;
+ }
+ conn->connectpath = talloc_strdup(conn, "");
+ if (conn->connectpath == NULL) {
+ DBG_ERR("talloc_zero failed\n");
+ TALLOC_FREE(conn);
+ return NULL;
+ }
+ conn->cwd_fsp = talloc_zero(conn, struct files_struct);
+ if (conn->cwd_fsp == NULL) {
+ DBG_ERR("talloc_zero failed\n");
+ TALLOC_FREE(conn);
+ return NULL;
+ }
+ conn->cwd_fsp->fsp_name = synthetic_smb_fname(conn->cwd_fsp,
+ ".",
+ NULL,
+ NULL,
+ 0,
+ 0);
+ if (conn->cwd_fsp->fsp_name == NULL) {
+ TALLOC_FREE(conn);
+ return NULL;
+ }
+ conn->cwd_fsp->fh = fd_handle_create(conn->cwd_fsp);
+ if (conn->cwd_fsp->fh == NULL) {
+ DBG_ERR("talloc_zero failed\n");
TALLOC_FREE(conn);
return NULL;
}
conn->sconn = sconn;
conn->force_group_gid = (gid_t)-1;
+ fsp_set_fd(conn->cwd_fsp, -1);
+ conn->cwd_fsp->fnum = FNUM_FIELD_INVALID;
+ conn->cwd_fsp->conn = conn;
DLIST_ADD(sconn->connections, conn);
sconn->num_connections++;
+ /*
+ * Catches the case where someone forgets to call
+ * conn_free().
+ */
+ talloc_set_destructor(conn, conn_struct_destructor);
return conn;
}
if (ent->vuid == vuid) {
ent->vuid = UID_FIELD_INVALID;
-
- conn->user_ev_ctx = NULL;
-
- if (conn->user_vfs_evg == ent->user_vfs_evg) {
- conn->user_vfs_evg = NULL;
- }
- TALLOC_FREE(ent->user_vfs_evg);
-
/*
* We need to keep conn->session_info around
* if it's equal to ent->session_info as a SMBulogoff
} else {
TALLOC_FREE(ent->session_info);
}
-
ent->read_only = False;
ent->share_access = 0;
}
free_namearray(conn->aio_write_behind_list);
ZERO_STRUCTP(conn);
- talloc_destroy(conn);
}
/****************************************************************************
void conn_free(connection_struct *conn)
{
- if (conn->sconn == NULL) {
- conn_free_internal(conn);
- return;
- }
+ TALLOC_FREE(conn);
+}
- DLIST_REMOVE(conn->sconn->connections, conn);
- SMB_ASSERT(conn->sconn->num_connections > 0);
- conn->sconn->num_connections--;
+/*
+ * Correctly initialize a share with case options.
+ */
+void conn_setup_case_options(connection_struct *conn)
+{
+ int snum = conn->params->service;
+
+ if (lp_case_sensitive(snum) == Auto) {
+ /* We will be setting this per packet. Set to be case
+ * insensitive for now. */
+ conn->case_sensitive = false;
+ } else {
+ conn->case_sensitive = (bool)lp_case_sensitive(snum);
+ }
- conn_free_internal(conn);
+ conn->case_preserve = lp_preserve_case(snum);
+ conn->short_case_preserve = lp_short_preserve_case(snum);
}