diff options
author | Volker Lendecke <vlendec@samba.org> | 2007-05-28 13:33:54 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:22:52 -0500 |
commit | 0153386c1a3625b2f699863991893f399c40af48 (patch) | |
tree | 6642d376996d2516d1b07456f1e7c5f1c4a79d7c | |
parent | ccb5eb245e962b0264b337c2d0275c22e2a36830 (diff) | |
download | samba-0153386c1a3625b2f699863991893f399c40af48.tar.gz samba-0153386c1a3625b2f699863991893f399c40af48.tar.xz samba-0153386c1a3625b2f699863991893f399c40af48.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
-rw-r--r-- | source/smbd/session.c | 171 |
1 files changed, 118 insertions, 53 deletions
diff --git a/source/smbd/session.c b/source/smbd/session.c index f55576a7bec..837c37a49f7 100644 --- a/source/smbd/session.c +++ b/source/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", |