Changeset 77 for trunk/samba/source/smbd/session.c
- Timestamp:
- Sep 30, 2007, 3:42:50 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/samba/source/smbd/session.c
r1 r77 9 9 This program is free software; you can redistribute it and/or modify 10 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2of the License, or11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 … … 18 18 19 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 along with this program. If not, see <http://www.gnu.org/licenses/>. 22 21 */ 23 22 … … 30 29 #include "includes.h" 31 30 32 static TDB_CONTEXT *tdb; 33 34 /******************************************************************** 35 ********************************************************************/ 31 /******************************************************************** 32 ********************************************************************/ 33 34 static struct db_context *session_db_ctx(void) 35 { 36 static struct db_context *ctx; 37 38 if (ctx) 39 return ctx; 40 41 ctx = db_open(NULL, lock_path("sessionid.tdb"), 0, 42 TDB_CLEAR_IF_FIRST|TDB_DEFAULT, 43 O_RDWR | O_CREAT, 0644); 44 return ctx; 45 } 36 46 37 47 BOOL session_init(void) 38 48 { 39 if (tdb) 40 return True; 41 42 tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, 43 O_RDWR | O_CREAT, 0644); 44 if (!tdb) { 49 if (session_db_ctx() == NULL) { 45 50 DEBUG(1,("session_init: failed to open sessionid tdb\n")); 46 51 return False; … … 56 61 BOOL session_claim(user_struct *vuser) 57 62 { 63 TDB_DATA key, data; 58 64 int i = 0; 59 TDB_DATA data;60 65 struct sockaddr sa; 61 66 struct in_addr *client_ip; 62 67 struct sessionid sessionid; 63 uint32 pid = (uint32)sys_getpid(); 64 TDB_DATA key; 68 struct server_id pid = procid_self(); 65 69 fstring keystr; 66 70 char * hostname; 67 int tdb_store_flag; /* If using utmp, we do an inital 'lock hold' store,68 but we don't need this if we are just using the69 (unique) pid/vuid combination */71 struct db_context *ctx; 72 struct db_record *rec; 73 NTSTATUS status; 70 74 71 75 vuser->session_keystr = NULL; … … 77 81 } 78 82 79 if (!session_init()) 80 return False; 83 if (!(ctx = session_db_ctx())) { 84 return False; 85 } 81 86 82 87 ZERO_STRUCT(sessionid); … … 86 91 87 92 if (lp_utmp()) { 93 88 94 for (i=1;i<MAX_SESSION_ID;i++) { 89 slprintf(keystr, sizeof(keystr)-1, "ID/%d", i); 90 key.dptr = keystr; 91 key.dsize = strlen(keystr)+1; 92 93 if (tdb_store(tdb, key, data, TDB_INSERT) == 0) break; 95 96 /* 97 * This is very inefficient and needs fixing -- vl 98 */ 99 100 struct server_id sess_pid; 101 102 snprintf(keystr, sizeof(keystr), "ID/%d", i); 103 key = string_term_tdb_data(keystr); 104 105 rec = ctx->fetch_locked(ctx, NULL, key); 106 107 if (rec == NULL) { 108 DEBUG(1, ("Could not lock \"%s\"\n", keystr)); 109 return False; 110 } 111 112 if (rec->value.dsize != sizeof(sessionid)) { 113 DEBUG(1, ("Re-using invalid record\n")); 114 break; 115 } 116 117 sess_pid = ((struct sessionid *)rec->value.dptr)->pid; 118 119 if (!process_exists(sess_pid)) { 120 DEBUG(5, ("%s has died -- re-using session\n", 121 procid_str_static(&sess_pid))); 122 break; 123 } 124 125 TALLOC_FREE(rec); 94 126 } 95 127 96 128 if (i == MAX_SESSION_ID) { 97 DEBUG(1,("session_claim: out of session IDs (max is %d)\n", 98 MAX_SESSION_ID)); 129 SMB_ASSERT(rec == NULL); 130 DEBUG(1,("session_claim: out of session IDs " 131 "(max is %d)\n", MAX_SESSION_ID)); 99 132 return False; 100 133 } 101 slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, SESSION_UTMP_TEMPLATE, i); 102 tdb_store_flag = TDB_MODIFY; 134 135 snprintf(sessionid.id_str, sizeof(sessionid.id_str), 136 SESSION_UTMP_TEMPLATE, i); 103 137 } else 104 138 { 105 slprintf(keystr, sizeof(keystr)-1, "ID/%lu/%u", 106 (long unsigned int)sys_getpid(), 107 vuser->vuid); 108 slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, 139 snprintf(keystr, sizeof(keystr), "ID/%s/%u", 140 procid_str_static(&pid), vuser->vuid); 141 key = string_term_tdb_data(keystr); 142 143 rec = ctx->fetch_locked(ctx, NULL, key); 144 145 if (rec == NULL) { 146 DEBUG(1, ("Could not lock \"%s\"\n", keystr)); 147 return False; 148 } 149 150 snprintf(sessionid.id_str, sizeof(sessionid.id_str), 109 151 SESSION_TEMPLATE, (long unsigned int)sys_getpid(), 110 152 vuser->vuid); 111 112 key.dptr = keystr; 113 key.dsize = strlen(keystr)+1; 114 115 tdb_store_flag = TDB_REPLACE; 116 } 153 } 154 155 SMB_ASSERT(rec != NULL); 117 156 118 157 /* If 'hostname lookup' == yes, then do the DNS lookup. This is … … 139 178 client_ip = client_inaddr(&sa); 140 179 141 if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, sessionid.hostname)) { 180 if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, 181 sessionid.hostname)) { 142 182 DEBUG(1,("pam_session rejected the session for %s [%s]\n", 143 183 sessionid.username, sessionid.id_str)); 144 if (tdb_store_flag == TDB_MODIFY) { 145 tdb_delete(tdb, key); 146 } 147 return False; 148 } 149 150 data.dptr = (char *)&sessionid; 184 185 TALLOC_FREE(rec); 186 return False; 187 } 188 189 data.dptr = (uint8 *)&sessionid; 151 190 data.dsize = sizeof(sessionid); 152 if (tdb_store(tdb, key, data, tdb_store_flag) != 0) { 153 DEBUG(1,("session_claim: unable to create session id record\n")); 191 192 status = rec->store(rec, data, TDB_REPLACE); 193 194 TALLOC_FREE(rec); 195 196 if (!NT_STATUS_IS_OK(status)) { 197 DEBUG(1,("session_claim: unable to create session id " 198 "record: %s\n", nt_errstr(status))); 154 199 return False; 155 200 } … … 161 206 } 162 207 163 vuser->session_keystr = SMB_STRDUP(keystr);208 vuser->session_keystr = talloc_strdup(vuser, keystr); 164 209 if (!vuser->session_keystr) { 165 DEBUG(0, ("session_claim: strdup() failed for session_keystr\n"));210 DEBUG(0, ("session_claim: talloc_strdup() failed for session_keystr\n")); 166 211 return False; 167 212 } … … 175 220 void session_yield(user_struct *vuser) 176 221 { 177 TDB_DATA dbuf;222 TDB_DATA key; 178 223 struct sessionid sessionid; 179 224 struct in_addr *client_ip; 180 TDB_DATA key; 181 182 if (!tdb) return; 225 struct db_context *ctx; 226 struct db_record *rec; 227 228 if (!(ctx = session_db_ctx())) return; 183 229 184 230 if (!vuser->session_keystr) { … … 186 232 } 187 233 188 key.dptr = vuser->session_keystr; 189 key.dsize = strlen(vuser->session_keystr)+1; 190 191 dbuf = tdb_fetch(tdb, key); 192 193 if (dbuf.dsize != sizeof(sessionid)) 234 key = string_term_tdb_data(vuser->session_keystr); 235 236 if (!(rec = ctx->fetch_locked(ctx, NULL, key))) { 194 237 return; 195 196 memcpy(&sessionid, dbuf.dptr, sizeof(sessionid)); 238 } 239 240 if (rec->value.dsize != sizeof(sessionid)) 241 return; 242 243 memcpy(&sessionid, rec->value.dptr, sizeof(sessionid)); 197 244 198 245 client_ip = interpret_addr2(sessionid.ip_addr); 199 200 SAFE_FREE(dbuf.dptr);201 246 202 247 if (lp_utmp()) { … … 206 251 } 207 252 208 smb_pam_close_session(sessionid.username, sessionid.id_str, sessionid.hostname); 209 210 tdb_delete(tdb, key); 211 } 212 213 /******************************************************************** 214 ********************************************************************/ 215 216 BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *), 217 void *state) 218 { 219 if (!session_init()) { 253 smb_pam_close_session(sessionid.username, sessionid.id_str, 254 sessionid.hostname); 255 256 rec->delete_rec(rec); 257 258 TALLOC_FREE(rec); 259 } 260 261 /******************************************************************** 262 ********************************************************************/ 263 264 static BOOL session_traverse(int (*fn)(struct db_record *db, 265 void *private_data), 266 void *private_data) 267 { 268 struct db_context *ctx; 269 270 if (!(ctx = session_db_ctx())) { 220 271 DEBUG(3, ("No tdb opened\n")); 221 272 return False; 222 273 } 223 274 224 tdb_traverse(tdb, fn, state);275 ctx->traverse_read(ctx, fn, private_data); 225 276 return True; 226 277 } … … 230 281 231 282 struct session_list { 283 TALLOC_CTX *mem_ctx; 232 284 int count; 233 285 struct sessionid *sessions; 234 286 }; 235 287 236 static int gather_sessioninfo(TDB_CONTEXT *stdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) 237 { 238 uint32 i; 288 static int gather_sessioninfo(struct db_record *rec, void *state) 289 { 239 290 struct session_list *sesslist = (struct session_list *) state; 240 const struct sessionid *current = (const struct sessionid *) dbuf.dptr; 241 242 i = sesslist->count; 243 244 sesslist->sessions = SMB_REALLOC_ARRAY(sesslist->sessions, struct sessionid, i+1); 291 const struct sessionid *current = 292 (const struct sessionid *) rec->value.dptr; 293 294 sesslist->sessions = TALLOC_REALLOC_ARRAY( 295 sesslist->mem_ctx, sesslist->sessions, struct sessionid, 296 sesslist->count+1); 297 245 298 if (!sesslist->sessions) { 246 299 sesslist->count = 0; … … 248 301 } 249 302 250 memcpy(&sesslist->sessions[i], current, sizeof(struct sessionid)); 303 memcpy(&sesslist->sessions[sesslist->count], current, 304 sizeof(struct sessionid)); 305 251 306 sesslist->count++; 252 307 … … 260 315 ********************************************************************/ 261 316 262 int list_sessions( struct sessionid **session_list)317 int list_sessions(TALLOC_CTX *mem_ctx, struct sessionid **session_list) 263 318 { 264 319 struct session_list sesslist; 265 320 321 sesslist.mem_ctx = mem_ctx; 266 322 sesslist.count = 0; 267 323 sesslist.sessions = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.