CUserManager Class Reference

#include <UserManager.h>

Public Member Functions

 CUserManager ()
 ~CUserManager ()
int Initialize (UserManagerConfig *Config)
int Logon (char *UserName, char *Password, RioUser **User)
int CreateUser (char *UserName, char *Password)
 Nova funcao para criar um novo usuario.
int RemoveUser (char *UserName)
 Nova funcao para remover um dos usuarios do RIO.
int ChangePassword (char *UserName, char *Password)
 Nova funcao para alterar a senha de um dos usuarios do RIO.
int GetUserList (vector< string > &UserList)
 Nova funcao para obter a lista com todos os usuarios.

Data Fields

ofstream m_log

Private Attributes

char * m_UserRoot
char * m_FileRoot
CMutexm_Mutex
bool m_initialized
char m_PasswdFileName [MaxPathSize]

Detailed Description

Definition at line 41 of file UserManager.h.


Constructor & Destructor Documentation

CUserManager::CUserManager (  ) 

Definition at line 43 of file UserManager.cpp.

00044 {
00045     m_Mutex       = new CMutex;
00046     m_FileRoot    = NULL;
00047     m_UserRoot    = NULL;
00048     m_initialized = false;
00049     // m_log does not need to be initialized
00050 }

CUserManager::~CUserManager (  ) 

Definition at line 53 of file UserManager.cpp.

00054 {
00055     //if( m_PassFile != NULL )
00056     //    fclose( m_PassFile );
00057     if( m_FileRoot != NULL )    
00058         delete [] m_FileRoot;
00059     m_FileRoot = 0;
00060     if( m_UserRoot != NULL )    
00061         delete [] m_UserRoot;
00062     m_UserRoot = 0;
00063     delete m_Mutex;
00064     if( m_log.is_open() )
00065         m_log.close();
00066 }


Member Function Documentation

int CUserManager::ChangePassword ( char *  UserName,
char *  Password 
)

Nova funcao para alterar a senha de um dos usuarios do RIO.

Parameters:
UserName ponteiro para o nome do usuario.
Password pontrito para a senha do usuario.
Returns:
S_OK se o a senha fou alterada com sucesso ou o codigo de erro caso nao tenha sido possivel alterar a senha do usuario.

Definition at line 778 of file UserManager.cpp.

00779 {
00780     char localUserName[ MaxPathSize ];
00781     char localPassword[ MaxPathSize ];
00782     int TotalFields;
00783 
00784     // Variavel com o descritor do arquivo a ser aberto.
00785     FILE *PassFile;
00786 
00787     if( ( strlen( UserName ) == 0 ) && ( strcmp( UserName, "guest" ) == 0 ) )
00788     {
00789         if( m_log.is_open() )
00790             m_log << " Invalid User " << UserName << endl;
00791 
00792         return ERROR_USERMANAGER + ERROR_INVALID_USER;
00793     }
00794 
00795     // Espera tenta obter o mutex para acessar o arquivo de modo exclusivo.
00796     m_Mutex->Wait();
00797 
00798     // Tenta abrir o arquivo para a leitura e escrita.
00799     PassFile = fopen( m_PasswdFileName, "r+" );
00800     if( PassFile != NULL )
00801     {
00802         while( ( TotalFields = fscanf( PassFile, "%s %s",
00803                                        localUserName, localPassword ) )
00804                                        != EOF )
00805         {
00806             if( ( TotalFields == 2) &&
00807                 ( strcmp( localUserName, UserName ) == 0  ) )
00808                 break;
00809             else if( TotalFields == 1 )
00810             {
00811                 // A linha nao possui a senha. Note que se TotalFiels
00812                 // for 0, isso provavelmente indica uma linha vazia.
00813                 if( m_log.is_open() )
00814                     m_log << "User " << localUserName << " in file "
00815                           <<  m_PasswdFileName << " ignored because "
00816                           << "does not have a password!"<< endl;
00817 
00818             }
00819         }
00820 
00821         // Verifica se ocorreu algum erro ao acessar o arquivo (o scanf
00822         // pode ser abortado por fim do arquivo ou por um erro ao
00823         // acessar o arquivo).
00824         if( errno != 0 )
00825         {
00826             // Fecha o arquivo aberto.
00827             fclose( PassFile );
00828 
00829             // Se o usuario existir, entao devemos retornar um erro.
00830             // Libera o mutex para acessar o arquivo de modo exclusivo.
00831             m_Mutex->Release();
00832 
00833             // Eu acho que podemos gerar somente um aviso, pois e
00834             // possivel que tenhamos conseguido achar com sucesso o
00835             // usuario no arquivo.
00836             if( m_log.is_open() )
00837                 m_log << "Error " << errno << " (" << strerror( errno )
00838                       << ") when reading password file "
00839                       <<  m_PasswdFileName << "!"<< endl;
00840 
00841             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00842         }
00843 
00844         // Verifica se nao achamos nenhum usuario.
00845         if( strcmp( localUserName, UserName ) != 0 )
00846         {
00847             // Fecha o arquivo aberto.
00848             fclose( PassFile );
00849 
00850             // Se o usuario nao existir, entao devemos retornar um erro.
00851             // Libera o mutex para acessar o arquivo de modo exclusivo.
00852             m_Mutex->Release();
00853 
00854            if( m_log.is_open() )
00855                m_log << " User " << UserName << "not found!" << endl;
00856 
00857            return ERROR_USERMANAGER + ERROR_INVALID_USER;
00858         }
00859 
00860         // Volta para a posicao do arquivo com o nome do usuario.
00861         //if( fseek( PassFile, PosLastLine, SEEK_SET ) < 0 )
00862         if( fseek( PassFile,
00863                    -( strlen( localUserName ) + strlen( localPassword ) + 1 ),
00864                    SEEK_CUR ) < 0 )
00865         {
00866             // Fecha o arquivo aberto.
00867             fclose( PassFile );
00868 
00869             // Libera o mutex para acessar o arquivo de modo exclusivo.
00870             m_Mutex->Release();
00871 
00872             if( m_log.is_open() )
00873                 m_log << "Invalid User/Password [Failed to seek in "
00874                       << m_PasswdFileName << " file (errno=" << errno
00875                       << ",strerr=" << strerror( errno ) << ")!]"
00876                       << endl;
00877 
00878             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00879 
00880         }
00881 
00882         // Encripta a senha
00883         char *cryptPass;
00884         char salt[ 3 ];
00885 
00886         // Unshuffling password
00887         for( unsigned int i = 0; i < strlen( Password ); i++ )
00888             Password[ i ] = ( ( Password[ i ] & 0x0F ) << 4 ) |
00889                             ( ( Password[ i ] & 0xF0 ) >> 4 );
00890 
00891         salt[ 0 ] = localPassword[ 0 ];
00892         salt[ 1 ] = localPassword[ 1 ];
00893         salt[ 2 ] = 0;
00894         cryptPass = crypt( Password, salt );
00895 
00896         if( cryptPass == NULL )
00897         {
00898             // Fecha o arquivo aberto.
00899             fclose( PassFile );
00900 
00901             // Se o usuario existir, entao devemos retornar um erro.
00902             // Libera o mutex para acessar o arquivo de modo exclusivo.
00903             m_Mutex->Release();
00904 
00905             if( m_log.is_open() )
00906                 m_log << "Invalid User/Password [Failed to encrypt "
00907                       << "user " << UserName << " password!]" << endl;
00908 
00909             return ERROR_USERMANAGER + ERROR_MEMORY;
00910         }
00911 
00912         // Altera a senha do usuario.
00913         if( fprintf( PassFile, "%s %s\n", UserName, cryptPass ) < 0 )
00914         {
00915             // Fecha o arquivo aberto.
00916             fclose( PassFile );
00917 
00918             // Libera o mutex para acessar o arquivo de modo exclusivo.
00919             m_Mutex->Release();
00920 
00921             if( m_log.is_open() )
00922                 m_log << "Invalid User/Password [Failed to save new "
00923                       << "user " << UserName << "password in "
00924                       << m_PasswdFileName << " file (errno=" << errno
00925                       << ",strerr=" << strerror( errno ) << ")!]"
00926                       << endl;
00927 
00928             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00929         }
00930 
00931         // Fecha o arquivo aberto.
00932         fclose( PassFile );
00933 
00934         // Libera o mutex para acessar o arquivo de modo exclusivo.
00935         m_Mutex->Release();
00936     }
00937     else
00938     {
00939         // Libera o mutex para acessar o arquivo de modo exclusivo.
00940         m_Mutex->Release();
00941 
00942         if( m_log.is_open() )
00943             m_log << "Invalid User/Password [Failed to open "
00944                   << m_PasswdFileName << " file (errno=" << errno
00945                   << ",strerr=" << strerror( errno ) << ")!]" << endl;
00946 
00947         return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00948     }
00949 
00950     return S_OK;
00951 }

int CUserManager::CreateUser ( char *  UserName,
char *  Password 
)

Nova funcao para criar um novo usuario.

Parameters:
UserName ponteiro para o nome do usuario.
Password pontrito para a senha do usuario.
Returns:
S_OK se o usuario foi criado com sucesso ou o codigo de erro caso o usuario nao tenha sido criado com sucesso.

Definition at line 337 of file UserManager.cpp.

00338 {
00339     char localUserName[ MaxPathSize ];
00340     char localPassword[ MaxPathSize ];
00341     int  result;
00342     struct stat mystat;
00343     char name [2*MaxPathSize+1];
00344     int TotalFields;
00345 
00346     // Variavel com o descritor do arquivo a ser aberto.
00347     FILE *PassFile;
00348 
00349     if( ( strlen( UserName ) == 0 ) || ( strcmp( UserName, "guest") == 0 ) )
00350     {
00351         if( m_log.is_open() )
00352             m_log << " Invalid User " << name << endl;
00353         return ERROR_USERMANAGER + ERROR_INVALID_USER;
00354     }
00355 
00356     strcpy( name, m_FileRoot );
00357     strcat( name, "/" );
00358     strcat( name, UserName );
00359 
00360     // Verifica se o diretorio do usuario ja existe. Se nao existir, vamos
00361     // cria-lo. Se ele existir e for um arquivo, damos um erro.
00362     result = stat( name, &mystat );
00363 
00364     if( ( result == 0 ) && ( !S_ISDIR( mystat.st_mode ) ) )
00365     {
00366         // Existe o /<UserName>, mas ele e um arquivo e nao um diretorio.
00367         if( m_log.is_open() )
00368             m_log << "Invalid User/Password [" << name << " is not a directory!"
00369                   << "]" << endl;
00370 
00371         return ERROR_USERMANAGER + ERROR_INVALID_USER_DIRECTORY;
00372     }
00373     else if( result < 0 )
00374     {
00375         // Nao existe o /<UserName>. Entao, vamos criar este diretorio.
00376         if( mkdir( name, 0700 ) != 0 )
00377         {
00378             if( m_log.is_open() )
00379                 m_log << "Invalid User/Password [error " << errno << " ("
00380                       << strerror( errno ) << ") when trying to  create "
00381                       << "directory "<< name << "!]" << endl;
00382 
00383             return ERROR_USERMANAGER + ERROR_INVALID_USER_DIRECTORY;
00384 
00385         }
00386     }
00387 
00388     // Tenta obter o mutex para acessar o arquivo de modo exclusivo.
00389     m_Mutex->Wait();
00390 
00391     // Tenta abrir o arquivo para a leitura e escrita.
00392     PassFile = fopen( m_PasswdFileName, "r+" );
00393     if( PassFile != NULL )
00394     {
00395         while( ( TotalFields = fscanf( PassFile, "%s %s",
00396                                        localUserName, localPassword ) )
00397                                        != EOF )
00398         {
00399             if( ( TotalFields == 2) &&
00400                 ( strcmp( localUserName, UserName ) == 0  ) )
00401             {
00402                 // Fecha o arquivo aberto.
00403                 fclose( PassFile );
00404 
00405                 // Se o usuario existir, entao devemos retornar um erro.
00406                 // Libera o mutex para acessar o arquivo de modo exclusivo.
00407                 m_Mutex->Release();
00408 
00409                 if( m_log.is_open() )
00410                     m_log << "Invalid User/Password [User " << UserName
00411                           << " already exists!]"<< endl;
00412 
00413                 return ERROR_USERMANAGER + ERROR_USER_EXISTS;
00414             }
00415             else if( TotalFields == 1 )
00416             {
00417                 // A linha nao possui a senha. Note que se TotalFiels
00418                 // for 0, isso provavelmente indica uma linha vazia.
00419                 if( m_log.is_open() )
00420                     m_log << "User " << localUserName << " in file "
00421                           <<  m_PasswdFileName << " ignored because "
00422                           << "does not have a password!"<< endl;
00423 
00424             }
00425         }
00426 
00427         // Verifica se ocorreu algum erro ao acessar o arquivo (o scanf
00428         // pode ser abortado por fim do arquivo ou por um erro ao
00429         // acessar o arquivo).
00430         if( errno != 0 )
00431         {
00432             // Fecha o arquivo aberto.
00433             fclose( PassFile );
00434 
00435             // Se o usuario existir, entao devemos retornar um erro.
00436             // Libera o mutex para acessar o arquivo de modo exclusivo.
00437             m_Mutex->Release();
00438 
00439             // Eu acho que podemos gerar somente um aviso, pois e
00440             // possivel que tenhamos conseguido achar com sucesso o
00441             // usuario no arquivo.
00442             if( m_log.is_open() )
00443                 m_log << "Error " << errno << " (" << strerror( errno )
00444                       << ") when reading password file "
00445                       <<  m_PasswdFileName << "!"<< endl;
00446 
00447             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00448         }
00449 
00450         // Salta para o final do arquivo.
00451         if( fseek( PassFile, 0, SEEK_END ) < 0 )
00452         {
00453             // Fecha o arquivo aberto.
00454             fclose( PassFile );
00455 
00456             // Se o usuario existir, entao devemos retornar um erro.
00457             // Libera o mutex para acessar o arquivo de modo exclusivo.
00458             m_Mutex->Release();
00459 
00460             if( m_log.is_open() )
00461                 m_log << "Invalid User/Password [Failed to seek in "
00462                       << m_PasswdFileName << " file (errno=" << errno
00463                       << ",strerr=" << strerror( errno ) << ")!]"
00464                       << endl;
00465 
00466             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00467 
00468         }
00469 
00470         // Encripta a senha
00471         char *cryptPass;
00472         char salt[ 3 ];
00473 
00474         // Unshuffling password
00475         for( unsigned int i = 0; i < strlen( Password ); i++ )
00476             Password[ i ] = ( ( Password[ i ] & 0x0F) << 4 ) |
00477                             ( ( Password[ i ] & 0xF0) >> 4 );
00478 
00479         salt[ 0 ] = localPassword[ 0 ];
00480         salt[ 1 ] = localPassword[ 1 ];
00481         salt[ 2 ] = 0;
00482         cryptPass = crypt( Password, salt );
00483 
00484         if( cryptPass == NULL )
00485         {
00486             // Fecha o arquivo aberto.
00487             fclose( PassFile );
00488 
00489             // Se o usuario existir, entao devemos retornar um erro.
00490             // Libera o mutex para acessar o arquivo de modo exclusivo.
00491             m_Mutex->Release();
00492 
00493             if( m_log.is_open() )
00494                 m_log << "Invalid User/Password [Failed to encrypt "
00495                       << "user " << UserName << " password!]" << endl;
00496 
00497             return ERROR_USERMANAGER + ERROR_MEMORY;
00498         }
00499 
00500         // Adiciona o novo usuario ao final do arquivo (como a senha ja vem
00501         // encriptada, somente precisamos fazer a inversoes dos 4 bits
00502         // inferiores com os 4 bits superiores, como e feito na funcao
00503         // login). Note que, como varremos todo o arquivo, ja estamos no
00504         // final dele.
00505         if( fprintf( PassFile, "%s %s\n", UserName, cryptPass ) < 0 )
00506         {
00507             // Fecha o arquivo aberto.
00508             fclose( PassFile );
00509 
00510             // Se o usuario existir, entao devemos retornar um erro.
00511             // Libera o mutex para acessar o arquivo de modo exclusivo.
00512             m_Mutex->Release();
00513 
00514             if( m_log.is_open() )
00515                 m_log << "Invalid User/Password [Failed to save user/password  "
00516                       << "in " << m_PasswdFileName << " file (errno=" << errno
00517                       << ",strerr=" << strerror( errno ) << ")!]" << endl;
00518 
00519             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00520         }
00521 
00522         // Fecha o arquivo aberto.
00523         fclose( PassFile );
00524 
00525         // Libera o mutex para acessar o arquivo de modo exclusivo.
00526         m_Mutex->Release();
00527     }
00528     else
00529     {
00530         // Libera o mutex para acessar o arquivo de modo exclusivo.
00531         m_Mutex->Release();
00532 
00533         if( m_log.is_open() )
00534             m_log << "Invalid User/Password [Failed to open "
00535                   << m_PasswdFileName << " file (errno=" << errno << ",strerr="
00536                   << strerror( errno ) << ")!]" << endl;
00537 
00538         return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00539     }
00540 
00541     return S_OK;
00542 }

