in auth/kerberos/src/krb.cpp [569:659]
std::vector<std::string> delete_krb_tickets( std::string krb_files_dir, std::string lease_id )
{
std::vector<std::string> delete_krb_ticket_paths;
if ( lease_id.empty() || krb_files_dir.empty() ) {
return delete_krb_ticket_paths;
}
// Normalize paths using std::filesystem
std::filesystem::path base_dir = std::filesystem::absolute(krb_files_dir);
std::filesystem::path target_path = base_dir / lease_id;
try {
// Convert to canonical form (resolves ".." and symlinks)
std::filesystem::path canonical_base = std::filesystem::canonical(base_dir);
// Check if target path exists before canonicalization
if (std::filesystem::exists(target_path)) {
std::filesystem::path canonical_target = std::filesystem::canonical(target_path);
// Verify target path is under base directory
std::string base_str = canonical_base.string();
std::string target_str = canonical_target.string();
if (target_str.compare(0, base_str.length(), base_str) != 0) {
std::cerr << Util::getCurrentTime() << '\t'
<< "ERROR: Invalid path - attempted directory traversal"
<< std::endl;
return delete_krb_ticket_paths;
}
}
} catch (const std::filesystem::filesystem_error& e) {
std::cerr << Util::getCurrentTime() << '\t' << "ERROR: Path validation failed: " << e.what() << std::endl;
return delete_krb_ticket_paths;
}
DIR* curr_dir = opendir(target_path.c_str());
struct dirent* file;
try
{
if ( curr_dir )
{
while ( ( file = readdir( curr_dir ) ) != NULL )
{
std::string filename = file->d_name;
if ( !filename.empty() && filename.find( "_metadata" ) != std::string::npos )
{
std::string file_path = (target_path / filename).string();
std::list<krb_ticket_info_t*> krb_ticket_info_list =
read_meta_data_json( file_path );
for ( auto krb_ticket : krb_ticket_info_list )
{
std::string krb_file_path = krb_ticket->krb_file_path;
std::string cmd = "export KRB5CCNAME=" + krb_file_path + " && kdestroy";
std::pair<int, std::string> krb_ticket_destroy_result =
Util::exec_shell_cmd( cmd );
if ( krb_ticket_destroy_result.first == 0 )
{
delete_krb_ticket_paths.push_back( krb_file_path );
}
else
{
// log ticket deletion failure
std::cerr << Util::getCurrentTime() << '\t'
<< "Delete kerberos ticket "
"failed" +
krb_file_path
<< std::endl;
}
}
}
}
// close directory
closedir( curr_dir );
// finally delete lease file and directory
std::filesystem::remove_all(target_path);
}
}
catch ( ... )
{
std::cerr << Util::getCurrentTime() << '\t'
<< "Delete kerberos ticket "
"failed"
<< std::endl;
closedir( curr_dir );
return delete_krb_ticket_paths;
}
return delete_krb_ticket_paths;
}