s3: Abstract access to sessionid.tdb, similar to conn_tdb.c
authorVolker Lendecke <vl@samba.org>
Mon, 1 Mar 2010 15:18:23 +0000 (16:18 +0100)
committerVolker Lendecke <vl@samba.org>
Mon, 1 Mar 2010 16:53:22 +0000 (17:53 +0100)
source3/Makefile.in
source3/include/proto.h
source3/lib/sessionid_tdb.c [new file with mode: 0644]
source3/smbd/globals.c
source3/smbd/globals.h
source3/smbd/server.c
source3/smbd/session.c
source3/utils/net_status.c
source3/utils/status.c

index 6e40f8362f68703c749aa3d4fc07ddcfb7185f2b..323da3c91c77b5a02a53958bb54f6f592a10116b 100644 (file)
@@ -406,6 +406,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
          libsmb/clisigning.o libsmb/smb_signing.o \
          lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \
          lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \
+         lib/sessionid_tdb.o \
          lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \
          lib/ldap_escape.o @CHARSET_STATIC@ \
          lib/secdesc.o lib/util_seaccess.o ../libcli/security/secace.o \
index 39aca5f76a495afdeb1b6d0443ddf14baf16db70..93156f877914012a13185ce756315973d20a959b 100644 (file)
@@ -7007,6 +7007,19 @@ bool session_claim(user_struct *vuser);
 void session_yield(user_struct *vuser);
 int list_sessions(TALLOC_CTX *mem_ctx, struct sessionid **session_list);
 
+/* The following definitions come from lib/sessionid_tdb.c  */
+
+bool sessionid_init(void);
+struct db_record *sessionid_fetch_record(TALLOC_CTX *mem_ctx, const char *key);
+int sessionid_traverse(int (*fn)(struct db_record *rec, const char *key,
+                                struct sessionid *session,
+                                void *private_data),
+                      void *private_data);
+int sessionid_traverse_read(int (*fn)(const char *key,
+                                     struct sessionid *session,
+                                     void *private_data),
+                           void *private_data);
+
 /* The following definitions come from smbd/sesssetup.c  */
 
 NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in,
