11 files changed, 270 insertions, 36 deletions
diff --git a/noncore/settings/networksettings2/activateprofile.cpp b/noncore/settings/networksettings2/activateprofile.cpp index ba726bb..e4064e3 100644 --- a/noncore/settings/networksettings2/activateprofile.cpp +++ b/noncore/settings/networksettings2/activateprofile.cpp @@ -1,3 +1,4 @@ #include <qlistbox.h> +#include <qlabel.h> #include "activateprofile.h" @@ -7,4 +8,5 @@ ActivateProfile::ActivateProfile( const char * Interface ) : Possible = NSD.collectPossible( Interface ); + DeviceName_LBL->setText( Interface ); Profiles_LB->clear(); for( NodeCollection * NC = Possible.first(); diff --git a/noncore/settings/networksettings2/activateprofileGUI.ui b/noncore/settings/networksettings2/activateprofileGUI.ui index 296e044..12ab051 100644 --- a/noncore/settings/networksettings2/activateprofileGUI.ui +++ b/noncore/settings/networksettings2/activateprofileGUI.ui @@ -18,5 +18,5 @@ <property stdset="1"> <name>caption</name> - <string>Activate Profile</string> + <string>Activate Network</string> </property> <property> @@ -58,5 +58,5 @@ <property stdset="1"> <name>text</name> - <string>Select profile for device :</string> + <string>Select profile to activate for </string> </property> </widget> diff --git a/noncore/settings/networksettings2/main.cpp b/noncore/settings/networksettings2/main.cpp index 7ec26a7..e2c00f6 100644 --- a/noncore/settings/networksettings2/main.cpp +++ b/noncore/settings/networksettings2/main.cpp @@ -2,4 +2,5 @@ #include "activateprofile.h" #include "networksettings.h" + #include <qpe/qpeapplication.h> @@ -77,5 +78,17 @@ int main( int argc, char * argv[] ) { case ACT_REQUEST : { NetworkSettingsData NS; - NS.canStart( argv[1] ); + if( NS.canStart( argv[1] ) ) { + QString S; + S.sprintf( QPEApplication::qpeDir()+ + "/bin/networksettings2" ); + char * MyArgv[4]; + MyArgv[0] = "networksettings2"; + MyArgv[1] = "--prompt"; + MyArgv[2] = argv[1]; + MyArgv[3] = NULL; + NSResources->system().execAsUser( S, MyArgv ); + // if we come here , failed + printf( "%s-cNN-disallowed", argv[1] ); + } } break; diff --git a/noncore/settings/networksettings2/network/network_NNI.cpp b/noncore/settings/networksettings2/network/network_NNI.cpp index 054385a..3e368a2 100644 --- a/noncore/settings/networksettings2/network/network_NNI.cpp +++ b/noncore/settings/networksettings2/network/network_NNI.cpp @@ -110,21 +110,42 @@ bool ANetwork::generateDataForCommonFile( SystemFile & S, long DevNr ) { // we can safely call from here since device item is deeper if( Data.UseDHCP ) { - S << "iface " << NIC << "-c" << connection()->number() << - "-allowed inet dhcp" << endl; - S << " up echo \"" << NIC << "\" > /tmp/profile-" << connection()->number() << - ".up" << Data.IPAddress << endl; + S << "iface " + << NIC + << "-c" + << connection()->number() + << "-allowed inet dhcp" + << endl; + S << " up echo \"" + << NIC + << "\" > /tmp/profile-" + << connection()->number() + << ".up" + << endl; if( Data.SendHostname ) { - S << " hostname "<< Data.Hostname << endl; + S << " hostname " + << Data.Hostname + << endl; } - S << " down rm -f /tmp/profile-" << connection()->number() << - ".up" << Data.IPAddress << endl; + S << " down rm -f /tmp/profile-" + << connection()->number() + << ".up" + << endl; } else { - S << "iface " << NIC << "-c" << connection()->number() << - "-allowed inet static" << endl; - S << " up echo \"" << NIC << "\" > /tmp/profile-" << connection()->number() << - ".up" << Data.IPAddress << endl; - S << " down rm -f /tmp/profile-" << connection()->number() << - ".up" << Data.IPAddress << endl; + S << "iface " + << NIC << "-c" + << connection()->number() + << "-allowed inet static" + << endl; + S << " up echo \"" + << NIC + << "\" > /tmp/profile-" + << connection()->number() + << ".up" + << endl; + S << " down rm -f /tmp/profile-" + << connection()->number() + << ".up" + << endl; S << " address " << Data.IPAddress << endl; S << " broadcast " << Data.Broadcast << endl; diff --git a/noncore/settings/networksettings2/network/networkrun.cpp b/noncore/settings/networksettings2/network/networkrun.cpp index ddb9a5f..c19235a 100644 --- a/noncore/settings/networksettings2/network/networkrun.cpp +++ b/noncore/settings/networksettings2/network/networkrun.cpp @@ -31,5 +31,5 @@ bool NetworkRun::setState( NodeCollection * NC, Action_t A ) { II->Name.latin1(), II->Name.latin1(), connection()->number() ); - NSResources->system().execute( S ); + NSResources->system().runAsRoot( S ); } return 1; @@ -40,5 +40,5 @@ bool NetworkRun::setState( NodeCollection * NC, Action_t A ) { II->Name.latin1(), II->Name.latin1(), connection()->number() ); - NSResources->system().execute( S ); + NSResources->system().runAsRoot( S ); } return 1; diff --git a/noncore/settings/networksettings2/networksettings2/resources.cpp b/noncore/settings/networksettings2/networksettings2/resources.cpp index 0301361..e6ce2b7 100644 --- a/noncore/settings/networksettings2/networksettings2/resources.cpp +++ b/noncore/settings/networksettings2/networksettings2/resources.cpp @@ -1,6 +1,10 @@ +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <pwd.h> #include <qpixmap.h> +#include <qdir.h> #include <qpe/qlibrary.h> #include <qpe/qpeapplication.h> -#include <qdir.h> #include <opie2/odebug.h> #include <qtopia/resource.h> @@ -76,4 +80,6 @@ TheNSResources::TheNSResources( void ) : NodeTypeNameMap(), // get access to the system TheSystem = new System(); + + detectCurrentUser(); } @@ -233,2 +239,131 @@ void TheNSResources::renumberConnections( void ) { } } + +typedef struct EnvVars { + char * Name; + int Len; +} EnvVar_t; + +#define AnEV(x) x, sizeof(x)-1 + +static EnvVar_t EV[] = { + // AnEV( "HOME=" ), -> SPECIAL + // AnEV( "LOGNAME=" ), -> SPECIAL + AnEV( "USER=" ), + AnEV( "LD_LIBRARY_PATH=" ), + AnEV( "PATH=" ), + AnEV( "QTDIR=" ), + AnEV( "OPIEDIR=" ), + AnEV( "SHELL=" ), + { NULL, 0 } +}; + +void TheNSResources::detectCurrentUser( void ) { + // find current running qpe + QString QPEEnvFile = ""; + + // open proc dir and find all dirs in it + { QRegExp R("[0-9]+"); + QDir ProcDir( "/proc" ); + QString QPELoc = QPEApplication::qpeDir() + "bin/qpe"; + QFileInfo FI; + QStringList EL = ProcDir.entryList( QDir::Dirs ); + + // print it out + for ( QStringList::Iterator it = EL.begin(); + it != EL.end(); + ++it ) { + if( R.match( (*it) ) >= 0 ) { + QString S = ProcDir.path()+"/"+ (*it); + S.append( "/exe" ); + FI.setFile( S ); + // get the linke + S = FI.readLink(); + if( S == QPELoc ) { + // found running qpe + QPEEnvFile.sprintf( ProcDir.path()+ "/" + (*it) + "/environ" ); + break; + } + } + } + } + + if( QPEEnvFile.isEmpty() ) { + // could not find qpe + fprintf( stderr, "Could not find qpe\n" ); + return; + } + + // FI now contains path ProcDir to the cmd dir + { char * Buf = 0; + char TB[1024]; + long BufSize = 0; + int fd; + int rd; + + fd = open( QPEEnvFile.latin1(), O_RDONLY ); + if( fd < 0 ) { + fprintf( stderr, "Could not open %s : %d\n", + QPEEnvFile.latin1(), errno ); + return; + } + + while( (rd = read( fd, TB, sizeof(TB) ) ) > 0 ) { + Buf = (char *)realloc( Buf, BufSize+rd ); + memcpy( Buf+BufSize, TB, rd ); + BufSize += rd; + } + + char * Data = Buf; + char * DataEnd = Data+BufSize-1; + + // get env items out of list + while( Data < DataEnd ) { + if( strncmp( Data, "LOGNAME=", 8 ) == 0 ) { + CurrentUser.UserName = Data+8; + CurrentUser.EnvList.resize( CurrentUser.EnvList.size()+1 ); + CurrentUser.EnvList[CurrentUser.EnvList.size()-1] = + strdup( Data ); + } else if( strncmp( Data, "HOME=", 5 ) == 0 ) { + CurrentUser.HomeDir = Data+5; + CurrentUser.EnvList.resize( CurrentUser.EnvList.size()+1 ); + CurrentUser.EnvList[CurrentUser.EnvList.size()-1] = + strdup( Data ); + } else { + EnvVar_t * Run = EV; + while( Run->Name ) { + if( strncmp( Data, Run->Name, Run->Len ) == 0 ) { + CurrentUser.EnvList.resize( CurrentUser.EnvList.size()+1 ); + CurrentUser.EnvList[CurrentUser.EnvList.size()-1] = + strdup( Data ); + break; + } + Run ++; + } + } + + Data += strlen( Data )+1; + } + + free( Buf ); + + if( ! CurrentUser.UserName.isEmpty() ) { + // find user info + struct passwd pwd; + struct passwd * pwdres; + + if( getpwnam_r( CurrentUser.UserName.latin1(), + &pwd, TB, sizeof(TB), &pwdres ) || + pwdres == 0 ) { + fprintf( stderr, "Could not determine user %s : %d\n", + CurrentUser.UserName.latin1(), errno ); + return; + } + CurrentUser.Uid = pwd.pw_uid; + CurrentUser.Gid = pwd.pw_gid; + } else{ + CurrentUser.Uid = + CurrentUser.Gid = -1; + } + } +} diff --git a/noncore/settings/networksettings2/networksettings2/resources.h b/noncore/settings/networksettings2/networksettings2/resources.h index 4df3ce3..3048fb3 100644 --- a/noncore/settings/networksettings2/networksettings2/resources.h +++ b/noncore/settings/networksettings2/networksettings2/resources.h @@ -23,4 +23,16 @@ typedef struct NetNode_S { } NetNode_t; +class CurrentQPEUser { + +public : + CurrentQPEUser() : UserName(), HomeDir(), EnvList() {} + + QString UserName; + QString HomeDir; + int Uid; + int Gid; + QArray<char *> EnvList; +}; + typedef QDict<NetNode_t> Name2NetNode_t; typedef QDict<ANetNodeInstance > Name2Instance_t; @@ -84,6 +96,10 @@ public : { return ConnectionsMap; } + CurrentQPEUser & currentUser( void ) + { return CurrentUser; } + private : + void detectCurrentUser( void ); QString tr( const char * path ); void findAvailableNetNodes( const QString &path ); @@ -103,4 +119,6 @@ private : // all nodes Name2Instance_t AllNodes; + + CurrentQPEUser CurrentUser; }; diff --git a/noncore/settings/networksettings2/networksettings2/system.cpp b/noncore/settings/networksettings2/networksettings2/system.cpp index a68f3c0..2133d34 100644 --- a/noncore/settings/networksettings2/networksettings2/system.cpp +++ b/noncore/settings/networksettings2/networksettings2/system.cpp @@ -1,7 +1,5 @@ -#include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> -#include <qfile.h> -#include <qtextstream.h> + #include <net/if.h> #include <net/if_arp.h> @@ -10,4 +8,14 @@ #include <sys/ioctl.h> #include <sys/socket.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> + +#include <qdir.h> +#include <qregexp.h> +#include <qstringlist.h> +#include <qfile.h> +#include <qtextstream.h> #include "resources.h" @@ -37,5 +45,5 @@ System::~System( void ) { } -int System::execute( const QString & S ) { +int System::runAsRoot( const QString & S ) { QString MyS = S; char * usr = getenv("USER"); @@ -319,2 +327,29 @@ void System::probeInterfaces( void ) { } } + +void System::execAsUser( QString & Cmd, char * argv[] ) { + CurrentQPEUser CU = NSResources->currentUser(); + + if( CU.UserName.isEmpty() ) { + // if we come here, the exec was not successfull + fprintf( stderr, "User not known \n" ); + return; + } + + // now we are ready to exec the requested command + setuid( CU.Uid ); + setgid( CU.Gid ); + + char ** envp = (char **)alloca( sizeof( char *) * + (CU.EnvList.count()+1) ); + + for( unsigned int i = 0 ; i < CU.EnvList.count() ; i ++ ) { + *(envp+i) = CU.EnvList[i]; + } + envp[CU.EnvList.count()]=NULL; + + execve( Cmd.latin1(), argv, envp ); + + // if we come here, the exec was not successfull + fprintf( stderr, "Could not exec : %d\n", errno ); +} diff --git a/noncore/settings/networksettings2/networksettings2/system.h b/noncore/settings/networksettings2/networksettings2/system.h index f89fe5d..96ee9bd 100644 --- a/noncore/settings/networksettings2/networksettings2/system.h +++ b/noncore/settings/networksettings2/networksettings2/system.h @@ -60,5 +60,10 @@ public : { return ProbedInterfaces[N]; } - int execute( const QString & S ); + // exec command as root + int runAsRoot( const QString & S ); + + // exec command as user + void execAsUser( QString & Cmd, char * argv[] ); + // refresh stats for this interface void refreshStatistics( InterfaceInfo & ); diff --git a/noncore/settings/networksettings2/nsdata.cpp b/noncore/settings/networksettings2/nsdata.cpp index eb63e02..b4d9aaa 100644 --- a/noncore/settings/networksettings2/nsdata.cpp +++ b/noncore/settings/networksettings2/nsdata.cpp @@ -16,5 +16,7 @@ NetworkSettingsData::NetworkSettingsData( void ) { new TheNSResources(); - CfgFile.sprintf( "%s/NETCONFIG", getenv("HOME") ); + CfgFile.sprintf( "%s/NETCONFIG", + NSResources->currentUser().HomeDir.latin1() ); + fprintf( stderr, "Cfg from %s\n", CfgFile.latin1() ); // load settings @@ -354,8 +356,10 @@ QList<NodeCollection> NetworkSettingsData::collectPossible( const char * Interfa NC = it.current(); // check if this profile handles the requested interface + fprintf( stderr, "check %s\n", NC->name().latin1() ); if( NC->handlesInterface( Interface ) && // if different Intf. NC->state() != Disabled && // if not enabled NC->state() != IsUp // if already used ) { + fprintf( stderr, "Append %s\n", NC->name().latin1() ); PossibleConnections.append( NC ); } @@ -371,5 +375,5 @@ QList<NodeCollection> NetworkSettingsData::collectPossible( const char * Interfa */ -void NetworkSettingsData::canStart( const char * Interface ) { +bool NetworkSettingsData::canStart( const char * Interface ) { // load situation NodeCollection * NC = 0; @@ -378,4 +382,6 @@ void NetworkSettingsData::canStart( const char * Interface ) { PossibleConnections = collectPossible( Interface ); + fprintf( stderr, "Possiblilies %d\n", + PossibleConnections.count() ); switch( PossibleConnections.count() ) { case 0 : // no connections @@ -385,8 +391,5 @@ void NetworkSettingsData::canStart( const char * Interface ) { break; default : // need to ask user ? - // are we connected to a server - // system( "su %d networksettings2 --prompt %s\n", - // "", Interface ); - break; + return 1; } @@ -411,10 +414,11 @@ void NetworkSettingsData::canStart( const char * Interface ) { // device is ready -> done printf( "%s-c%d-allowed\n", Interface, NC->number() ); - return; + return 0; } - } else { - // if we come here no alternatives are possible - printf( "%s-cnn-disallowed\n", Interface ); - } + } + + // if we come here no alternatives are possible + printf( "%s-cnn-disallowed\n", Interface ); + return 0; } diff --git a/noncore/settings/networksettings2/nsdata.h b/noncore/settings/networksettings2/nsdata.h index b54df24..eb96930 100644 --- a/noncore/settings/networksettings2/nsdata.h +++ b/noncore/settings/networksettings2/nsdata.h @@ -22,5 +22,6 @@ public : QList<NodeCollection> collectPossible( const char * Interface ); - void canStart( const char * Interface ); + // return TRUE if we need gui to decide + bool canStart( const char * Interface ); bool regenerate( void ); |