int CUserManager::GetUserList ( vector< string > &  UserList  ) 

Nova funcao para obter a lista com todos os usuarios.

Parameters:
USerList vetor de strings (STL) no qual a lista de usuarios sera armazenada.
Returns:
S_OK caso a lista tenha sido gerada com sucesso ou o codigo de erro caso nao tenha sido possivel gerar a lista.

Definition at line 953 of file UserManager.cpp.

00954 {
00955     char localUserName[ MaxPathSize ];
00956     char localPassword[ MaxPathSize ];
00957     int TotalFields;
00958 
00959     // Variavel com o descritor temporario do arquivo. Somente abrimos o arquivo
00960     // aqui para verificar se ele existe.
00961     FILE *PassFile;
00962 
00963     // Limpa a lista de usuarios.
00964     UserList.clear();
00965 
00966     try
00967     {
00968         UserList.push_back( string( "guest" ) );
00969     }
00970     catch( bad_alloc &ba )
00971     {
00972         if( m_log.is_open() )
00973             m_log << "Error bac_alloc (" << ba.what()
00974                   << ") when adding user guest to userlist!" << endl;
00975 
00976         // Limpa o vetor.
00977         UserList.clear();
00978 
00979         return ERROR_USERMANAGER + ERROR_MEMORY;
00980 
00981     }
00982 
00983     // Espera tenta obter o mutex para acessar o arquivo de modo exclusivo.
00984     m_Mutex->Wait();
00985 
00986     // Tenta abrir o arquivo para a leitura e escrita.
00987     PassFile = fopen( m_PasswdFileName, "r+" );
00988     if( PassFile != NULL )
00989     {
00990         while( ( TotalFields = fscanf( PassFile, "%s %s",
00991                                        localUserName, localPassword ) )
00992                                        != EOF )
00993         {
00994             if( TotalFields == 2)
00995             {
00996                 try
00997                 {
00998                     UserList.push_back( string( localUserName ) );
00999                 }
01000                 catch( bad_alloc &ba )
01001                 {
01002                     if( m_log.is_open() )
01003                         m_log << "Error bac_alloc (" << ba.what()
01004                               << ") when adding a user " << localUserName
01005                               << " to userlist!" << endl;
01006 
01007                     // Fecha o arquivo aberto.
01008                     fclose( PassFile );
01009 
01010                     // Se o usuario existir, entao devemos retornar um erro.
01011                     // Libera o mutex para acessar o arquivo de modo exclusivo.
01012                     m_Mutex->Release();
01013 
01014                     // Limpa o vetor.
01015                     UserList.clear();
01016 
01017                     return ERROR_USERMANAGER + ERROR_MEMORY;
01018 
01019                 }
01020             }
01021             else if( TotalFields == 1 )
01022             {
01023                 // A linha nao possui a senha. Note que se TotalFiels
01024                 // for 0, isso provavelmente indica uma linha vazia.
01025                 if( m_log.is_open() )
01026                     m_log << "User " << localUserName << " in file "
01027                           <<  m_PasswdFileName << " ignored because "
01028                           << "does not have a password!"<< endl;
01029 
01030             }
01031         }
01032 
01033         // Fecha o arquivo aberto.
01034         fclose( PassFile );
01035 
01036         // Se o usuario existir, entao devemos retornar um erro.
01037         // Libera o mutex para acessar o arquivo de modo exclusivo.
01038         m_Mutex->Release();
01039     }
01040     else
01041     {
01042         // Libera o mutex para acessar o arquivo de modo exclusivo.
01043         m_Mutex->Release();
01044 
01045         if( m_log.is_open() )
01046             m_log << "Invalid User/Password [Failed to open "
01047                   << m_PasswdFileName << " file (errno=" << errno
01048                   << ",strerr=" << strerror( errno ) << ")!]" << endl;
01049 
01050         // Limpa o vetor.
01051         UserList.clear();
01052 
01053         return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
01054     }
01055 
01056     return S_OK;
01057 }