diff --git a/source3/lib/sessionid_tdb.c b/source3/lib/sessionid_tdb.c
new file mode 100644 (file)
index 0000000..6efbafd
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+   Unix SMB/CIFS implementation.
+   Low-level sessionid.tdb access functions
+   Copyright (C) Volker Lendecke 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"
+
+static struct db_context *session_db_ctx(void)
+{
+       static struct db_context *session_db_ctx_ptr;
+
+       if (session_db_ctx_ptr != NULL) {
+               return session_db_ctx_ptr;
+       }
+
+       session_db_ctx_ptr = db_open(NULL, lock_path("sessionid.tdb"), 0,
+                                    TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
+                                    O_RDWR | O_CREAT, 0644);
+       return session_db_ctx_ptr;
+}
+
+bool sessionid_init(void)
+{
+       if (session_db_ctx() == NULL) {
+               DEBUG(1,("session_init: failed to open sessionid tdb\n"));
+               return False;
+       }
+
+       return True;
+}
+
+struct db_record *sessionid_fetch_record(TALLOC_CTX *mem_ctx, const char *key)
+{
+       struct db_context *db;
+
+       db = session_db_ctx();
+       if (db == NULL) {
+               return NULL;
+       }
+       return db->fetch_locked(db, mem_ctx, string_term_tdb_data(key));
+}
+
+struct sessionid_traverse_state {
+       int (*fn)(struct db_record *rec, const char *key,
+                 struct sessionid *session, void *private_data);
+       void *private_data;
+};
+
+static int sessionid_traverse_fn(struct db_record *rec, void *private_data)
+{
+       struct sessionid_traverse_state *state =
+               (struct sessionid_traverse_state *)private_data;
+       struct sessionid session;
+
+       if ((rec->key.dptr[rec->key.dsize-1] != '\0')
+           || (rec->value.dsize != sizeof(struct sessionid))) {
+               DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
+               return 0;
+       }
+
+       memcpy(&session, rec->value.dptr, sizeof(session));
+
+       return state->fn(rec, (char *)rec->key.dptr, &session,
+                        state->private_data);
+}
+
+int sessionid_traverse(int (*fn)(struct db_record *rec, const char *key,
+                                struct sessionid *session,
+                                void *private_data),
+                      void *private_data)
+{
+       struct db_context *db;
+       struct sessionid_traverse_state state;
+
+       db = session_db_ctx();
+       if (db == NULL) {
+               return -1;
+       }
+       state.fn = fn;
+       state.private_data = private_data;
+       return db->traverse(db, sessionid_traverse_fn, &state);
+}
+
+struct sessionid_traverse_read_state {
+       int (*fn)(const char *key, struct sessionid *session,
+                 void *private_data);
+       void *private_data;
+};
+
+static int sessionid_traverse_read_fn(struct db_record *rec,
+                                     void *private_data)
+{
+       struct sessionid_traverse_read_state *state =
+               (struct sessionid_traverse_read_state *)private_data;
+       struct sessionid session;
+
+       if ((rec->key.dptr[rec->key.dsize-1] != '\0')
+           || (rec->value.dsize != sizeof(struct sessionid))) {
+               DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
+               return 0;
+       }
+
+       memcpy(&session, rec->value.dptr, sizeof(session));
+
+       return state->fn((char *)rec->key.dptr, &session,
+                        state->private_data);
+}
+
+int sessionid_traverse_read(int (*fn)(const char *key,
+                                     struct sessionid *session,
+                                     void *private_data),
+                           void *private_data)
+{
+       struct db_context *db;
+       struct sessionid_traverse_read_state state;
+
+       db = session_db_ctx();
+       if (db == NULL) {
+               return -1;
+       }
+       state.fn = fn;
+       state.private_data = private_data;
+       return db->traverse(db, sessionid_traverse_read_fn, &state);
+}
index e6db5ec41492c98bbd1b14a5f442465862b072b4..a632aa2e9b5872b59d3577b3837cad8be7d60444 100644 (file)
@@ -110,8 +110,6 @@ bool become_gid_done = false;
 connection_struct *last_conn = NULL;
 uint16_t last_flags = 0;
 
-struct db_context *session_db_ctx_ptr = NULL;
-
 uint32_t global_client_caps = 0;
 
 uint16_t fnf_handle = 257;
index 3cc967f4fd3164bb4ae8599e4b01307a14a66f8e..428733d2dcf23b813e1405b21bdd748c68749d05 100644 (file)
@@ -114,8 +114,6 @@ extern bool become_gid_done;
 extern connection_struct *last_conn;
 extern uint16_t last_flags;
 
-extern struct db_context *session_db_ctx_ptr;
-
 extern uint32_t global_client_caps;
 
 extern uint16_t fnf_handle;
index 9d7de1637a03b55fccf0f3e5625a44ebe24b6c6e..d88679c95fd619b40789a8e5587d39de29539252 100644 (file)
@@ -1233,8 +1233,9 @@ extern void build_options(bool screen);
                exit(1);
        }
 
-       if (!session_init())
+       if (!sessionid_init()) {
                exit(1);
+       }
 
        if (!connections_init(True))
                exit(1);
index ebfffb7d57ead87d83843ff787d8088c406f1dc3..fdbb4834ab254cc701fa3e76547d703d2cca0784 100644 (file)
 #include "includes.h"
 #include "smbd/globals.h"
 
