int ProcessCredSpecFile()

in api/src/gmsa_service.cpp [2365:2495]


int ProcessCredSpecFile( std::string krb_files_dir, std::string credspec_filepath,
                         CF_logger& cf_logger, std::string cred_file_lease_id )
{
    std::string err_msg;
    std::string credspec_contents;
    std::string log_message = "Generating lease id " + cred_file_lease_id;

    cf_logger.logger( LOG_INFO, log_message.c_str() );

    if ( !std::filesystem::exists( credspec_filepath ) )
    {
        std::cerr << Util::getCurrentTime() << '\t' << "The credential spec file "
                  << credspec_filepath << " was not found!" << std::endl;
        log_message = "The credential spec file " + credspec_filepath + " was not found!";
        cf_logger.logger( LOG_ERR, log_message.c_str() );
        return EXIT_FAILURE;
    }

    std::ifstream inputFile( credspec_filepath );
    if ( inputFile.is_open() )
    {
        credspec_contents.assign( ( std::istreambuf_iterator<char>( inputFile ) ),
                                  std::istreambuf_iterator<char>() );

        inputFile.close(); // Close the file
    }
    else
    {
        log_message = "Unable to open credential spec file: " + credspec_filepath;
        cf_logger.logger( LOG_ERR, log_message.c_str() );
        std::cerr << Util::getCurrentTime() << '\t'
                  << "Unable to open credential spec file: " << credspec_filepath << std::endl;

        return EXIT_FAILURE;
    }

    krb_ticket_info_t* krb_ticket_info = new krb_ticket_info_t;
    int parse_result = parse_cred_spec( credspec_contents, krb_ticket_info );

    // only add the ticket info if the parsing is successful
    if ( parse_result == EXIT_SUCCESS )
    {
        std::string krb_files_path =
            krb_files_dir + "/" + cred_file_lease_id + "/" + krb_ticket_info->service_account_name;
        krb_ticket_info->krb_file_path = krb_files_path;
        krb_ticket_info->domainless_user = "";
        krb_ticket_info->credspec_info = "";
    }
    else
    {
        err_msg = "Error: credential spec provided is not properly formatted";
        std::cerr << Util::getCurrentTime() << '\t' << err_msg << std::endl;
    }

    if ( err_msg.empty() )
    {
        std::pair<int, std::string> status;
        // invoke to get machine ticket
        status = generate_krb_ticket_from_machine_keytab( krb_ticket_info->domain_name, cf_logger );
        if ( status.first < 0 )
        {
            log_message = "Error: " + std::to_string( status.first ) + " " + status.second +
                          " Cannot get machine krb ticket";
            cf_logger.logger( LOG_ERR, log_message.c_str() );
            delete krb_ticket_info;

            return EXIT_FAILURE;
        }

        std::string krb_file_path = krb_ticket_info->krb_file_path;
        if ( std::filesystem::exists( krb_file_path ) )
        {
            log_message = "Deleting existing credential file directory " + krb_file_path;
            cf_logger.logger( LOG_INFO, log_message.c_str() );

            std::filesystem::remove_all( krb_file_path );
        }
        std::filesystem::create_directories( krb_file_path );

        std::string krb_ccname_str = krb_ticket_info->krb_file_path + "/krb5cc";

        if ( !std::filesystem::exists( krb_ccname_str ) )
        {
            std::ofstream file( krb_ccname_str );
            file.close();

            krb_ticket_info->krb_file_path = krb_ccname_str;
        }

        std::pair<int, std::string> gmsa_ticket_result = fetch_gmsa_password_and_create_krb_ticket(
            krb_ticket_info->domain_name, krb_ticket_info, krb_ccname_str, cf_logger );
        if ( gmsa_ticket_result.first != 0 )
        {
            err_msg = "ERROR: Cannot get gMSA krb ticket";
            std::cerr << Util::getCurrentTime() << '\t' << err_msg << std::endl;
            log_message = "ERROR: Cannot get gMSA krb ticket " + std::to_string( status.first ) +
                          " " + status.second;
            cf_logger.logger( LOG_ERR, log_message.c_str() );
        }
        else
        {
            chmod( krb_ccname_str.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
            log_message = "gMSA ticket is at " + gmsa_ticket_result.second;
            cf_logger.logger( LOG_INFO, log_message.c_str() );
            std::cerr << Util::getCurrentTime() << '\t' << "INFO: gMSA ticket is created"
                      << std::endl;
        }
    }

    // And we are done! Let the gRPC runtime know we've finished, using the
    // memory address of this instance as the uniquely identifying tag for
    // the event.
    if ( !err_msg.empty() )
    {
        // remove the directory on failure
        std::filesystem::remove_all( krb_ticket_info->krb_file_path );

        std::cerr << err_msg << std::endl;
        cf_logger.logger( LOG_ERR, err_msg.c_str() );
        delete krb_ticket_info;

        return EXIT_FAILURE;
    }

    // write the ticket information to meta data file
    write_meta_data_json( krb_ticket_info, cred_file_lease_id, krb_files_dir );

    delete krb_ticket_info;

    return EXIT_SUCCESS;
}