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 2 of the License, or
+ 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,
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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* a "session" is claimed when we do a SessionSetupX operation
#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;
}
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;
- uint32 pid = (uint32)sys_getpid();
+ 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;
return True;
}
- if (!session_init())
+ if (!(ctx = session_db_ctx())) {
return False;
+ }
ZERO_STRUCT(sessionid);
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,
- SESSION_TEMPLATE, (long unsigned int)sys_getpid(),
+ 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
-
+ needed because utmp and PAM both expect DNS names
+
client_name() handles this case internally.
*/
sessionid.uid = vuser->uid;
sessionid.gid = vuser->gid;
fstrcpy(sessionid.remote_machine, get_remote_machine_name());
- fstrcpy(sessionid.ip_addr, client_addr());
+ fstrcpy(sessionid.ip_addr_str, client_addr());
sessionid.connect_start = time(NULL);
- 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);
+
+ TALLOC_FREE(rec);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1,("session_claim: unable to create session id "
+ "record: %s\n", nt_errstr(status)));
return False;
}
if (lp_utmp()) {
- sys_utmp_claim(sessionid.username, sessionid.hostname,
- client_ip,
+ sys_utmp_claim(sessionid.username, sessionid.hostname,
+ sessionid.ip_addr_str,
sessionid.id_str, sessionid.id_num);
}
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));
-
- client_ip = interpret_addr2(sessionid.ip_addr);
+ if (rec->value.dsize != sizeof(sessionid))
+ return;
- SAFE_FREE(dbuf.dptr);
+ memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
if (lp_utmp()) {
sys_utmp_yield(sessionid.username, sessionid.hostname,
- client_ip,
+ sessionid.ip_addr_str,
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);
}
/********************************************************************
********************************************************************/
-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_read(ctx, fn, private_data);
return True;
}
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",