DocumentationGenerated on Thu Aug 31 00:02:30 2006 |
||
User.cppGo to the documentation of this file.00001 00002 // $Id: User.cpp,v 1.98 2005/07/23 19:57:17 klas Exp $ 00003 // 00004 // Usage: Holds information about connected users. 00005 // 00006 // A part of babyftpd, licensed under the GNU GPL, see the file 00007 // LICENSE for complete information. 00009 00010 #define USER_CPP 00011 #define NETINCLS 00012 #define BABY_CORE 00013 #include "User.h" 00014 00015 User::User(int socket_id, struct sockaddr_in &addr) : Connection() 00016 { 00017 this->_root_dir = "/"; 00018 this->_failed_logins = 0; 00019 this->_logged_in = NOT_LOGGED_IN; 00020 this->_data_id = 0; 00021 this->_rest_pos = 0; 00022 this->addr(addr); 00023 this->socket_id(socket_id); 00024 this->thread_id(pthread_self()); 00025 this->host_name(inet_ntoa(this->addr().sin_addr)); 00026 struct timeval tmp = {config->general_user.idle, 0}; 00027 this->timeout(tmp); 00028 00029 // setting the bitflags on mlst_facts... not to clean.. 00030 for(int i = 0; i <= LAST_FACT; i++) 00031 this->settings(i, B_SET); 00032 } 00033 00034 User::~User() 00035 { 00036 if(this->_data_id) 00037 close(this->_data_id); 00038 00039 if(this->settings(PAM_DONE)) 00040 { 00041 sem_wait(&comm.pam_lock); 00042 pam_close_session(this->_pamh, PAM_SILENT); 00043 pam_end(this->_pamh, PAM_SUCCESS); 00044 sem_post(&comm.pam_lock); 00045 } 00046 00047 // killing off any ongoing data threads 00048 for(vector<Data*>::iterator data_it = data_vec.begin(); 00049 data_it != data_vec.end(); data_it++) 00050 if(*data_it) 00051 pthread_cancel((*data_it)->thread_id()); 00052 00053 while(data_vec.size()) 00054 { } 00055 00056 pthread_rwlock_wrlock(&user_list_lock); 00057 user_list.erase(get_user_it(this->thread_id())); 00058 logging->log_this(4, TYPE_INFO, "user thread " + 00059 util.itos(this->thread_id()) + " exiting, connected users:" + 00060 util.itos(user_list.size())); 00061 pthread_rwlock_unlock(&user_list_lock); 00062 } 00063 00064 vector<User*>::iterator get_user_it(pthread_t thread_id) 00065 { 00066 vector<User*>::iterator user_it; 00067 00068 BABY_RDLOCK(user_list_lock); 00069 for(user_it = user_list.begin(); user_it != user_list.end(); user_it++) 00070 if(pthread_equal((*user_it)->thread_id(), thread_id)) 00071 break; 00072 BABY_UNLOCK(user_list_lock); 00073 00074 return(user_it); 00075 } 00076 00077 00078 vector<Data*>::iterator User::get_data_it(pthread_t thread_id) 00079 { 00080 vector<Data*>::iterator data_it; 00081 00082 BABY_RDLOCK(this->lock); 00083 for(data_it = this->data_vec.begin(); data_it != this->data_vec.end(); 00084 data_it++) 00085 if(pthread_equal((*data_it)->thread_id(), thread_id)) 00086 break; 00087 BABY_UNLOCK(this->lock); 00088 00089 return(data_it); 00090 } 00091 00092 bool User::data_vec_full() 00093 { 00094 if(data_vec.size() >= 00095 static_cast<size_t>(config->get_user(this->user_name()).sim_data)) 00096 return(true); 00097 return(false); 00098 } 00099 00100 bool User::login(void) 00101 { 00102 char pwdata[PWBUF_SIZE]; 00103 struct passwd pwd, *pwd_ptr; 00104 this->logged_in(LOGGED_IN); 00105 getpwnam_r(this->user_name().c_str(), &pwd, pwdata, sizeof(pwdata), 00106 &pwd_ptr); 00107 uid_t uid = pwd.pw_uid; 00108 gid_t gid = pwd.pw_gid; 00109 if(config->get_user(this->user_name()).only_home) 00110 this->root_dir(pwd.pw_dir); 00111 this->current_dir(pwd.pw_dir); 00112 seteuid(0); 00113 setgid(gid); 00114 seteuid(uid); // dropping permissions... 00115 struct timeval tmp = {config->get_user(this->user_name()).idle, 0}; 00116 this->timeout(tmp); 00117 return true; 00118 } 00119 00120 User &User::operator>>(string &message) 00121 { 00122 char tmp_buf[210] = { 0 }; 00123 fd_set rfd; 00124 FD_ZERO(&rfd); 00125 FD_SET(this->socket_id(), &rfd); 00126 timeval tv = this->timeout(); 00127 00128 if(!select(this->socket_id() + 1, &rfd, NULL, NULL, &tv)) 00129 { 00130 *this << "421 Connection timed out(" 00131 << util.itos(config->get_user(this->user_name()).idle) 00132 << " seconds). Disconnected."; 00133 if(this->logged_in()) 00134 logging->log_this(3, TYPE_AUTH, "User " + this->user_name() + 00135 ", disconnected due to timeout."); 00136 00137 this->settings(FAILURE, B_SET); 00138 } 00139 else 00140 { 00141 if(this->receive(tmp_buf, 200) > 0) 00142 message = tmp_buf; 00143 else 00144 this->settings(FAILURE, B_SET); 00145 } 00146 return *this; 00147 } 00148 00149 void kill_user(void *user) 00150 { 00151 delete static_cast<User*>(user); 00152 } |
- Copyright © 2005, BabyFTPd
- Powered by: