ref: refs/heads/ma-misc
commit a16adb004b0e20e84a5ab16a4d04d2e5fa48b8e8
Author: Michael Andres
Date: Sat Oct 31 17:49:22 2009 +0100
MediaSMB and MediaCIFS are the same, so use CIFS everywhere and dop SMB
---
zypp/CMakeLists.txt | 2 -
zypp/media/MediaAccess.cc | 7 +-
zypp/media/MediaCIFS.cc | 461 +++++++++++++++++++++++++++++++++++++++++++-
zypp/media/MediaCIFS.h | 41 +++--
zypp/media/MediaSMB.cc | 470 ---------------------------------------------
zypp/media/MediaSMB.h | 78 --------
6 files changed, 487 insertions(+), 572 deletions(-)
diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt
index 40973fc..bbceaa3 100644
--- a/zypp/CMakeLists.txt
+++ b/zypp/CMakeLists.txt
@@ -260,7 +260,6 @@ SET( zypp_media_SRCS
media/MediaCD.cc
media/MediaDIR.cc
media/MediaDISK.cc
- media/MediaSMB.cc
media/MediaCIFS.cc
media/ProxyInfo.cc
media/MediaCurl.cc
@@ -289,7 +288,6 @@ SET( zypp_media_HEADERS
media/MediaISO.h
media/MediaManager.h
media/MediaNFS.h
- media/MediaSMB.h
media/MediaSource.h
media/MediaUserAuth.h
media/Mount.h
diff --git a/zypp/media/MediaAccess.cc b/zypp/media/MediaAccess.cc
index cff2d01..7ed6af5 100644
--- a/zypp/media/MediaAccess.cc
+++ b/zypp/media/MediaAccess.cc
@@ -25,7 +25,6 @@
#include "zypp/media/MediaCD.h"
#include "zypp/media/MediaDIR.h"
#include "zypp/media/MediaDISK.h"
-#include "zypp/media/MediaSMB.h"
#include "zypp/media/MediaCIFS.h"
#include "zypp/media/MediaCurl.h"
#include "zypp/media/MediaAria2c.h"
@@ -123,10 +122,8 @@ MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
_handler = new MediaDIR (url,preferred_attach_point);
else if (scheme == "hd")
_handler = new MediaDISK (url,preferred_attach_point);
- else if (scheme == "smb")
- _handler = new MediaSMB (url,preferred_attach_point);
- else if (scheme == "cifs")
- _handler = new MediaCIFS (url,preferred_attach_point);
+ else if (scheme == "cifs" || scheme == "smb")
+ _handler = new MediaCIFS (url,preferred_attach_point);
else if (scheme == "ftp" || scheme == "http" || scheme == "https")
{
// Another good idea would be activate MediaAria2c handler via external var
diff --git a/zypp/media/MediaCIFS.cc b/zypp/media/MediaCIFS.cc
index f4f2133..7d5215e 100644
--- a/zypp/media/MediaCIFS.cc
+++ b/zypp/media/MediaCIFS.cc
@@ -10,7 +10,460 @@
*
*/
-//
-// NOTE: It's actually MediaSMB, but using "cifs"
-// as vfstype for mount.
-//
+#include <iostream>
+#include <fstream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/base/Gettext.h"
+#include "zypp/TmpPath.h"
+#include "zypp/KVMap.h"
+#include "zypp/media/Mount.h"
+#include "zypp/media/MediaUserAuth.h"
+#include "zypp/media/CredentialManager.h"
+#include "zypp/ZYppCallbacks.h"
+
+#warning FIXME: get rid of this dependency on Target
+#include "zypp/ZYppFactory.h" // for target->root()
+#include "zypp/Target.h" // for zypp->target->root()
+
+#include "zypp/media/MediaCIFS.h"
+
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+namespace zypp {
+ namespace media {
+
+ /******************************************************************
+ **
+ **
+ ** FUNCTION NAME : getShare
+ ** FUNCTION TYPE : inline Pathname
+ **
+ ** Get the 1st path component (CIFS share name).
+ */
+ inline string getShare( Pathname spath_r )
+ {
+ if ( spath_r.empty() )
+ return string();
+
+ string share( spath_r.absolutename().asString() );
+ string::size_type sep = share.find( "/", 1 );
+ if ( sep == string::npos )
+ share = share.erase( 0, 1 ); // nothing but the share name in spath_r
+ else
+ share = share.substr( 1, sep-1 );
+
+ // deescape %2f in sharename
+ while ( (sep = share.find( "%2f" )) != string::npos ) {
+ share.replace( sep, 3, "/" );
+ }
+
+ return share;
+ }
+
+ /******************************************************************
+ **
+ **
+ ** FUNCTION NAME : stripShare
+ ** FUNCTION TYPE : inline Pathname
+ **
+ ** Strip off the 1st path component (CIFS share name).
+ */
+ inline Pathname stripShare( Pathname spath_r )
+ {
+ if ( spath_r.empty() )
+ return Pathname();
+
+ string striped( spath_r.absolutename().asString() );
+ string::size_type sep = striped.find( "/", 1 );
+ if ( sep == string::npos )
+ return "/"; // nothing but the share name in spath_r
+
+ return striped.substr( sep );
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : MediaCIFS
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ //
+ // METHOD NAME : MediaCIFS::MediaCIFS
+ // METHOD TYPE : Constructor
+ //
+ // DESCRIPTION :
+ //
+ MediaCIFS::MediaCIFS( const Url & url_r,
+ const Pathname & attach_point_hint_r )
+ : MediaHandler( url_r, attach_point_hint_r,
+ stripShare( url_r.getPathName() ), // urlpath WITHOUT share name at attachpoint
+ false ) // does_download
+ {
+ MIL << "MediaCIFS::MediaCIFS(" << url_r << ", " << attach_point_hint_r << ")" << endl;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ //
+ // METHOD NAME : MediaCIFS::attachTo
+ // METHOD TYPE : PMError
+ /**
+ * Asserted that not already attached, and attachPoint is a directory.
+ *
+ * Authentication: credentials can be specified in the following few ways
+ * (the first has the highest preference).
+ * - URL username:password
+ * - mountoptions URL query parameter (see man mount.cifs)
+ * - CredentialManager - either previously saved credentials will be used
+ * or the user will be promted for them via AuthenticationReport callback.
+ *
+ * \note The implementation currently serves both, "smb" and
+ * and "cifs" URL's, but passes "cifs" to the mount command
+ * in any case.
+ */
+ void MediaCIFS::attachTo(bool next)
+ {
+ if(_url.getHost().empty())
+ ZYPP_THROW(MediaBadUrlEmptyHostException(_url));
+ if(next)
+ ZYPP_THROW(MediaNotSupportedException(_url));
+
+ string path = "//";
+ path += _url.getHost() + "/" + getShare( _url.getPathName() );
+
+ MediaSourceRef media( new MediaSource( "cifs", path));
+ AttachedMedia ret( findAttachedMedia( media));
+
+ if( ret.mediaSource &&
+ ret.attachPoint &&
+ !ret.attachPoint->empty())
+ {
+ DBG << "Using a shared media "
+ << ret.mediaSource->name
+ << " attached on "
+ << ret.attachPoint->path
+ << endl;
+
+ removeAttachPoint();
+ setAttachPoint(ret.attachPoint);
+ setMediaSource(ret.mediaSource);
+ return;
+ }
+
+ std::string mountpoint = attachPoint().asString();
+ if( !isUseableAttachPoint(attachPoint()))
+ {
+ mountpoint = createAttachPoint().asString();
+ if( mountpoint.empty())
+ ZYPP_THROW( MediaBadAttachPointException(url()));
+ setAttachPoint( mountpoint, true);
+ }
+
+ Mount mount;
+ CredentialManager cm;
+
+ Mount::Options options( _url.getQueryParam("mountoptions") );
+ string username = _url.getUsername();
+ string password = _url.getPassword();
+
+ options["guest"]; // prevent smbmount from asking for password
+
+ if ( ! options.has( "rw" ) ) {
+ options["ro"];
+ }
+
+ // look for a workgroup
+ string workgroup = _url.getQueryParam("workgroup");
+ if ( workgroup.empty() )
+ workgroup = _url.getQueryParam("domain");
+ if ( !workgroup.empty() )
+ options["domain"] = workgroup;
+
+ // extract 'username', do not overwrite any _url.username
+
+ Mount::Options::iterator toEnv;
+ toEnv = options.find("username");
+ if ( toEnv != options.end() ) {
+ if ( username.empty() )
+ username = toEnv->second;
+ options.erase( toEnv );
+ }
+
+ toEnv = options.find("user"); // actually cifs specific
+ if ( toEnv != options.end() ) {
+ if ( username.empty() )
+ username = toEnv->second;
+ options.erase( toEnv );
+ }
+
+ // extract 'password', do not overwrite any _url.password
+
+ toEnv = options.find("password");
+ if ( toEnv != options.end() ) {
+ if ( password.empty() )
+ password = toEnv->second;
+ options.erase( toEnv );
+ }
+
+ toEnv = options.find("pass"); // actually cifs specific
+ if ( toEnv != options.end() ) {
+ if ( password.empty() )
+ password = toEnv->second;
+ options.erase( toEnv );
+ }
+
+ if ( username.empty() || password.empty() )
+ {
+ AuthData_Ptr c = cm.getCred(_url);
+ if (c)
+ {
+ username = c->username();
+ password = c->password();
+ }
+ }
+
+ bool firstTry = true;
+ bool authRequired = false;
+ AuthData authdata;
+ do // repeat this while the mount returns "Permission denied" error
+ {
+ // get credentials from authenicate()
+ if ( !firstTry )
+ {
+ username = authdata.username();
+ password = authdata.password();
+ }
+
+ // pass 'username' and 'password' via environment
+ Mount::Environment environment;
+ if ( !username.empty() )
+ environment["USER"] = username;
+ if ( !password.empty() )
+ environment["PASSWD"] = password;
+
+ //////////////////////////////////////////////////////
+ // In case we need a tmpfile, credentials will remove
+ // it in it's destructor after the mout call below.
+ filesystem::TmpPath credentials;
+ if ( !username.empty() || !password.empty() )
+ {
+ filesystem::TmpFile tmp;
+ ofstream outs( tmp.path().asString().c_str() );
+ outs << "username=" << username << endl;
+ outs << "password=" << password << endl;
+ outs.close();
+
+ credentials = tmp;
+ options["credentials"] = credentials.path().asString();
+ }
+ //
+ //////////////////////////////////////////////////////
+
+ try
+ {
+ mount.mount( path, mountpoint, "cifs",
+ options.asString(), environment );
+ setMediaSource(media);
+ break;
+ }
+ catch (const MediaMountException & e)
+ {
+ ZYPP_CAUGHT( e );
+
+ if ( e.mountError() == "Permission denied" )
+ authRequired = authenticate( authdata, firstTry );
+ else
+ ZYPP_RETHROW( e );
+ }
+
+ firstTry = false;
+ }
+ while ( authRequired );
+
+ // wait for /etc/mtab update ...
+ // (shouldn't be needed)
+ int limit = 3;
+ bool mountsucceeded;
+ while( !(mountsucceeded=isAttached()) && --limit)
+ sleep(1);
+
+ if ( !mountsucceeded )
+ {
+ setMediaSource(MediaSourceRef());
+ try
+ {
+ mount.umount(attachPoint().asString());
+ }
+ catch (const MediaException & excpt_r)
+ {
+ ZYPP_CAUGHT(excpt_r);
+ }
+ ZYPP_THROW(MediaMountException(
+ "Unable to verify that the media was mounted",
+ path, mountpoint
+ ));
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : MediaCIFS::isAttached
+ // METHOD TYPE : bool
+ //
+ // DESCRIPTION : Override check if media is attached.
+ //
+ bool
+ MediaCIFS::isAttached() const
+ {
+ return checkAttached(true);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ //
+ // METHOD NAME : MediaCIFS::releaseFrom
+ // METHOD TYPE : PMError
+ //
+ // DESCRIPTION : Asserted that media is attached.
+ //
+ void MediaCIFS::releaseFrom( const std::string & ejectDev )
+ {
+ Mount mount;
+ mount.umount(attachPoint().asString());
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : MediaCIFS::getFile
+ // METHOD TYPE : PMError
+ //
+ // DESCRIPTION : Asserted that media is attached.
+ //
+ void MediaCIFS::getFile (const Pathname & filename) const
+ {
+ MediaHandler::getFile( filename );
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : MediaCIFS::getDir
+ // METHOD TYPE : PMError
+ //
+ // DESCRIPTION : Asserted that media is attached.
+ //
+ void MediaCIFS::getDir( const Pathname & dirname, bool recurse_r ) const
+ {
+ MediaHandler::getDir( dirname, recurse_r );
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ //
+ // METHOD NAME : MediaCIFS::getDirInfo
+ // METHOD TYPE : PMError
+ //
+ // DESCRIPTION : Asserted that media is attached and retlist is empty.
+ //
+ void MediaCIFS::getDirInfo( std::liststd::string & retlist,
+ const Pathname & dirname, bool dots ) const
+ {
+ MediaHandler::getDirInfo( retlist, dirname, dots );
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ //
+ // METHOD NAME : MediaCIFS::getDirInfo
+ // METHOD TYPE : PMError
+ //
+ // DESCRIPTION : Asserted that media is attached and retlist is empty.
+ //
+ void MediaCIFS::getDirInfo( filesystem::DirContent & retlist,
+ const Pathname & dirname, bool dots ) const
+ {
+ MediaHandler::getDirInfo( retlist, dirname, dots );
+ }
+
+ bool MediaCIFS::getDoesFileExist( const Pathname & filename ) const
+ {
+ return MediaHandler::getDoesFileExist( filename );
+ }
+
+ bool MediaCIFS::authenticate(AuthData & authdata, bool firstTry) const
+ {
+ //! \todo need a way to pass different CredManagerOptions here
+ Target_Ptr target = zypp::getZYpp()->getTarget();
+ CredentialManager cm(CredManagerOptions(target ? target->root() : ""));
+
+ // get stored credentials
+ AuthData_Ptr cmcred = cm.getCred(_url);
+
+ AuthData_Ptr smbcred;
+ smbcred.reset(new AuthData());
+ callback::SendReport<AuthenticationReport> auth_report;
+
+ // preset the username if present in current url
+ if (!_url.getUsername().empty() && firstTry)
+ smbcred->setUsername(_url.getUsername());
+ // if CM has found some credentials, preset the username from there
+ else if (cmcred)
+ smbcred->setUsername(cmcred->username());
+
+ // indicate we have no good credentials from CM
+ cmcred.reset();
+
+ string prompt_msg = str::form(
+ //!\todo add comma to the message for the next release
+ _("Authentication required for '%s'"), _url.asString().c_str());
+
+ // ask user
+ if (auth_report->prompt(_url, prompt_msg, *smbcred))
+ {
+ DBG << "callback answer: retry" << endl
+ << "AuthData: " << *smbcred << endl;
+
+ if (smbcred->valid())
+ {
+ cmcred = smbcred;
+ // if (credentials->username() != _url.getUsername())
+ // _url.setUsername(credentials->username());
+ /**
+ * \todo find a way to save the url with changed username
+ * back to repoinfo or dont store urls with username
+ * (and either forbid more repos with the same url and different
+ * user, or return a set of credentials from CM and try them one
+ * by one)
+ */
+ }
+ }
+ else
+ DBG << "callback answer: cancel" << endl;
+
+ // set username and password
+ if (cmcred)
+ {
+ authdata.setUsername(cmcred->username());
+ authdata.setPassword(cmcred->password());
+
+ // save the credentials
+ cmcred->setUrl(_url);
+ cm.addCred(*cmcred);
+ cm.save();
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ } // namespace media
+} // namespace zypp
diff --git a/zypp/media/MediaCIFS.h b/zypp/media/MediaCIFS.h
index f05b912..73affb4 100644
--- a/zypp/media/MediaCIFS.h
+++ b/zypp/media/MediaCIFS.h
@@ -12,36 +12,51 @@
#ifndef ZYPP_MEDIA_MEDIACIFS_H
#define ZYPP_MEDIA_MEDIACIFS_H
-#include "zypp/media/MediaSMB.h"
+#include "zypp/media/MediaHandler.h"
namespace zypp {
namespace media {
+ class AuthData;
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : MediaCIFS
/**
* @short Implementation class for CIFS MediaHandler
*
- * NOTE: It's actually MediaSMB, but using "cifs"
- * as vfstype for mount.
+ * NOTE: The implementation serves both, "smb" and "cifs" URL's,
+ * but passes "cifs" to the mount command in any case.
* @see MediaHandler
**/
- class MediaCIFS : public MediaSMB {
-
+ class MediaCIFS : public MediaHandler {
+
+ protected:
+
+ virtual void attachTo (bool next = false);
+ virtual void releaseFrom( const std::string & ejectDev );
+ virtual void getFile( const Pathname & filename ) const;
+ virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
+ virtual void getDirInfo( std::liststd::string & retlist,
+ const Pathname & dirname, bool dots = true ) const;
+ virtual void getDirInfo( filesystem::DirContent & retlist,
+ const Pathname & dirname, bool dots = true ) const;
+ virtual bool getDoesFileExist( const Pathname & filename ) const;
+
public:
-
MediaCIFS( const Url& url_r,
- const Pathname & attach_point_hint_r )
- : MediaSMB( url_r, attach_point_hint_r )
- {
- mountAsCIFS();
- }
+ const Pathname & attach_point_hint_r );
+
+ virtual ~MediaCIFS() { try { release(); } catch(...) {} }
+
+ virtual bool isAttached() const;
+
+ private:
+ bool authenticate( AuthData & authdata, bool firstTry ) const;
};
+///////////////////////////////////////////////////////////////////A
} // namespace media
} // namespace zypp
-///////////////////////////////////////////////////////////////////
-
#endif // ZYPP_MEDIA_MEDIACIFS_H
diff --git a/zypp/media/MediaSMB.cc b/zypp/media/MediaSMB.cc
deleted file mode 100644
index 08e4f05..0000000
--- a/zypp/media/MediaSMB.cc
+++ /dev/null
@@ -1,470 +0,0 @@
-/*---------------------------------------------------------------------\
-| ____ _ __ __ ___ |
-| |__ / \ / / . \ . \ |
-| / / \ V /| _/ _/ |
-| / /__ | | | | | | |
-| /_____||_| |_| |_| |
-| |
-\---------------------------------------------------------------------*/
-/** \file zypp/media/MediaSMB.cc
- *
-*/
-
-#include <iostream>
-#include <fstream>
-
-#include "zypp/base/Logger.h"
-#include "zypp/base/Gettext.h"
-#include "zypp/TmpPath.h"
-#include "zypp/KVMap.h"
-#include "zypp/media/Mount.h"
-#include "zypp/media/MediaUserAuth.h"
-#include "zypp/media/CredentialManager.h"
-#include "zypp/ZYppCallbacks.h"
-
-#warning FIXME: get rid of this dependency on Target
-#include "zypp/ZYppFactory.h" // for target->root()
-#include "zypp/Target.h" // for zypp->target->root()
-
-#include "zypp/media/MediaSMB.h"
-
-#include
-#include
-#include
-#include
-
-using namespace std;
-
-namespace zypp {
- namespace media {
-
- /******************************************************************
- **
- **
- ** FUNCTION NAME : getShare
- ** FUNCTION TYPE : inline Pathname
- **
- ** Get the 1st path component (CIFS share name).
- */
- inline string getShare( Pathname spath_r )
- {
- if ( spath_r.empty() )
- return string();
-
- string share( spath_r.absolutename().asString() );
- string::size_type sep = share.find( "/", 1 );
- if ( sep == string::npos )
- share = share.erase( 0, 1 ); // nothing but the share name in spath_r
- else
- share = share.substr( 1, sep-1 );
-
- // deescape %2f in sharename
- while ( (sep = share.find( "%2f" )) != string::npos ) {
- share.replace( sep, 3, "/" );
- }
-
- return share;
- }
-
- /******************************************************************
- **
- **
- ** FUNCTION NAME : stripShare
- ** FUNCTION TYPE : inline Pathname
- **
- ** Strip off the 1st path component (CIFS share name).
- */
- inline Pathname stripShare( Pathname spath_r )
- {
- if ( spath_r.empty() )
- return Pathname();
-
- string striped( spath_r.absolutename().asString() );
- string::size_type sep = striped.find( "/", 1 );
- if ( sep == string::npos )
- return "/"; // nothing but the share name in spath_r
-
- return striped.substr( sep );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : MediaSMB
- //
- ///////////////////////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : MediaSMB::MediaSMB
- // METHOD TYPE : Constructor
- //
- // DESCRIPTION :
- //
- MediaSMB::MediaSMB( const Url & url_r,
- const Pathname & attach_point_hint_r )
- : MediaHandler( url_r, attach_point_hint_r,
- stripShare( url_r.getPathName() ), // urlpath WITHOUT share name at attachpoint
- false ) // does_download
- , _vfstype( "cifs" )
- {
- MIL << "MediaSMB::MediaSMB(" << url_r << ", " << attach_point_hint_r << ")" << endl;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : MediaSMB::attachTo
- // METHOD TYPE : PMError
- /**
- * Asserted that not already attached, and attachPoint is a directory.
- *
- * Authentication: credentials can be specified in the following few ways
- * (the first has the highest preference).
- * - URL username:password
- * - mountoptions URL query parameter (see man mount.cifs)
- * - CredentialManager - either previously saved credentials will be used
- * or the user will be promted for them via AuthenticationReport callback.
- *
- * \note The implementation currently serves both, "smb" and
- * and "cifs" URL's, but passes "cifs" to the mount command
- * in any case.
- */
- void MediaSMB::attachTo(bool next)
- {
- if(_url.getHost().empty())
- ZYPP_THROW(MediaBadUrlEmptyHostException(_url));
- if(next)
- ZYPP_THROW(MediaNotSupportedException(_url));
-
- string path = "//";
- path += _url.getHost() + "/" + getShare( _url.getPathName() );
-
- MediaSourceRef media( new MediaSource( _vfstype, path));
- AttachedMedia ret( findAttachedMedia( media));
-
- if( ret.mediaSource &&
- ret.attachPoint &&
- !ret.attachPoint->empty())
- {
- DBG << "Using a shared media "
- << ret.mediaSource->name
- << " attached on "
- << ret.attachPoint->path
- << endl;
-
- removeAttachPoint();
- setAttachPoint(ret.attachPoint);
- setMediaSource(ret.mediaSource);
- return;
- }
-
- std::string mountpoint = attachPoint().asString();
- if( !isUseableAttachPoint(attachPoint()))
- {
- mountpoint = createAttachPoint().asString();
- if( mountpoint.empty())
- ZYPP_THROW( MediaBadAttachPointException(url()));
- setAttachPoint( mountpoint, true);
- }
-
- Mount mount;
- CredentialManager cm;
-
- Mount::Options options( _url.getQueryParam("mountoptions") );
- string username = _url.getUsername();
- string password = _url.getPassword();
-
- options["guest"]; // prevent smbmount from asking for password
-
- if ( ! options.has( "rw" ) ) {
- options["ro"];
- }
-
- // look for a workgroup
- string workgroup = _url.getQueryParam("workgroup");
- if ( workgroup.empty() )
- workgroup = _url.getQueryParam("domain");
- if ( !workgroup.empty() )
- options["domain"] = workgroup;
-
- // extract 'username', do not overwrite any _url.username
-
- Mount::Options::iterator toEnv;
- toEnv = options.find("username");
- if ( toEnv != options.end() ) {
- if ( username.empty() )
- username = toEnv->second;
- options.erase( toEnv );
- }
-
- toEnv = options.find("user"); // actually cifs specific
- if ( toEnv != options.end() ) {
- if ( username.empty() )
- username = toEnv->second;
- options.erase( toEnv );
- }
-
- // extract 'password', do not overwrite any _url.password
-
- toEnv = options.find("password");
- if ( toEnv != options.end() ) {
- if ( password.empty() )
- password = toEnv->second;
- options.erase( toEnv );
- }
-
- toEnv = options.find("pass"); // actually cifs specific
- if ( toEnv != options.end() ) {
- if ( password.empty() )
- password = toEnv->second;
- options.erase( toEnv );
- }
-
- if ( username.empty() || password.empty() )
- {
- AuthData_Ptr c = cm.getCred(_url);
- if (c)
- {
- username = c->username();
- password = c->password();
- }
- }
-
- bool firstTry = true;
- bool authRequired = false;
- AuthData authdata;
- do // repeat this while the mount returns "Permission denied" error
- {
- // get credentials from authenicate()
- if ( !firstTry )
- {
- username = authdata.username();
- password = authdata.password();
- }
-
- // pass 'username' and 'password' via environment
- Mount::Environment environment;
- if ( !username.empty() )
- environment["USER"] = username;
- if ( !password.empty() )
- environment["PASSWD"] = password;
-
- //////////////////////////////////////////////////////
- // In case we need a tmpfile, credentials will remove
- // it in it's destructor after the mout call below.
- filesystem::TmpPath credentials;
- if ( !username.empty() || !password.empty() )
- {
- filesystem::TmpFile tmp;
- ofstream outs( tmp.path().asString().c_str() );
- outs << "username=" << username << endl;
- outs << "password=" << password << endl;
- outs.close();
-
- credentials = tmp;
- options["credentials"] = credentials.path().asString();
- }
- //
- //////////////////////////////////////////////////////
-
- try
- {
- mount.mount( path, mountpoint, _vfstype,
- options.asString(), environment );
- setMediaSource(media);
- break;
- }
- catch (const MediaMountException & e)
- {
- ZYPP_CAUGHT( e );
-
- if ( e.mountError() == "Permission denied" )
- authRequired = authenticate( authdata, firstTry );
- else
- ZYPP_RETHROW( e );
- }
-
- firstTry = false;
- }
- while ( authRequired );
-
- // wait for /etc/mtab update ...
- // (shouldn't be needed)
- int limit = 3;
- bool mountsucceeded;
- while( !(mountsucceeded=isAttached()) && --limit)
- sleep(1);
-
- if ( !mountsucceeded )
- {
- setMediaSource(MediaSourceRef());
- try
- {
- mount.umount(attachPoint().asString());
- }
- catch (const MediaException & excpt_r)
- {
- ZYPP_CAUGHT(excpt_r);
- }
- ZYPP_THROW(MediaMountException(
- "Unable to verify that the media was mounted",
- path, mountpoint
- ));
- }
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- // METHOD NAME : MediaSMB::isAttached
- // METHOD TYPE : bool
- //
- // DESCRIPTION : Override check if media is attached.
- //
- bool
- MediaSMB::isAttached() const
- {
- return checkAttached(true);
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : MediaSMB::releaseFrom
- // METHOD TYPE : PMError
- //
- // DESCRIPTION : Asserted that media is attached.
- //
- void MediaSMB::releaseFrom( const std::string & ejectDev )
- {
- Mount mount;
- mount.umount(attachPoint().asString());
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- // METHOD NAME : MediaSMB::getFile
- // METHOD TYPE : PMError
- //
- // DESCRIPTION : Asserted that media is attached.
- //
- void MediaSMB::getFile (const Pathname & filename) const
- {
- MediaHandler::getFile( filename );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- // METHOD NAME : MediaSMB::getDir
- // METHOD TYPE : PMError
- //
- // DESCRIPTION : Asserted that media is attached.
- //
- void MediaSMB::getDir( const Pathname & dirname, bool recurse_r ) const
- {
- MediaHandler::getDir( dirname, recurse_r );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : MediaSMB::getDirInfo
- // METHOD TYPE : PMError
- //
- // DESCRIPTION : Asserted that media is attached and retlist is empty.
- //
- void MediaSMB::getDirInfo( std::liststd::string & retlist,
- const Pathname & dirname, bool dots ) const
- {
- MediaHandler::getDirInfo( retlist, dirname, dots );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : MediaSMB::getDirInfo
- // METHOD TYPE : PMError
- //
- // DESCRIPTION : Asserted that media is attached and retlist is empty.
- //
- void MediaSMB::getDirInfo( filesystem::DirContent & retlist,
- const Pathname & dirname, bool dots ) const
- {
- MediaHandler::getDirInfo( retlist, dirname, dots );
- }
-
- bool MediaSMB::getDoesFileExist( const Pathname & filename ) const
- {
- return MediaHandler::getDoesFileExist( filename );
- }
-
- bool MediaSMB::authenticate(AuthData & authdata, bool firstTry) const
- {
- //! \todo need a way to pass different CredManagerOptions here
- Target_Ptr target = zypp::getZYpp()->getTarget();
- CredentialManager cm(CredManagerOptions(target ? target->root() : ""));
-
- // get stored credentials
- AuthData_Ptr cmcred = cm.getCred(_url);
-
- AuthData_Ptr smbcred;
- smbcred.reset(new AuthData());
- callback::SendReport<AuthenticationReport> auth_report;
-
- // preset the username if present in current url
- if (!_url.getUsername().empty() && firstTry)
- smbcred->setUsername(_url.getUsername());
- // if CM has found some credentials, preset the username from there
- else if (cmcred)
- smbcred->setUsername(cmcred->username());
-
- // indicate we have no good credentials from CM
- cmcred.reset();
-
- string prompt_msg = str::form(
- //!\todo add comma to the message for the next release
- _("Authentication required for '%s'"), _url.asString().c_str());
-
- // ask user
- if (auth_report->prompt(_url, prompt_msg, *smbcred))
- {
- DBG << "callback answer: retry" << endl
- << "AuthData: " << *smbcred << endl;
-
- if (smbcred->valid())
- {
- cmcred = smbcred;
- // if (credentials->username() != _url.getUsername())
- // _url.setUsername(credentials->username());
- /**
- * \todo find a way to save the url with changed username
- * back to repoinfo or dont store urls with username
- * (and either forbid more repos with the same url and different
- * user, or return a set of credentials from CM and try them one
- * by one)
- */
- }
- }
- else
- DBG << "callback answer: cancel" << endl;
-
- // set username and password
- if (cmcred)
- {
- authdata.setUsername(cmcred->username());
- authdata.setPassword(cmcred->password());
-
- // save the credentials
- cmcred->setUrl(_url);
- cm.addCred(*cmcred);
- cm.save();
-
- return true;
- }
-
- return false;
- }
-
-
- } // namespace media
-} // namespace zypp
diff --git a/zypp/media/MediaSMB.h b/zypp/media/MediaSMB.h
deleted file mode 100644
index 41d3f11..0000000
--- a/zypp/media/MediaSMB.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*---------------------------------------------------------------------\
-| ____ _ __ __ ___ |
-| |__ / \ / / . \ . \ |
-| / / \ V /| _/ _/ |
-| / /__ | | | | | | |
-| /_____||_| |_| |_| |
-| |
-\---------------------------------------------------------------------*/
-/** \file zypp/media/MediaSMB.h
- *
-*/
-#ifndef ZYPP_MEDIA_MEDIASMB_H
-#define ZYPP_MEDIA_MEDIASMB_H
-
-#include "zypp/media/MediaHandler.h"
-
-namespace zypp {
- namespace media {
-
- class AuthData;
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : MediaSMB
- /**
- * @short Implementation class for SMB MediaHandler
- *
- * NOTE: The implementation currently serves both, "smb"
- * and "cifs" URL's, but passes "cifs" to the mount command
- * in any case.
- * @see MediaHandler
- **/
- class MediaSMB : public MediaHandler {
-
- private:
-
- /**
- * vfstype for mount. This is either "smbfs"
- * or "cifs" (rewritten by MediaCIFS).
- * Obsolete: vfstype is allways "cifs".
- **/
- const char* _vfstype;
-
- protected:
-
- virtual void attachTo (bool next = false);
- virtual void releaseFrom( const std::string & ejectDev );
- virtual void getFile( const Pathname & filename ) const;
- virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
- virtual void getDirInfo( std::liststd::string & retlist,
- const Pathname & dirname, bool dots = true ) const;
- virtual void getDirInfo( filesystem::DirContent & retlist,
- const Pathname & dirname, bool dots = true ) const;
- virtual bool getDoesFileExist( const Pathname & filename ) const;
-
- /**
- * MediaCIFS rewrites the vfstype to "cifs"
- * within it's constructor.
- **/
- void mountAsCIFS() { _vfstype = "cifs"; }
-
- public:
- MediaSMB( const Url& url_r,
- const Pathname & attach_point_hint_r );
-
- virtual ~MediaSMB() { try { release(); } catch(...) {} }
-
- virtual bool isAttached() const;
-
- private:
- bool authenticate( AuthData & authdata, bool firstTry ) const;
- };
-
-///////////////////////////////////////////////////////////////////A
- } // namespace media
-} // namespace zypp
-
-#endif // ZYPP_MEDIA_MEDIASMB_H
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org