int CUserManager::Initialize ( UserManagerConfig Config  ) 

Definition at line 73 of file UserManager.cpp.

00074 {
00075     // Variavel com o descritor temporario do arquivo. Somente abrimos o arquivo
00076     // aqui para verificar se ele existe.
00077     FILE *PassFile;
00078 
00079     if( Config->GenerateLogs )
00080     {
00081         // Variavel usada para compor o nome do arquivo com o log.
00082         char LogFileName[ MaxPathSize ];
00083         // Compoe o nome do arquivo com o log.
00084         strcpy( LogFileName, Config->LogsDirectory );
00085         strcat( LogFileName, LOGFILE );
00086         m_log.open( LogFileName );
00087     }
00088 
00089     // Check if not initialized yet
00090     if( m_initialized )
00091     {
00092         if( m_log.is_open() )
00093             m_log << "Initialize(): Tried to initialize component "
00094                   << "already initialized" << endl;
00095 
00096         return ERROR_USERMANAGER + ERROR_INITIALIZED;
00097     }
00098 
00099     // check if mutex to control table access was successfully created
00100     if( !m_Mutex->IsOpen() )
00101     {
00102         if( m_log.is_open() )
00103             m_log << "Initialize(): Failed to create mutex" << endl;
00104 
00105         return ERROR_USERMANAGER + ERROR_CREATE_MUTEX;
00106     }
00107 
00108     // Alteracao para ler o arquivo de senhas de um diretorio qualquer,
00109     // diferente de onde o servidor esta. 
00110     // Compoe o nome do arquivo com as senhas.
00111     strcpy( m_PasswdFileName, Config->ConfigsDirectory );
00112     strcat( m_PasswdFileName, PASSWDFILE );
00113 
00114     // Vou deixar isso somente para verificar se o arquivo existe e pode ser
00115     // lido ou escrito.
00116     PassFile = fopen( m_PasswdFileName, "r+" );
00117     if( PassFile == NULL )
00118     {
00119         RioErr << "Initialize(): Failed to check password file" << endl;
00120         return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00121     }
00122 
00123     // Fecha o arquivo aberto.
00124     fclose( PassFile );
00125 
00126     m_FileRoot = new char[strlen( Config->FileRoot ) + 1];
00127     strcpy( m_FileRoot, Config->FileRoot );
00128 
00129     m_UserRoot = new char[strlen( Config->UserRoot ) + 1];
00130     strcpy( m_UserRoot, Config->UserRoot );
00131 
00132     m_initialized = true;
00133 
00134     return S_OK;
00135 }

int CUserManager::Logon ( char *  UserName,
char *  Password,
RioUser **  User 
)

Definition at line 138 of file UserManager.cpp.