-/********************************************************************
-********************************************************************/
-
-static struct db_context *session_db_ctx(void)
-{
-       if (session_db_ctx_ptr)
-               return session_db_ctx_ptr;
-
-       session_db_ctx_ptr = db_open(NULL, lock_path("sessionid.tdb"), 0,
-                                    TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
-                                    O_RDWR | O_CREAT, 0644);
-       return session_db_ctx_ptr;
-}
-
-bool session_init(void)
-{
-       if (session_db_ctx() == NULL) {
-               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)
 {
-       TDB_DATA key, data;
+       TDB_DATA data;
        int i = 0;
        struct sessionid sessionid;
        struct server_id pid = procid_self();
        fstring keystr;
        const char * hostname;
-       struct db_context *ctx;
        struct db_record *rec;
        NTSTATUS status;
        char addr[INET6_ADDRSTRLEN];
@@ -78,7 +53,7 @@ bool session_claim(user_struct *vuser)
                return True;
        }
 
-       if (!(ctx = session_db_ctx())) {
+       if (!sessionid_init()) {
                return False;
        }
 
@@ -98,10 +73,8 @@ bool session_claim(user_struct *vuser)
                        struct server_id sess_pid;
 
                        snprintf(keystr, sizeof(keystr), "ID/%d", i);
-                       key = string_term_tdb_data(keystr);
-
-                       rec = ctx->fetch_locked(ctx, NULL, key);
 
+                       rec = sessionid_fetch_record(NULL, keystr);
                        if (rec == NULL) {
                                DEBUG(1, ("Could not lock \"%s\"\n", keystr));
                                return False;
@@ -139,10 +112,8 @@ bool session_claim(user_struct *vuser)
        {
                snprintf(keystr, sizeof(keystr), "ID/%s/%u",
                         procid_str_static(&pid), vuser->vuid);
-               key = string_term_tdb_data(keystr);
-
-               rec = ctx->fetch_locked(ctx, NULL, key);
 
+               rec = sessionid_fetch_record(NULL, keystr);
                if (rec == NULL) {
                        DEBUG(1, ("Could not lock \"%s\"\n", keystr));
                        return False;
@@ -219,20 +190,15 @@ bool session_claim(user_struct *vuser)
 
 void session_yield(user_struct *vuser)
 {
-       TDB_DATA key;
        struct sessionid sessionid;
-       struct db_context *ctx;
        struct db_record *rec;
 
-       if (!(ctx = session_db_ctx())) return;
-
        if (!vuser->session_keystr) {
                return;
        }
 
-       key = string_term_tdb_data(vuser->session_keystr);
-
-       if (!(rec = ctx->fetch_locked(ctx, NULL, key))) {
+       rec = sessionid_fetch_record(NULL, vuser->session_keystr);
+       if (rec == NULL) {
                return;
        }
 
@@ -258,35 +224,16 @@ void session_yield(user_struct *vuser)
 /********************************************************************
 ********************************************************************/
 
-static bool session_traverse(int (*fn)(struct db_record *db,
-                                      void *private_data),
-                            void *private_data)
-{
-       struct db_context *ctx;
-
-       if (!(ctx = session_db_ctx())) {
-               DEBUG(3, ("No tdb opened\n"));
-               return False;
-       }
-
-       ctx->traverse_read(ctx, fn, private_data);
-       return True;
-}
-
-/********************************************************************
-********************************************************************/
-
 struct session_list {
        TALLOC_CTX *mem_ctx;
        int count;
        struct sessionid *sessions;
 };
 
-static int gather_sessioninfo(struct db_record *rec, void *state)
+static int gather_sessioninfo(const char *key, struct sessionid *session,
+                             void *private_data)
 {
-       struct session_list *sesslist = (struct session_list *) state;
-       const struct sessionid *current =
-               (const struct sessionid *) rec->value.dptr;
+       struct session_list *sesslist = (struct session_list *)private_data;
 
        sesslist->sessions = TALLOC_REALLOC_ARRAY(
                sesslist->mem_ctx, sesslist->sessions, struct sessionid,
@@ -297,13 +244,13 @@ static int gather_sessioninfo(struct db_record *rec, void *state)
                return -1;
        }
 
-       memcpy(&sesslist->sessions[sesslist->count], current,
+       memcpy(&sesslist->sessions[sesslist->count], session,
               sizeof(struct sessionid));
 
        sesslist->count++;
 
-       DEBUG(7,("gather_sessioninfo session from %s@%s\n", 
-                current->username, current->remote_machine));
+       DEBUG(7, ("gather_sessioninfo session from %s@%s\n",
+                 session->username, session->remote_machine));
 
        return 0;
 }
@@ -314,12 +261,14 @@ static int gather_sessioninfo(struct db_record *rec, void *state)
 int list_sessions(TALLOC_CTX *mem_ctx, struct sessionid **session_list)
 {
        struct session_list sesslist;
+       int ret;
 
        sesslist.mem_ctx = mem_ctx;
        sesslist.count = 0;
        sesslist.sessions = NULL;
-       
-       if (!session_traverse(gather_sessioninfo, (void *) &sesslist)) {
+
+       ret = sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist);
+       if (ret == -1) {
                DEBUG(3, ("Session traverse failed\n"));
                SAFE_FREE(sesslist.sessions);
                *session_list = NULL;
index 47860cb5849dc591d9b60d6ac1b2031de148d53a..54ad7864364bdf45b9a583276771043e676d62cc 100644 (file)
@@ -28,30 +28,27 @@ int net_status_usage(struct net_context *c, int argc, const char **argv)
        return -1;
 }
 
-static int show_session(struct db_record *rec, void *private_data)
+static int show_session(const char *key, struct sessionid *session,
+                       void *private_data)
 {
        bool *parseable = (bool *)private_data;
-       struct sessionid sessionid;
 
-       if (rec->value.dsize != sizeof(sessionid))
-               return 0;
-
-       memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
-
-       if (!process_exists(sessionid.pid)) {
+       if (!process_exists(session->pid)) {
                return 0;
        }
 
        if (*parseable) {
                d_printf("%s\\%s\\%s\\%s\\%s\n",
-                        procid_str_static(&sessionid.pid), uidtoname(sessionid.uid),
-                        gidtoname(sessionid.gid),
-                        sessionid.remote_machine, sessionid.hostname);
+                        procid_str_static(&session->pid),
+                        uidtoname(session->uid),
+                        gidtoname(session->gid),
+                        session->remote_machine, session->hostname);
        } else {
                d_printf("%7s   %-12s  %-12s  %-12s (%s)\n",
-                        procid_str_static(&sessionid.pid), uidtoname(sessionid.uid),
-                        gidtoname(sessionid.gid),
-                        sessionid.remote_machine, sessionid.hostname);
+                        procid_str_static(&session->pid),
+                        uidtoname(session->uid),
+                        gidtoname(session->gid),
+                        session->remote_machine, session->hostname);
        }
 
        return 0;
@@ -59,7 +56,6 @@ static int show_session(struct db_record *rec, void *private_data)
 
 static int net_status_sessions(struct net_context *c, int argc, const char **argv)
 {
-       struct db_context *db;
        bool parseable;
 
        if (c->display_usage) {
@@ -88,17 +84,7 @@ static int net_status_sessions(struct net_context *c, int argc, const char **arg
                           "------------------------\n"));
        }
 
-       db = db_open(NULL, lock_path("sessionid.tdb"), 0,
-                    TDB_CLEAR_IF_FIRST, O_RDONLY, 0644);
-       if (db == NULL) {
-               d_fprintf(stderr, _("%s not initialised\n"),
-                         lock_path("sessionid.tdb"));
-               return -1;
-       }
-
-       db->traverse_read(db, show_session, &parseable);
-       TALLOC_FREE(db);
-
+       sessionid_traverse_read(show_session, &parseable);
        return 0;
 }
 
@@ -127,17 +113,12 @@ struct sessionids {
        struct sessionid *entries;
 };
 
-static int collect_pid(struct db_record *rec, void *private_data)
+static int collect_pids(const char *key, struct sessionid *session,
+                       void *private_data)
 {
        struct sessionids *ids = (struct sessionids *)private_data;
-       struct sessionid sessionid;
 
-       if (rec->value.dsize != sizeof(sessionid))
-               return 0;
-
-       memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
-
-       if (!process_exists(sessionid.pid))
+       if (!process_exists(session->pid))
                return 0;
 
        ids->num_entries += 1;
@@ -146,7 +127,7 @@ static int collect_pid(struct db_record *rec, void *private_data)
                ids->num_entries = 0;
                return 0;
        }
-       ids->entries[ids->num_entries-1] = sessionid;
+       ids->entries[ids->num_entries-1] = *session;
 
        return 0;
 }
@@ -188,21 +169,11 @@ static int show_share_parseable(const struct connections_key *key,
 static int net_status_shares_parseable(struct net_context *c, int argc, const char **argv)
 {
        struct sessionids ids;
-       struct db_context *db;
 
        ids.num_entries = 0;
        ids.entries = NULL;
 
-       db = db_open(NULL, lock_path("sessionid.tdb"), 0,
-                    TDB_CLEAR_IF_FIRST, O_RDONLY, 0644);
-       if (db == NULL) {
-               d_fprintf(stderr, _("%s not initialised\n"),
-                         lock_path("sessionid.tdb"));
-               return -1;
-       }
-
-       db->traverse_read(db, collect_pid, &ids);
-       TALLOC_FREE(db);
+       sessionid_traverse_read(collect_pids, &ids);
 
        connections_forall_read(show_share_parseable, &ids);
 
index 60cad2c28f24b8cda8ab67d7167f64fd6a73a26b..d2b10c1810a861a8e8755faec2fc022b0f6f8b5d 100644 (file)
@@ -251,30 +251,26 @@ static int traverse_fn1(const struct connections_key *key,
        return 0;
 }
 
-static int traverse_sessionid(struct db_record *db, void *state)
+static int traverse_sessionid(const char *key, struct sessionid *session,
+                             void *private_data)
 {
-       struct sessionid sessionid;
        fstring uid_str, gid_str;
 
-       if (db->value.dsize != sizeof(sessionid))
-               return 0;
-
-       memcpy(&sessionid, db->value.dptr, sizeof(sessionid));
-
-       if (!process_exists(sessionid.pid) || !Ucrit_checkUid(sessionid.uid)) {
+       if (!process_exists(session->pid)
+           || !Ucrit_checkUid(session->uid)) {
                return 0;
        }
 
-       Ucrit_addPid( sessionid.pid );
+       Ucrit_addPid(session->pid);
 
-       fstr_sprintf(uid_str, "%u", (unsigned int)sessionid.uid);
-       fstr_sprintf(gid_str, "%u", (unsigned int)sessionid.gid);
+       fstr_sprintf(uid_str, "%u", (unsigned int)session->uid);
+       fstr_sprintf(gid_str, "%u", (unsigned int)session->gid);
 
        d_printf("%-7s   %-12s  %-12s  %-12s (%s)\n",
-                procid_str_static(&sessionid.pid),
-                numeric_only ? uid_str : uidtoname(sessionid.uid),
-                numeric_only ? gid_str : gidtoname(sessionid.gid), 
-                sessionid.remote_machine, sessionid.hostname);
+                procid_str_static(&session->pid),
+                numeric_only ? uid_str : uidtoname(session->uid),
+                numeric_only ? gid_str : gidtoname(session->gid),
+                session->remote_machine, session->hostname);
 
        return 0;
 }
@@ -411,24 +407,16 @@ static int traverse_sessionid(struct db_record *db, void *state)
        }
 
        if ( show_processes ) {
-               struct db_context *db;
-               db = db_open(NULL, lock_path("sessionid.tdb"), 0,
-                            TDB_CLEAR_IF_FIRST, O_RDONLY, 0644);
-               if (!db) {
-                       d_printf("sessionid.tdb not initialised\n");
-               } else {
-                       d_printf("\nSamba version %s\n",samba_version_string());
-                       d_printf("PID     Username      Group         Machine                        \n");
-                       d_printf("-------------------------------------------------------------------\n");
-                       if (lp_security() == SEC_SHARE) {
-                               d_printf(" <processes do not show up in "
-                                   "anonymous mode>\n");
-                       }
-
-                       db->traverse_read(db, traverse_sessionid, NULL);
-                       TALLOC_FREE(db);
+               d_printf("\nSamba version %s\n",samba_version_string());
+               d_printf("PID     Username      Group         Machine                        \n");
+               d_printf("-------------------------------------------------------------------\n");
+               if (lp_security() == SEC_SHARE) {
+                       d_printf(" <processes do not show up in "
+                                "anonymous mode>\n");
                }
 
+               sessionid_traverse_read(traverse_sessionid, NULL);
+
                if (processes_only) {
                        goto done;
                }