summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2007-05-28 13:33:54 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:22:52 -0500
commitba0bce2c6f7298840e0d223a5f170b777b8c9d64 (patch)
treeaa881116a46842e7b06ee254a51a60d91677d1d4
parentfff51a9af20b7221844ffb11d7491372bbbcda0e (diff)
downloadsamba-ba0bce2c6f7298840e0d223a5f170b777b8c9d64.tar.gz
samba-ba0bce2c6f7298840e0d223a5f170b777b8c9d64.tar.bz2
samba-ba0bce2c6f7298840e0d223a5f170b777b8c9d64.zip
r23173: Convert sessionid.tdb to ctdb. The 3.0.26 patch is a bit larger because
it brings across the tdb-based list_sessions (This used to be commit 0153386c1a3625b2f699863991893f399c40af48)
-rw-r--r--source3/smbd/session.c171
1 files changed, 118 insertions, 53 deletions
diff --git a/source3/smbd/session.c b/source3/smbd/session.c
index f55576a7be..837c37a49f 100644
--- a/source3/smbd/session.c
+++ b/source3/smbd/session.c
@@ -29,19 +29,25 @@
#include "includes.h"
-static TDB_CONTEXT *tdb;
-
/********************************************************************
********************************************************************/
-BOOL session_init(void)
+static struct db_context *session_db_ctx(void)
{
- if (tdb)
- return True;
+ static struct db_context *ctx;
+
+ if (ctx)
+ return ctx;
+
+ ctx = db_open(NULL, lock_path("sessionid.tdb"), 0,
+ TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
+ O_RDWR | O_CREAT, 0644);
+ return ctx;
+}
- tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
- O_RDWR | O_CREAT, 0644);
- if (!tdb) {
+BOOL session_init(void)
+{
+ if (session_db_ctx() == NULL) {
DEBUG(1,("session_init: failed to open sessionid tdb\n"));
return False;
}
@@ -55,17 +61,17 @@ BOOL session_init(void)
BOOL session_claim(user_struct *vuser)
{
+ TDB_DATA key, data;
int i = 0;
- TDB_DATA data;
struct sockaddr sa;
struct in_addr *client_ip;
struct sessionid sessionid;
struct server_id pid = procid_self();
fstring keystr;
char * hostname;
- int tdb_store_flag; /* If using utmp, we do an inital 'lock hold' store,
- but we don't need this if we are just using the
- (unique) pid/vuid combination */
+ struct db_context *ctx;
+ struct db_record *rec;
+ NTSTATUS status;
vuser->session_keystr = NULL;
@@ -75,8 +81,9 @@ BOOL session_claim(user_struct *vuser)
return True;
}
- if (!session_init())
+ if (!(ctx = session_db_ctx())) {
return False;
+ }
ZERO_STRUCT(sessionid);
@@ -84,30 +91,70 @@ BOOL session_claim(user_struct *vuser)
data.dsize = 0;
if (lp_utmp()) {
+
for (i=1;i<MAX_SESSION_ID;i++) {
- slprintf(keystr, sizeof(keystr)-1, "ID/%d", i);
-
- if (tdb_store_bystring(tdb, keystr, data, TDB_INSERT) == 0) break;
+
+ /*
+ * This is very inefficient and needs fixing -- vl
+ */
+
+ 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);
+
+ if (rec == NULL) {
+ DEBUG(1, ("Could not lock \"%s\"\n", keystr));
+ return False;
+ }
+
+ if (rec->value.dsize != sizeof(sessionid)) {
+ DEBUG(1, ("Re-using invalid record\n"));
+ break;
+ }
+
+ sess_pid = ((struct sessionid *)rec->value.dptr)->pid;
+
+ if (!process_exists(sess_pid)) {
+ DEBUG(5, ("%s has died -- re-using session\n",
+ procid_str_static(&sess_pid)));
+ break;
+ }
+
+ TALLOC_FREE(rec);
}
if (i == MAX_SESSION_ID) {
- DEBUG(1,("session_claim: out of session IDs (max is %d)\n",
- MAX_SESSION_ID));
+ SMB_ASSERT(rec == NULL);
+ DEBUG(1,("session_claim: out of session IDs "
+ "(max is %d)\n", MAX_SESSION_ID));
return False;
}
- slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, SESSION_UTMP_TEMPLATE, i);
- tdb_store_flag = TDB_MODIFY;
+
+ snprintf(sessionid.id_str, sizeof(sessionid.id_str),
+ SESSION_UTMP_TEMPLATE, i);
} else
{
- slprintf(keystr, sizeof(keystr)-1, "ID/%lu/%u",
- (long unsigned int)sys_getpid(),
- vuser->vuid);
- slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1,
+ 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);
+
+ if (rec == NULL) {
+ DEBUG(1, ("Could not lock \"%s\"\n", keystr));
+ return False;
+ }
+
+ snprintf(sessionid.id_str, sizeof(sessionid.id_str),
SESSION_TEMPLATE, (long unsigned int)sys_getpid(),
vuser->vuid);
- tdb_store_flag = TDB_REPLACE;
}
+ SMB_ASSERT(rec != NULL);
+
/* If 'hostname lookup' == yes, then do the DNS lookup. This is
needed because utmp and PAM both expect DNS names
@@ -131,19 +178,24 @@ BOOL session_claim(user_struct *vuser)
client_ip = client_inaddr(&sa);
- if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, sessionid.hostname)) {
+ if (!smb_pam_claim_session(sessionid.username, sessionid.id_str,
+ sessionid.hostname)) {
DEBUG(1,("pam_session rejected the session for %s [%s]\n",
sessionid.username, sessionid.id_str));
- if (tdb_store_flag == TDB_MODIFY) {
- tdb_delete_bystring(tdb, keystr);
- }
+
+ TALLOC_FREE(rec);
return False;
}
data.dptr = (uint8 *)&sessionid;
data.dsize = sizeof(sessionid);
- if (tdb_store_bystring(tdb, keystr, data, tdb_store_flag) != 0) {
- DEBUG(1,("session_claim: unable to create session id record\n"));
+
+ status = rec->store(rec, data, TDB_REPLACE);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1,("session_claim: unable to create session id "
+ "record: %s\n", nt_errstr(status)));
+ TALLOC_FREE(rec);
return False;
}
@@ -153,9 +205,12 @@ BOOL session_claim(user_struct *vuser)
sessionid.id_str, sessionid.id_num);
}
+ TALLOC_FREE(rec);
+
vuser->session_keystr = talloc_strdup(vuser, keystr);
if (!vuser->session_keystr) {
- DEBUG(0, ("session_claim: talloc_strdup() failed for session_keystr\n"));
+ DEBUG(0, ("session_claim: talloc_strdup() failed for "
+ "session_keystr\n"));
return False;
}
return True;
@@ -167,26 +222,30 @@ BOOL session_claim(user_struct *vuser)
void session_yield(user_struct *vuser)
{
- TDB_DATA dbuf;
+ TDB_DATA key;
struct sessionid sessionid;
struct in_addr *client_ip;
+ struct db_context *ctx;
+ struct db_record *rec;
- if (!tdb) return;
+ if (!(ctx = session_db_ctx())) return;
if (!vuser->session_keystr) {
return;
}
- dbuf = tdb_fetch_bystring(tdb, vuser->session_keystr);
+ key = string_term_tdb_data(vuser->session_keystr);
- if (dbuf.dsize != sizeof(sessionid))
+ if (!(rec = ctx->fetch_locked(ctx, NULL, key))) {
return;
+ }
- memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
+ if (rec->value.dsize != sizeof(sessionid))
+ return;
- client_ip = interpret_addr2(sessionid.ip_addr);
+ memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
- SAFE_FREE(dbuf.dptr);
+ client_ip = interpret_addr2(sessionid.ip_addr);
if (lp_utmp()) {
sys_utmp_yield(sessionid.username, sessionid.hostname,
@@ -194,24 +253,29 @@ void session_yield(user_struct *vuser)
sessionid.id_str, sessionid.id_num);
}
- smb_pam_close_session(sessionid.username, sessionid.id_str, sessionid.hostname);
+ smb_pam_close_session(sessionid.username, sessionid.id_str,
+ sessionid.hostname);
+
+ rec->delete_rec(rec);
- tdb_delete_bystring(tdb, vuser->session_keystr);
+ TALLOC_FREE(rec);
}
/********************************************************************
********************************************************************/
-static BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA,
- void *),
- void *state)
+static BOOL session_traverse(int (*fn)(struct db_record *db,
+ void *private_data),
+ void *private_data)
{
- if (!session_init()) {
+ struct db_context *ctx;
+
+ if (!(ctx = session_db_ctx())) {
DEBUG(3, ("No tdb opened\n"));
return False;
}
- tdb_traverse(tdb, fn, state);
+ ctx->traverse(ctx, fn, private_data);
return True;
}
@@ -224,23 +288,24 @@ struct session_list {
struct sessionid *sessions;
};
-static int gather_sessioninfo(TDB_CONTEXT *stdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
+static int gather_sessioninfo(struct db_record *rec, void *state)
{
- uint32 i;
struct session_list *sesslist = (struct session_list *) state;
- const struct sessionid *current = (const struct sessionid *) dbuf.dptr;
+ const struct sessionid *current =
+ (const struct sessionid *) rec->value.dptr;
- i = sesslist->count;
-
sesslist->sessions = TALLOC_REALLOC_ARRAY(
- sesslist->mem_ctx, sesslist->sessions, struct sessionid, i+1);
+ sesslist->mem_ctx, sesslist->sessions, struct sessionid,
+ sesslist->count+1);
if (!sesslist->sessions) {
sesslist->count = 0;
return -1;
}
- memcpy(&sesslist->sessions[i], current, sizeof(struct sessionid));
+ memcpy(&sesslist->sessions[sesslist->count], current,
+ sizeof(struct sessionid));
+
sesslist->count++;
DEBUG(7,("gather_sessioninfo session from %s@%s\n",