00139 {
00140     char localUserName[ MaxPathSize ];
00141     char localPassword[ MaxPathSize ];
00142     int  result;
00143     struct stat mystat;
00144     char name [2*MaxPathSize+1];
00145     int TotalFields;
00146 
00147     // Variavel com o descritor do arquivo a ser aberto.
00148     FILE *PassFile;
00149 
00150     // be sure he doesn't have anyone
00151     *User = 0;
00152 
00153     RioUser *newuser = new RioUser( this );
00154     if( newuser == 0 )
00155     {
00156         if( m_log.is_open() )
00157             m_log << " Error when allocating RioUser! " << UserName << endl;
00158 
00159         return ERROR_USERMANAGER + ERROR_MEMORY;
00160     }
00161 
00162     if( strlen( UserName ) == 0 )
00163     {
00164         if( m_log.is_open() )
00165             m_log << " Invalid User " << UserName << endl;
00166 
00167         return ERROR_USERMANAGER + ERROR_INVALID_USER;
00168     }
00169 
00170     if( strcmp( UserName, "guest" ) != 0 )
00171     {
00172         // Espera tenta obter o mutex para acessar o arquivo de modo
00173         // exclusivo.
00174         m_Mutex->Wait();
00175 
00176         // Tenta abrir o arquivo para a leitura.
00177         PassFile = fopen( m_PasswdFileName, "r" );
00178         if( PassFile != NULL )
00179         {
00180             while( ( TotalFields = fscanf( PassFile, "%s %s",
00181                                            localUserName, localPassword ) )
00182                                            != EOF )
00183             {
00184                 if( ( TotalFields == 2) &&
00185                     ( strcmp( localUserName, UserName ) == 0  ) )
00186                     break;
00187                 else if( TotalFields == 1 )
00188                 {
00189                     // A linha nao possui a senha. Note que se TotalFiels
00190                     // for 0, isso provavelmente indica uma linha vazia.
00191                     if( m_log.is_open() )
00192                         m_log << "User " << localUserName << " in file "
00193                               <<  m_PasswdFileName << " ignored because "
00194                               << "does not have a password!"<< endl;
00195 
00196                 }
00197             }
00198 
00199             // Verifica se ocorreu algum erro ao acessar o arquivo (o scanf
00200             // pode ser abortado por fim do arquivo ou por um erro ao
00201             // acessar o arquivo).
00202             if( errno != 0 )
00203             {
00204                 // Eu acho que podemos gerar somente um aviso, pois e
00205                 // possivel que tenhamos conseguido achar com sucesso o
00206                 // usuario no arquivo.
00207                 if( m_log.is_open() )
00208                     m_log << "Error " << errno << " (" << strerror( errno )
00209                           << ") when reading password file "
00210                           <<  m_PasswdFileName << "!"<< endl;
00211             }
00212 
00213             // Fecha o arquivo aberto.
00214             fclose( PassFile );
00215 
00216             // Libera o mutex para acessar o arquivo de modo exclusivo.
00217             m_Mutex->Release();
00218 
00219             if( strcmp( localUserName, UserName ) == 0 )
00220             {
00221                 char *cryptPass;
00222                 char salt[ 3 ];
00223 
00224                 // Unshuffling password
00225                 for( unsigned int i = 0; i < strlen( Password ); i++ )
00226                     Password[ i ] = ( (Password[ i ] & 0x0F) << 4 ) |
00227                                     ( (Password[ i ] & 0xF0) >> 4 );
00228 
00229                 salt[ 0 ] = localPassword[ 0 ];
00230                 salt[ 1 ] = localPassword[ 1 ];
00231                 salt[ 2 ] = 0;
00232                 cryptPass = crypt( Password, salt );
00233 
00234                 if( cryptPass == NULL )
00235                 {
00236                     if( m_log.is_open() )
00237                         m_log << "Invalid User/Password [Failed to encrypt "
00238                               << "user " << UserName << " password!]"
00239                               << endl;
00240 
00241                     return ERROR_USERMANAGER + ERROR_MEMORY;
00242                 }
00243 
00244                 if( strcmp( localPassword, cryptPass ) != 0 )
00245                 {
00246                     if( m_log.is_open() )
00247                         m_log << "Invalid User/Password " << name << endl;
00248 
00249                     return ERROR_USERMANAGER + ERROR_INVALID_USER;
00250                 }
00251             }
00252             else
00253             {
00254                 if( m_log.is_open() )
00255                     m_log << "Invalid User/Password " << name << endl;
00256 
00257                 return ERROR_USERMANAGER + ERROR_INVALID_USER;
00258             }
00259         }
00260         else
00261         {
00262             // Libera o mutex para acessar o arquivo de modo exclusivo.
00263             m_Mutex->Release();
00264 
00265             if( m_log.is_open() )
00266                 m_log << "Invalid User/Password [Failed to open "
00267                       << m_PasswdFileName << " file (errno=" << errno
00268                       << ",strerr=" << strerror( errno ) << ")!]" << endl;
00269 
00270             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00271         }
00272     }
00273 
00274     // Verifica se o diretorio do usuario existe
00275     strcpy( name, m_FileRoot );
00276     strcat( name, "/" );
00277     strcat( name, UserName );
00278 
00279     result = stat( name, &mystat );
00280 
00281     if( ( result == 0 ) && ( !S_ISDIR( mystat.st_mode ) ) )
00282     {
00283         if( m_log.is_open() )
00284             m_log << "Invalid User/Password [" << name << " is not a directory!"
00285                   << "]" << endl;
00286 
00287         return ERROR_USERMANAGER + ERROR_INVALID_USER_DIRECTORY;
00288     }
00289     else if( result != 0 )
00290     {
00291         if( m_log.is_open() )
00292             m_log << "Invalid User/Password [stat for file " << name
00293                   << " returned error " << errno << " (" << strerror( errno )
00294                   << ")!]" << endl;
00295 
00296         return ERROR_USERMANAGER + ERROR_INVALID_USER_DIRECTORY;
00297     }
00298 
00299     newuser->user_home = new char[strlen( UserName ) + 1];
00300     if( newuser->user_home == 0 )
00301     {
00302         delete newuser;
00303         if( m_log.is_open() )
00304             m_log << " Error when allocating home user string path! "
00305                   << UserName << endl;
00306 
00307         return ERROR_USERMANAGER + ERROR_MEMORY;
00308     }
00309 
00310     newuser->user = new char[strlen( UserName ) + 1];
00311     if( newuser->user == 0 )
00312     {
00313         delete[] newuser->user_home;
00314         delete newuser;
00315         if( m_log.is_open() )
00316             m_log << " Error when allocating user string! "
00317                   << UserName << endl;
00318 
00319         return ERROR_USERMANAGER + ERROR_MEMORY;
00320     }
00321 
00322     strcpy( newuser->user_home, UserName );
00323     strcpy( newuser->user, UserName );
00324 
00325     #ifdef RIO_DEBUG2
00326     if( m_log.is_open() )
00327         m_log << "User " << newuser->user_home << " log on." << endl;
00328     #endif
00329 
00330     // - permissions/capabilities
00331     *User = newuser;
00332 
00333     return S_OK;
00334 }

