00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "includes.h"
00031
00032 static TDB_CONTEXT *tdb;
00033
00034
00035
00036
00037 BOOL session_init(void)
00038 {
00039 if (tdb)
00040 return True;
00041
00042 tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
00043 O_RDWR | O_CREAT, 0644);
00044 if (!tdb) {
00045 DEBUG(1,("session_init: failed to open sessionid tdb\n"));
00046 return False;
00047 }
00048
00049 return True;
00050 }
00051
00052
00053
00054
00055
00056 BOOL session_claim(user_struct *vuser)
00057 {
00058 int i = 0;
00059 TDB_DATA data;
00060 struct sockaddr sa;
00061 struct in_addr *client_ip;
00062 struct sessionid sessionid;
00063 uint32 pid = (uint32)sys_getpid();
00064 TDB_DATA key;
00065 fstring keystr;
00066 char * hostname;
00067 int tdb_store_flag;
00068
00069
00070
00071 vuser->session_keystr = NULL;
00072
00073
00074
00075 if (vuser->guest) {
00076 return True;
00077 }
00078
00079 if (!session_init())
00080 return False;
00081
00082 ZERO_STRUCT(sessionid);
00083
00084 data.dptr = NULL;
00085 data.dsize = 0;
00086
00087 if (lp_utmp()) {
00088 for (i=1;i<MAX_SESSION_ID;i++) {
00089 slprintf(keystr, sizeof(keystr)-1, "ID/%d", i);
00090 key.dptr = keystr;
00091 key.dsize = strlen(keystr)+1;
00092
00093 if (tdb_store(tdb, key, data, TDB_INSERT) == 0) break;
00094 }
00095
00096 if (i == MAX_SESSION_ID) {
00097 DEBUG(1,("session_claim: out of session IDs (max is %d)\n",
00098 MAX_SESSION_ID));
00099 return False;
00100 }
00101 slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, SESSION_UTMP_TEMPLATE, i);
00102 tdb_store_flag = TDB_MODIFY;
00103 } else
00104 {
00105 slprintf(keystr, sizeof(keystr)-1, "ID/%lu/%u",
00106 (long unsigned int)sys_getpid(),
00107 vuser->vuid);
00108 slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1,
00109 SESSION_TEMPLATE, (long unsigned int)sys_getpid(),
00110 vuser->vuid);
00111
00112 key.dptr = keystr;
00113 key.dsize = strlen(keystr)+1;
00114
00115 tdb_store_flag = TDB_REPLACE;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 hostname = client_name();
00125 if (strcmp(hostname, "UNKNOWN") == 0) {
00126 hostname = client_addr();
00127 }
00128
00129 fstrcpy(sessionid.username, vuser->user.unix_name);
00130 fstrcpy(sessionid.hostname, hostname);
00131 sessionid.id_num = i;
00132 sessionid.pid = pid;
00133 sessionid.uid = vuser->uid;
00134 sessionid.gid = vuser->gid;
00135 fstrcpy(sessionid.remote_machine, get_remote_machine_name());
00136 fstrcpy(sessionid.ip_addr, client_addr());
00137 sessionid.connect_start = time(NULL);
00138
00139 client_ip = client_inaddr(&sa);
00140
00141 if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, sessionid.hostname)) {
00142 DEBUG(1,("pam_session rejected the session for %s [%s]\n",
00143 sessionid.username, sessionid.id_str));
00144 if (tdb_store_flag == TDB_MODIFY) {
00145 tdb_delete(tdb, key);
00146 }
00147 return False;
00148 }
00149
00150 data.dptr = (char *)&sessionid;
00151 data.dsize = sizeof(sessionid);
00152 if (tdb_store(tdb, key, data, tdb_store_flag) != 0) {
00153 DEBUG(1,("session_claim: unable to create session id record\n"));
00154 return False;
00155 }
00156
00157 if (lp_utmp()) {
00158 sys_utmp_claim(sessionid.username, sessionid.hostname,
00159 client_ip,
00160 sessionid.id_str, sessionid.id_num);
00161 }
00162
00163 vuser->session_keystr = SMB_STRDUP(keystr);
00164 if (!vuser->session_keystr) {
00165 DEBUG(0, ("session_claim: strdup() failed for session_keystr\n"));
00166 return False;
00167 }
00168 return True;
00169 }
00170
00171
00172
00173
00174
00175 void session_yield(user_struct *vuser)
00176 {
00177 TDB_DATA dbuf;
00178 struct sessionid sessionid;
00179 struct in_addr *client_ip;
00180 TDB_DATA key;
00181
00182 if (!tdb) return;
00183
00184 if (!vuser->session_keystr) {
00185 return;
00186 }
00187
00188 key.dptr = vuser->session_keystr;
00189 key.dsize = strlen(vuser->session_keystr)+1;
00190
00191 dbuf = tdb_fetch(tdb, key);
00192
00193 if (dbuf.dsize != sizeof(sessionid))
00194 return;
00195
00196 memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
00197
00198 client_ip = interpret_addr2(sessionid.ip_addr);
00199
00200 SAFE_FREE(dbuf.dptr);
00201
00202 if (lp_utmp()) {
00203 sys_utmp_yield(sessionid.username, sessionid.hostname,
00204 client_ip,
00205 sessionid.id_str, sessionid.id_num);
00206 }
00207
00208 smb_pam_close_session(sessionid.username, sessionid.id_str, sessionid.hostname);
00209
00210 tdb_delete(tdb, key);
00211 }
00212
00213
00214
00215
00216 BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *),
00217 void *state)
00218 {
00219 if (!session_init()) {
00220 DEBUG(3, ("No tdb opened\n"));
00221 return False;
00222 }
00223
00224 tdb_traverse(tdb, fn, state);
00225 return True;
00226 }
00227
00228
00229
00230
00231 struct session_list {
00232 int count;
00233 struct sessionid *sessions;
00234 };
00235
00236 static int gather_sessioninfo(TDB_CONTEXT *stdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
00237 {
00238 uint32 i;
00239 struct session_list *sesslist = (struct session_list *) state;
00240 const struct sessionid *current = (const struct sessionid *) dbuf.dptr;
00241
00242 i = sesslist->count;
00243
00244 sesslist->sessions = SMB_REALLOC_ARRAY(sesslist->sessions, struct sessionid, i+1);
00245 if (!sesslist->sessions) {
00246 sesslist->count = 0;
00247 return -1;
00248 }
00249
00250 memcpy(&sesslist->sessions[i], current, sizeof(struct sessionid));
00251 sesslist->count++;
00252
00253 DEBUG(7,("gather_sessioninfo session from %s@%s\n",
00254 current->username, current->remote_machine));
00255
00256 return 0;
00257 }
00258
00259
00260
00261
00262 int list_sessions(struct sessionid **session_list)
00263 {
00264 struct session_list sesslist;
00265
00266 sesslist.count = 0;
00267 sesslist.sessions = NULL;
00268
00269 if (!session_traverse(gather_sessioninfo, (void *) &sesslist)) {
00270 DEBUG(3, ("Session traverse failed\n"));
00271 SAFE_FREE(sesslist.sessions);
00272 *session_list = NULL;
00273 return 0;
00274 }
00275
00276 *session_list = sesslist.sessions;
00277 return sesslist.count;
00278 }