Changeset 988 for vendor/current/source3/smbd/session.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/session.c
r740 r988 30 30 #include "smbd/smbd.h" 31 31 #include "smbd/globals.h" 32 #include "dbwrap .h"32 #include "dbwrap/dbwrap.h" 33 33 #include "session.h" 34 34 #include "auth.h" 35 #include "../lib/tsocket/tsocket.h" 36 #include "../libcli/security/security.h" 37 #include "messages.h" 35 38 36 39 /******************************************************************** … … 38 41 ********************************************************************/ 39 42 40 bool session_claim(struct smbd_server_connection *sconn, user_struct *vuser) 41 { 42 struct server_id pid = sconn_server_id(sconn); 43 TDB_DATA data; 44 int i = 0; 45 struct sessionid sessionid; 46 fstring keystr; 47 struct db_record *rec; 48 NTSTATUS status; 49 50 vuser->session_keystr = NULL; 43 bool session_claim(struct smbXsrv_session *session) 44 { 45 struct auth_session_info *session_info = 46 session->global->auth_session_info; 47 const char *username; 48 const char *hostname; 49 unsigned int id_num; 50 fstring id_str; 51 51 52 52 /* don't register sessions for the guest user - its just too 53 53 expensive to go through pam session code for browsing etc */ 54 if (vuser->session_info->guest) { 55 return True; 56 } 57 58 if (!sessionid_init()) { 59 return False; 60 } 61 62 ZERO_STRUCT(sessionid); 63 64 data.dptr = NULL; 65 data.dsize = 0; 54 if (security_session_user_level(session_info, NULL) < SECURITY_USER) { 55 return true; 56 } 57 58 id_num = session->global->session_global_id; 59 60 snprintf(id_str, sizeof(id_str), "smb/%u", id_num); 61 62 /* Make clear that we require the optional unix_token in the source3 code */ 63 SMB_ASSERT(session_info->unix_token); 64 65 username = session_info->unix_info->unix_name; 66 hostname = session->global->channels[0].remote_name; 67 68 if (!smb_pam_claim_session(username, id_str, hostname)) { 69 DEBUG(1,("pam_session rejected the session for %s [%s]\n", 70 username, id_str)); 71 return false; 72 } 66 73 67 74 if (lp_utmp()) { 68 69 for (i=1;i<MAX_SESSION_ID;i++) { 70 71 /* 72 * This is very inefficient and needs fixing -- vl 73 */ 74 75 struct server_id sess_pid; 76 77 snprintf(keystr, sizeof(keystr), "ID/%d", i); 78 79 rec = sessionid_fetch_record(NULL, keystr); 80 if (rec == NULL) { 81 DEBUG(1, ("Could not lock \"%s\"\n", keystr)); 82 return False; 83 } 84 85 if (rec->value.dsize != sizeof(sessionid)) { 86 DEBUG(1, ("Re-using invalid record\n")); 87 break; 88 } 89 90 memcpy(&sess_pid, 91 ((char *)rec->value.dptr) 92 + offsetof(struct sessionid, pid), 93 sizeof(sess_pid)); 94 95 if (!process_exists(sess_pid)) { 96 DEBUG(5, ("%s has died -- re-using session\n", 97 procid_str_static(&sess_pid))); 98 break; 99 } 100 101 TALLOC_FREE(rec); 102 } 103 104 if (i == MAX_SESSION_ID) { 105 SMB_ASSERT(rec == NULL); 106 DEBUG(1,("session_claim: out of session IDs " 107 "(max is %d)\n", MAX_SESSION_ID)); 108 return False; 109 } 110 111 snprintf(sessionid.id_str, sizeof(sessionid.id_str), 112 SESSION_UTMP_TEMPLATE, i); 113 } else 114 { 115 snprintf(keystr, sizeof(keystr), "ID/%s/%u", 116 procid_str_static(&pid), vuser->vuid); 117 118 rec = sessionid_fetch_record(NULL, keystr); 119 if (rec == NULL) { 120 DEBUG(1, ("Could not lock \"%s\"\n", keystr)); 121 return False; 122 } 123 124 snprintf(sessionid.id_str, sizeof(sessionid.id_str), 125 SESSION_TEMPLATE, (long unsigned int)sys_getpid(), 126 vuser->vuid); 127 } 128 129 SMB_ASSERT(rec != NULL); 130 131 /* If 'hostname lookup' == yes, then do the DNS lookup. This is 132 needed because utmp and PAM both expect DNS names 133 134 client_name() handles this case internally. 135 */ 136 137 fstrcpy(sessionid.username, vuser->session_info->unix_name); 138 fstrcpy(sessionid.hostname, sconn->client_id.name); 139 sessionid.id_num = i; /* Only valid for utmp sessions */ 140 sessionid.pid = pid; 141 sessionid.uid = vuser->session_info->utok.uid; 142 sessionid.gid = vuser->session_info->utok.gid; 143 fstrcpy(sessionid.remote_machine, get_remote_machine_name()); 144 fstrcpy(sessionid.ip_addr_str, sconn->client_id.addr); 145 sessionid.connect_start = time(NULL); 146 147 if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, 148 sessionid.hostname)) { 149 DEBUG(1,("pam_session rejected the session for %s [%s]\n", 150 sessionid.username, sessionid.id_str)); 151 152 TALLOC_FREE(rec); 153 return False; 154 } 155 156 data.dptr = (uint8 *)&sessionid; 157 data.dsize = sizeof(sessionid); 158 159 status = rec->store(rec, data, TDB_REPLACE); 160 161 TALLOC_FREE(rec); 162 163 if (!NT_STATUS_IS_OK(status)) { 164 DEBUG(1,("session_claim: unable to create session id " 165 "record: %s\n", nt_errstr(status))); 166 return False; 167 } 75 sys_utmp_claim(username, hostname, id_str, id_num); 76 } 77 78 return true; 79 } 80 81 /******************************************************************** 82 called when a session is destroyed 83 ********************************************************************/ 84 85 void session_yield(struct smbXsrv_session *session) 86 { 87 struct auth_session_info *session_info = 88 session->global->auth_session_info; 89 const char *username; 90 const char *hostname; 91 unsigned int id_num; 92 fstring id_str = ""; 93 94 id_num = session->global->session_global_id; 95 96 snprintf(id_str, sizeof(id_str), "smb/%u", id_num); 97 98 /* Make clear that we require the optional unix_token in the source3 code */ 99 SMB_ASSERT(session_info->unix_token); 100 101 username = session_info->unix_info->unix_name; 102 hostname = session->global->channels[0].remote_name; 168 103 169 104 if (lp_utmp()) { 170 sys_utmp_claim(sessionid.username, sessionid.hostname, 171 sessionid.ip_addr_str, 172 sessionid.id_str, sessionid.id_num); 173 } 174 175 vuser->session_keystr = talloc_strdup(vuser, keystr); 176 if (!vuser->session_keystr) { 177 DEBUG(0, ("session_claim: talloc_strdup() failed for session_keystr\n")); 178 return False; 179 } 180 return True; 181 } 182 183 /******************************************************************** 184 called when a session is destroyed 185 ********************************************************************/ 186 187 void session_yield(user_struct *vuser) 188 { 189 struct sessionid sessionid; 190 struct db_record *rec; 191 192 if (!vuser->session_keystr) { 193 return; 194 } 195 196 rec = sessionid_fetch_record(NULL, vuser->session_keystr); 197 if (rec == NULL) { 198 return; 199 } 200 201 if (rec->value.dsize != sizeof(sessionid)) 202 return; 203 204 memcpy(&sessionid, rec->value.dptr, sizeof(sessionid)); 205 206 if (lp_utmp()) { 207 sys_utmp_yield(sessionid.username, sessionid.hostname, 208 sessionid.ip_addr_str, 209 sessionid.id_str, sessionid.id_num); 210 } 211 212 smb_pam_close_session(sessionid.username, sessionid.id_str, 213 sessionid.hostname); 214 215 rec->delete_rec(rec); 216 217 TALLOC_FREE(rec); 105 sys_utmp_yield(username, hostname, id_str, id_num); 106 } 107 108 smb_pam_close_session(username, id_str, hostname); 218 109 } 219 110 … … 224 115 TALLOC_CTX *mem_ctx; 225 116 int count; 117 const char *filter_user; 118 const char *filter_machine; 226 119 struct sessionid *sessions; 227 120 }; … … 232 125 struct session_list *sesslist = (struct session_list *)private_data; 233 126 234 sesslist->sessions = TALLOC_REALLOC_ARRAY( 127 /* filter the session if required */ 128 129 if (sesslist->filter_user && 130 (sesslist->filter_user[0] != '\0') && 131 !strequal(session->username, sesslist->filter_user)) { 132 return 0; 133 } 134 135 if (sesslist->filter_machine && 136 (sesslist->filter_machine[0] != '\0') && 137 !strequal(session->remote_machine, 138 sesslist->filter_machine)) { 139 return 0; 140 } 141 142 sesslist->sessions = talloc_realloc( 235 143 sesslist->mem_ctx, sesslist->sessions, struct sessionid, 236 144 sesslist->count+1); … … 258 166 { 259 167 struct session_list sesslist; 260 int ret;168 NTSTATUS status; 261 169 262 170 sesslist.mem_ctx = mem_ctx; 263 171 sesslist.count = 0; 172 sesslist.filter_user = NULL; 173 sesslist.filter_machine = NULL; 264 174 sesslist.sessions = NULL; 265 175 266 ret= sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist);267 if ( ret == -1) {176 status = sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist); 177 if (!NT_STATUS_IS_OK(status)) { 268 178 DEBUG(3, ("Session traverse failed\n")); 269 179 SAFE_FREE(sesslist.sessions); … … 275 185 return sesslist.count; 276 186 } 187 188 /******************************************************************** 189 find the sessions that match the given username and machine 190 ********************************************************************/ 191 192 int find_sessions(TALLOC_CTX *mem_ctx, const char *username, 193 const char *machine, struct sessionid **session_list) 194 { 195 struct session_list sesslist; 196 NTSTATUS status; 197 198 sesslist.mem_ctx = mem_ctx; 199 sesslist.count = 0; 200 sesslist.filter_user = username; 201 sesslist.filter_machine = machine; 202 sesslist.sessions = NULL; 203 204 status = sessionid_traverse_read(gather_sessioninfo, (void *)&sesslist); 205 if (!NT_STATUS_IS_OK(status)) { 206 DEBUG(3, ("Session traverse failed: %s\n", nt_errstr(status))); 207 TALLOC_FREE(sesslist.sessions); 208 *session_list = NULL; 209 return 0; 210 } 211 212 *session_list = sesslist.sessions; 213 return sesslist.count; 214 }
Note:
See TracChangeset
for help on using the changeset viewer.