std::vector delete_krb_tickets()

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;
}