int CUserManager::RemoveUser ( char *  UserName  ) 

Nova funcao para remover um dos usuarios do RIO.

Parameters:
UserName ponteiro para o nome do usuario.
Returns:
S_OK se o usuario foi removido com sucesso ou o codigo de erro caso nao tenha sido possivel remover o usuario.

Definition at line 545 of file UserManager.cpp.

00546 {
00547     char localUserName[ MaxPathSize ];
00548     char localPassword[ MaxPathSize ];
00549     int TotalFields;
00550     // Armazena o nome do arquivo temporario.
00551     char NewFileName[ MaxPathSize ];
00552 
00553     // Variavel com o descritor do arquivo a ser aberto.
00554     FILE *PassFile;
00555     FILE *NewPassFile;
00556 
00557     if( ( strlen( UserName ) == 0 ) && ( strcmp( UserName, "guest" ) == 0 ) )
00558     {
00559         if( m_log.is_open() )
00560             m_log << " Invalid User " << UserName << endl;
00561 
00562         return ERROR_USERMANAGER + ERROR_INVALID_USER;
00563     }
00564 
00565     // Define o nome do novo arquivo (fiz isso para evitar dependencia do /tmp).
00566     strcpy( NewFileName, m_PasswdFileName );
00567     strcat( NewFileName, "." );
00568     strcat( NewFileName, "new" );
00569 
00570     // Espera tenta obter o mutex para acessar o arquivo de modo exclusivo.
00571     m_Mutex->Wait();
00572 
00573     // Tenta abrir o arquivo para a leitura.
00574     PassFile = fopen( m_PasswdFileName, "r" );
00575     if( PassFile != NULL )
00576     {
00577         while( ( TotalFields = fscanf( PassFile, "%s %s",
00578                                        localUserName, localPassword ) )
00579                                        != EOF )
00580         {
00581             if( ( TotalFields == 2) &&
00582                 ( strcmp( localUserName, UserName ) == 0  ) )
00583                 break;
00584             else if( TotalFields == 1 )
00585             {
00586                 // A linha nao possui a senha. Note que se TotalFiels
00587                 // for 0, isso provavelmente indica uma linha vazia.
00588                 if( m_log.is_open() )
00589                     m_log << "User " << localUserName << " in file "
00590                           <<  m_PasswdFileName << " ignored because "
00591                           << "does not have a password!"<< endl;
00592 
00593             }
00594         }
00595 
00596         // Verifica se ocorreu algum erro ao acessar o arquivo (o scanf
00597         // pode ser abortado por fim do arquivo ou por um erro ao
00598         // acessar o arquivo).
00599         if( errno != 0 )
00600         {
00601             // Fecha o arquivo aberto.
00602             fclose( PassFile );
00603 
00604             // Se o usuario existir, entao devemos retornar um erro.
00605             // Libera o mutex para acessar o arquivo de modo exclusivo.
00606             m_Mutex->Release();
00607 
00608             // Eu acho que podemos gerar somente um aviso, pois e
00609             // possivel que tenhamos conseguido achar com sucesso o
00610             // usuario no arquivo.
00611             if( m_log.is_open() )
00612                 m_log << "Error " << errno << " (" << strerror( errno )
00613                       << ") when reading password file "
00614                       <<  m_PasswdFileName << "!"<< endl;
00615 
00616             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00617         }
00618 
00619         // Verifica se nao achamos nenhum usuario.
00620         if( strcmp( localUserName, UserName ) != 0 )
00621         {
00622             // Fecha o arquivo aberto.
00623             fclose( PassFile );
00624 
00625             // Se o usuario nao existir, entao devemos retornar um erro.
00626             // Libera o mutex para acessar o arquivo de modo exclusivo.
00627             m_Mutex->Release();
00628 
00629            if( m_log.is_open() )
00630                m_log << " User " << UserName << "not found!" << endl;
00631 
00632            return ERROR_USERMANAGER + ERROR_INVALID_USER;
00633         }
00634 
00635         // Posiciona o arquivo de senhas na primeira linha (o inicio do
00636         // arquivo).
00637         if( fseek( PassFile, 0, SEEK_SET ) < 0 )
00638         {
00639             // Fecha o arquivo aberto.
00640             fclose( PassFile );
00641 
00642             // Se o usuario existir, entao devemos retornar um erro.
00643             // Libera o mutex para acessar o arquivo de modo exclusivo.
00644             m_Mutex->Release();
00645 
00646             if( m_log.is_open() )
00647                 m_log << "Invalid User/Password [Failed to seek in "
00648                       << m_PasswdFileName << " file (errno=" << errno
00649                       << ",strerr=" << strerror( errno ) << ")!]"
00650                       << endl;
00651 
00652             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00653 
00654         }
00655 
00656         // Abre o novo arquivo para escrita, sobreescrevendo-o se ele ja
00657         // existir.
00658         NewPassFile = fopen( NewFileName, "w+" );
00659         if( NewPassFile == NULL )
00660         {
00661             // Fecha o arquivo aberto.
00662             fclose( PassFile );
00663 
00664             // Libera o mutex para acessar o arquivo de modo exclusivo.
00665             m_Mutex->Release();
00666 
00667             if( m_log.is_open() )
00668                 m_log << "Invalid User/Password [Failed to open "
00669                       << m_PasswdFileName << " file (errno=" << errno
00670                       << ",strerr=" << strerror( errno ) << ")!]" << endl;
00671 
00672             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00673         }
00674 
00675         // Copia todas as linhas do arquivo de senhas, com excecao da linha com
00676         // o usuario removido.
00677         while( ( TotalFields = fscanf( PassFile, "%s %s",
00678                                        localUserName, localPassword ) )
00679                                        != EOF )
00680         {
00681             if( ( TotalFields > 0 ) &&
00682                 ( strcmp( localUserName, UserName ) != 0  ) )
00683             {
00684                  // Como nao e o usuario procurado, copiamos a linha para o novo
00685                  // arquivo (mesmo com um erro).
00686 
00687                  // Se nao existe a senha, a inicializamos com a string vazia.
00688                  if( TotalFields == 1 )
00689                      strcmp( localPassword, "" );
00690 
00691                  // Salva a linha no novo arquivo.
00692                  // Altera a senha do usuario.
00693                  if( fprintf( NewPassFile, "%s %s\n", localUserName,
00694                               localPassword ) < 0 )
00695                  {
00696                      // Fecha o arquivo aberto das novas senhas.
00697                      fclose( NewPassFile );
00698 
00699                      // Fecha o arquivo aberto.
00700                      fclose( PassFile );
00701 
00702                         // Libera o mutex para acessar o arquivo de modo exclusivo.
00703                     m_Mutex->Release();
00704 
00705                     if( m_log.is_open() )
00706                          m_log << "Invalid User/Password [Failed to save new "
00707                                << "user " << UserName << "password in "
00708                                << m_PasswdFileName << " file (errno=" << errno
00709                                << ",strerr=" << strerror( errno ) << ")!]"
00710                                << endl;
00711 
00712                      return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00713                  }
00714             }
00715         }
00716 
00717         // Verifica se ocorreu algum erro ao acessar o arquivo (o scanf
00718         // pode ser abortado por fim do arquivo ou por um erro ao
00719         // acessar o arquivo).
00720         if( errno != 0 )
00721         {
00722             // Fecha o arquivo aberto das novas senhas.
00723             fclose( NewPassFile );
00724 
00725             // Fecha o arquivo aberto.
00726             fclose( PassFile );
00727 
00728             // Remove o arquivo criado.
00729             remove( NewFileName );
00730 
00731             // Se o usuario existir, entao devemos retornar um erro.
00732             // Libera o mutex para acessar o arquivo de modo exclusivo.
00733             m_Mutex->Release();
00734 
00735             // Eu acho que podemos gerar somente um aviso, pois e
00736             // possivel que tenhamos conseguido achar com sucesso o
00737             // usuario no arquivo.
00738             if( m_log.is_open() )
00739                 m_log << "Error " << errno << " (" << strerror( errno )
00740                       << ") when reading password file "
00741                       <<  m_PasswdFileName << "!"<< endl;
00742 
00743             return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00744         }
00745 
00746         // Fecha o arquivo aberto das novas senhas.
00747         fclose( NewPassFile );
00748 
00749         // Fecha o arquivo aberto.
00750         fclose( PassFile );
00751 
00752         // Remove o arquivo antigo.
00753         remove( m_PasswdFileName );
00754 
00755         // Move o arquivo novo criado para o arquivo original.
00756         rename( NewFileName, m_PasswdFileName );
00757 
00758         // Libera o mutex para acessar o arquivo de modo exclusivo.
00759         m_Mutex->Release();
00760     }
00761     else
00762     {
00763         // Libera o mutex para acessar o arquivo de modo exclusivo.
00764         m_Mutex->Release();
00765 
00766         if( m_log.is_open() )
00767             m_log << "Invalid User/Password [Failed to open "
00768                   << m_PasswdFileName << " file (errno=" << errno
00769                   << ",strerr=" << strerror( errno ) << ")!]" << endl;
00770 
00771         return ERROR_USERMANAGER + ERROR_RIOPASSWORD_FILE;
00772     }
00773 
00774     return S_OK;
00775 }


Field Documentation

char* CUserManager::m_FileRoot [private]

Definition at line 45 of file UserManager.h.

Definition at line 49 of file UserManager.h.

Definition at line 102 of file UserManager.h.

Definition at line 48 of file UserManager.h.

char CUserManager::m_PasswdFileName[MaxPathSize] [private]

Definition at line 52 of file UserManager.h.

char* CUserManager::m_UserRoot [private]

Definition at line 44 of file UserManager.h.


The documentation for this class was generated from the following files:
Generated on Wed Jul 4 16:03:34 2012 for RIO by  doxygen 1.6.3