diff options
-rw-r--r-- | source3/smbd/server.c | 34 | ||||
-rw-r--r-- | source3/smbd/session.c | 29 | ||||
-rw-r--r-- | source3/tdb/tdb.c | 32 | ||||
-rw-r--r-- | source3/tdb/tdbutil.c | 2 |
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; }; } - - |