int zuluCryptUnmountVolume( const char * device,char ** m_point ) { int h = 3 ; char * e ; size_t s ; stringList_t stl ; StringListIterator it ; StringListIterator end ; ssize_t r ; string_t st ; string_t xt ; if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress() is defined in create_loop_device.c */ e = zuluCryptLoopDeviceAddress( device ) ; if( e == NULL ){ return h ; }else{ stl = _get_mount_entries( e ) ; StringFree( e ) ; } }else{ stl = _get_mount_entries( device ) ; } s = StringListSize( stl ) ; if( s == 0 ){ /* * volume appear to not be mounted. */ }else if( s == 1 ){ /* * there is only one mount point for the volume,unmount it normally */ h = _zuluCryptUnmountVolume_0( StringListStringAtFirstPlace( stl ),m_point ) ; }else{ /* * There are multiple mount points for the same volume. * * Try to figure out which one among the mount points is ours and then try * first to unmount the rest of them. */ r = StringListHasSequence( stl," /run/media/private/" ) ; if( r == -1 ){ /* * Probable reason for getting here is if a user use a home mount point path, * we dont know the path because we dont know the user we are serving * and hence we bail out with an error. */ h = 10 ; }else{ /* * We got our mount point,take it out of the list to use it last */ st = StringListDetachAt( stl,r ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ xt = *it ; it++ ; if( _zuluCryptUnmountVolume_0( xt,NULL ) != 0 ){ /* * Failed to unmount one of the extra mount points, * bail out with an error. */ h = 10 ; break ; } } if( h != 10 ){ /* * Attempt to unmount our mount point last. */ h = _zuluCryptUnmountVolume_0( st,m_point ) ; } StringDelete( &st ) ; } } if( h != 0 && h != 3 && h != 4 && h != 1 && h != 10 ){ h = 2 ; } StringListDelete( &stl ) ; return h ; }
int zuluCryptBindMountVolume( const char * device,string_t z_path,unsigned long flags ) { struct stat st ; string_t path ; string_t tmp ; ssize_t index = StringLastIndexOfChar( z_path,'/' ) ; const char * o_path = StringContent( z_path ) ; const char * m_path ; const char * e ; int xt ; stringList_t stl ; mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH ; if( index == -1 ){ return 1 ; } if( device ){;} zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptGetMoutedListFromMountInfo() is defined in ../lib/process_mountinfo.c */ stl = zuluCryptGetMoutedListFromMountInfo() ; path = String( "/run/media/public/" ) ; m_path = StringAppend( path,o_path + index + 1 ) ; #define path_does_not_exist( x ) stat( x,&st ) != 0 #define path_does_exist( x ) stat( x,&st ) == 0 if( path_does_not_exist( "/run" ) ){ mkdir( "/run",mode ) ; _chown( "/run",0,0 ) ; } if( path_does_not_exist( "/run/media" ) ){ mkdir( "/run/media",mode ) ; _chown( "/run/media",0,0 ) ; } if( path_does_not_exist( "/run/media/public" ) ){ mkdir( "/run/media/public",mode ) ; _chown( "/run/media/public",0,0 ) ; } if( path_does_exist( m_path ) ){ /* * bind mount point exists,this will happen if the mount point is already taken or a mount point folder * was not autodeleted for some reason */ tmp = StringCopy( path ) ; e = StringAppend( tmp," " ) ; if( StringListHasSequence( stl,e ) != -1 ){ /* * An attempt is made to bind mount on a path already bind mounted path,dont attempt to mount */ xt = 1 ; }else{ /* * the mount point folder is there for some reason but is not being used. */ xt = mount( o_path,m_path,"",flags|MS_BIND,"" ) ; } StringDelete( &tmp ) ; }else{ mkdir( m_path,S_IRWXU | S_IRWXG | S_IRWXG ) ; _chown( m_path,0,0 ) ; xt = mount( o_path,m_path,"",flags|MS_BIND,"" ) ; if( xt != 0 ){ rmdir( m_path ) ; } } StringListDelete( &stl ) ; StringDelete( &path ) ; zuluCryptSecurityDropElevatedPrivileges() ; return xt ; }