summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/server.c34
-rw-r--r--source3/smbd/session.c29
-rw-r--r--source3/tdb/tdb.c32
-rw-r--r--source3/tdb/tdbutil.c2
4 files changed, 62 insertions, 35 deletions
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index be59e92cd7..1de33739b2 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -405,10 +405,10 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
done correctly in the process. */
reset_globals_after_fork();
- /* tdb needs special fork handling */
+ /* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
if (tdb_reopen_all() == -1) {
DEBUG(0,("tdb_reopen_all failed.\n"));
- return False;
+ smb_panic("tdb_reopen_all failed.");
}
return True;
@@ -809,9 +809,27 @@ void build_options(BOOL screen);
if (is_daemon)
pidfile_create("smbd");
+ /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
if (!message_init())
exit(1);
+ if (!session_init())
+ exit(1);
+
+ if (conn_tdb_ctx() == NULL)
+ exit(1);
+
+ if (!locking_init(0))
+ exit(1);
+
+ if (!share_info_db_init())
+ exit(1);
+
+ namecache_enable();
+
+ if (!init_registry())
+ exit(1);
+
if (!print_backend_init())
exit(1);
@@ -832,17 +850,6 @@ void build_options(BOOL screen);
* everything after this point is run after the fork()
*/
- namecache_enable();
-
- if (!locking_init(0))
- exit(1);
-
- if (!share_info_db_init())
- exit(1);
-
- if (!init_registry())
- exit(1);
-
/* Initialise the password backed before the global_sam_sid
to ensure that we fetch from ldap before we make a domain sid up */
@@ -891,4 +898,3 @@ void build_options(BOOL screen);
exit_server("normal exit");
return(0);
}
-
diff --git a/source3/smbd/session.c b/source3/smbd/session.c
index a811a6e305..61118f13dd 100644
--- a/source3/smbd/session.c
+++ b/source3/smbd/session.c
@@ -28,6 +28,22 @@
#include "includes.h"
static TDB_CONTEXT *tdb;
+
+BOOL session_init(void)
+{
+ if (tdb)
+ return True;
+
+ tdb = tdb_open_ex(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
+ O_RDWR | O_CREAT, 0644, smbd_tdb_log);
+ if (!tdb) {
+ DEBUG(1,("session_init: failed to open sessionid tdb\n"));
+ return False;
+ }
+
+ return True;
+}
+
/* called when a session is created */
BOOL session_claim(user_struct *vuser)
{
@@ -52,14 +68,8 @@ BOOL session_claim(user_struct *vuser)
return True;
}
- if (!tdb) {
- tdb = tdb_open_ex(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
- O_RDWR | O_CREAT, 0644, smbd_tdb_log);
- if (!tdb) {
- DEBUG(1,("session_claim: failed to open sessionid tdb\n"));
- return False;
- }
- }
+ if (!session_init())
+ return False;
ZERO_STRUCT(sessionid);
@@ -190,7 +200,7 @@ void session_yield(user_struct *vuser)
static BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *), void *state)
{
- if (!tdb) {
+ if (!session_init()) {
DEBUG(3, ("No tdb opened\n"));
return False;
}
@@ -238,4 +248,3 @@ int list_sessions(struct sessionid **session_list)
*session_list = sesslist.sessions;
return sesslist.count;
}
-
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index 7ad39175ac..7b10cfb377 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -1705,7 +1705,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
{
TDB_CONTEXT *tdb;
struct stat st;
- int rev = 0, locked;
+ int rev = 0, locked = 0;
unsigned char *vp;
u32 vertest;
@@ -1763,8 +1763,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
}
/* we need to zero database if we are the only one with it open */
- if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))
- && (tdb_flags & TDB_CLEAR_IF_FIRST)) {
+ if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
+ (locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))) {
open_flags |= O_CREAT;
if (ftruncate(tdb->fd, 0) == -1) {
TDB_LOG((tdb, 0, "tdb_open_ex: "
@@ -1837,10 +1837,19 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
name, strerror(errno)));
goto fail;
}
+
}
- /* leave this lock in place to indicate it's in use */
- if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
- goto fail;
+
+ /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
+ we didn't get the initial exclusive lock as we need to let all other
+ users know we're using it. */
+
+ if (tdb_flags & TDB_CLEAR_IF_FIRST) {
+ /* leave this lock in place to indicate it's in use */
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
+ goto fail;
+ }
+
internal:
/* Internal (memory-only) databases skip all the code above to
@@ -2018,12 +2027,14 @@ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , cons
}
-/* reopen a tdb - this is used after a fork to ensure that we have an independent
+/* reopen a tdb - this can be used after a fork to ensure that we have an independent
seek pointer from our parent and to re-establish locks */
int tdb_reopen(TDB_CONTEXT *tdb)
{
struct stat st;
+ if (tdb->flags & TDB_INTERNAL)
+ return 0; /* Nothing to do. */
if (tdb_munmap(tdb) != 0) {
TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
goto fail;
@@ -2044,7 +2055,7 @@ int tdb_reopen(TDB_CONTEXT *tdb)
goto fail;
}
tdb_mmap(tdb);
- if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) {
+ if ((tdb->flags & TDB_CLEAR_IF_FIRST) && (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) {
TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n"));
goto fail;
}
@@ -2062,7 +2073,10 @@ int tdb_reopen_all(void)
TDB_CONTEXT *tdb;
for (tdb=tdbs; tdb; tdb = tdb->next) {
- if (tdb_reopen(tdb) != 0) return -1;
+ /* Ensure no clear-if-first. */
+ tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+ if (tdb_reopen(tdb) != 0)
+ return -1;
}
return 0;
diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c
index bae9a8b9d4..304bf9c816 100644
--- a/source3/tdb/tdbutil.c
+++ b/source3/tdb/tdbutil.c
@@ -826,5 +826,3 @@ void tdb_search_list_free(TDB_LIST_NODE* node)
node = next_node;
};
}
-
-