Skip to content

Commit

Permalink
Merge pull request #18 from aws/handle_mulitple_service_accounts
Browse files Browse the repository at this point in the history
Handle duplicate credential spec
  • Loading branch information
saikiranakula-amzn authored Oct 4, 2022
2 parents e952f4a + e87befd commit 3c03790
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 46 deletions.
56 changes: 32 additions & 24 deletions api/src/gmsa_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,23 +109,30 @@ class CredentialsFetcherImpl final
// The actual processing.
std::string lease_id = generate_lease_id();
std::list<creds_fetcher::krb_ticket_info*> krb_ticket_info_list;
std::unordered_set<std::string> krb_ticket_dirs;

std::string err_msg;
create_krb_reply_.set_lease_id( lease_id );
for ( int i = 0; i < create_krb_request_.credspec_contents_size(); i++ )
{
creds_fetcher::krb_ticket_info* krb_ticket_info =
new creds_fetcher::krb_ticket_info;

int parse_result = parse_cred_spec( create_krb_request_.credspec_contents( i ),
krb_ticket_info );

// only add the ticket info if the parsing is succesful
// only add the ticket info if the parsing is successful
if ( parse_result == 0 )
{
krb_ticket_info->krb_file_path = krb_files_dir + "/" + lease_id;
std::string krb_files_path = krb_files_dir + "/" + lease_id + "/" +
krb_ticket_info->service_account_name;
krb_ticket_info->krb_file_path = krb_files_path;

krb_ticket_info_list.push_back( krb_ticket_info );
// handle duplicate service accounts
if ( !krb_ticket_dirs.count( krb_files_path ) )
{
krb_ticket_dirs.insert( krb_files_path );
krb_ticket_info_list.push_back( krb_ticket_info );
}
}
else
{
Expand All @@ -148,28 +155,25 @@ class CredentialsFetcherImpl final
break;
}

boost::filesystem::create_directories( krb_ticket->krb_file_path );
std::string krb_ccname = krb_ticket->krb_file_path + "/ccname_" +
krb_ticket->service_account_name +
std::string( "_XXXXXX" );
char krb_ccname_str[PATH_MAX];
strncpy( krb_ccname_str, krb_ccname.c_str(), PATH_MAX );
int fd = mkstemp( krb_ccname_str ); // XXXXXX as per mkstemp man page
krb_ticket->krb_file_path = krb_ccname_str;

if ( fd < 0 )
std::string krb_file_path = krb_ticket->krb_file_path;
if ( boost::filesystem::exists( krb_file_path ) )
{
cf_logger.logger( LOG_ERR,
"Error %d: Cannot make "
"temporary file",
errno );

err_msg = "ERROR: cannot make the temporary file for kerberos ticket";
cf_logger.logger( LOG_INFO,
"Directory already exists: "
"%s",
krb_file_path );
break;
}
else
boost::filesystem::create_directories( krb_file_path );

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

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

krb_ticket->krb_file_path = krb_ccname_str;
}

std::pair<int, std::string> gmsa_ticket_result = get_gmsa_krb_ticket(
Expand All @@ -190,15 +194,19 @@ class CredentialsFetcherImpl final
std::cout << "gMSA ticket is at " << gmsa_ticket_result.second
<< std::endl;
}
create_krb_reply_.add_created_kerberos_file_paths(
krb_ticket->krb_file_path );
create_krb_reply_.add_created_kerberos_file_paths( krb_file_path );
}
}
// 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 directories on failure
for ( auto krb_ticket : krb_ticket_info_list )
{
boost::filesystem::remove_all( krb_ticket->krb_file_path );
}
status_ = FINISH;
create_krb_responder_.Finish(
create_krb_reply_, grpc::Status( grpc::StatusCode::INTERNAL, err_msg ),
Expand Down
8 changes: 7 additions & 1 deletion api/tests/gmsa_test_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,13 @@ int main( int argc, char** argv )
"\"MachineAccountName\":\"WebApp03\",\"Guid\":\"af602f85-d754-4eea-9fa8-fd76810485f1\","
"\"DnsTreeName\":\"contoso.com\",\"DnsName\":\"contoso.com\",\"NetBiosName\":\"contoso\"},"
"\"ActiveDirectoryConfig\":{\"GroupManagedServiceAccounts\":[{\"Name\":\"WebApp03\","
"\"Scope\":\"contoso.com\"},{\"Name\":\"WebApp03\",\"Scope\":\"contoso\"}]}}" };
"\"Scope\":\"contoso.com\"},{\"Name\":\"WebApp03\",\"Scope\":\"contoso\"}]}}",
"{\"CmsPlugins\":[\"ActiveDirectory\"],"
"\"DomainJoinConfig\":{\"Sid\":\"S-1-5-21-4217655605-3681839426-3493040985\","
"\"MachineAccountName\":\"WebApp01\",\"Guid\":\"af602f85-d754-4eea-9fa8-fd76810485f1\","
"\"DnsTreeName\":\"contoso.com\",\"DnsName\":\"contoso.com\",\"NetBiosName\":\"contoso\"},"
"\"ActiveDirectoryConfig\":{\"GroupManagedServiceAccounts\":[{\"Name\":\"WebApp01\","
"\"Scope\":\"contoso.com\"},{\"Name\":\"WebApp01\",\"Scope\":\"contoso\"}]}}" };

std::list<std::string> invalid_credspec_contents = {
"{\"CmsPlugins\":[\"ActiveDirectory\"],"
Expand Down
52 changes: 31 additions & 21 deletions auth/kerberos/src/krb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
#define RENEW_TICKET_HOURS 1
#define SECONDS_IN_HOUR 3600

static const std::string install_path_for_decode_exe = "/usr/sbin/credentials_fetcher_utf16_private.exe";
static const std::string install_path_for_decode_exe =
"/usr/sbin/credentials_fetcher_utf16_private.exe";

/**
* Check if binary is writable other than root
Expand Down Expand Up @@ -85,8 +86,9 @@ static std::pair<int, std::string> get_machine_principal( std::string domain_nam
{
result.first = realm_name_result.first;
realm_name_result =
exec_shell_cmd( "net ads info | grep 'Realm' | cut -f2 -d: | tr -d ' ' | tr -d '\n'" );
if ( realm_name_result.first != 0 ) {
exec_shell_cmd( "net ads info | grep 'Realm' | cut -f2 -d: | tr -d ' ' | tr -d '\n'" );
if ( realm_name_result.first != 0 )
{
result.first = realm_name_result.first;
return result;
}
Expand Down Expand Up @@ -208,7 +210,7 @@ static uint8_t* base64_decode( const std::string& password, gsize* base64_decode
return (uint8_t*)secure_mem;
}

static std::pair<size_t, void *> find_password( std::string ldap_search_result )
static std::pair<size_t, void*> find_password( std::string ldap_search_result )
{
size_t base64_decode_len = 0;
std::vector<std::string> results;
Expand Down Expand Up @@ -241,7 +243,7 @@ static std::pair<size_t, void *> find_password( std::string ldap_search_result )
}
}

return std::make_pair(base64_decode_len, blob_base64_decoded);
return std::make_pair( base64_decode_len, blob_base64_decoded );
}

/**
Expand Down Expand Up @@ -290,7 +292,7 @@ int test_utf16_decode()

std::string decoded_password_file = "./decoded_password_file";

std::pair<size_t, void *> base64_decoded_password_blob =
std::pair<size_t, void*> base64_decoded_password_blob =
find_password( test_msds_managed_password );
if ( base64_decoded_password_blob.first == 0 || base64_decoded_password_blob.second == nullptr )
{
Expand All @@ -311,8 +313,7 @@ int test_utf16_decode()
}

// Use decode.exe in build directory
std::string decode_cmd =
decode_exe_path + std::string( " > " ) + decoded_password_file;
std::string decode_cmd = decode_exe_path + std::string( " > " ) + decoded_password_file;
creds_fetcher::blob_t* blob = ( (creds_fetcher::blob_t*)base64_decoded_password_blob.second );
FILE* fp = popen( decode_cmd.c_str(), "w" );
if ( fp == nullptr )
Expand Down Expand Up @@ -505,7 +506,7 @@ std::pair<int, std::string> get_gmsa_krb_ticket( std::string domain_name,
return std::make_pair( -1, std::string( "" ) );
}

std::pair<size_t, void *> password_found_result = find_password( ldap_search_result.second );
std::pair<size_t, void*> password_found_result = find_password( ldap_search_result.second );

if ( password_found_result.first == 0 || password_found_result.second == nullptr )
{
Expand Down Expand Up @@ -660,25 +661,34 @@ std::vector<std::string> delete_krb_tickets( std::string krb_files_dir, std::str
curr_dir = opendir( krb_tickets_path.c_str() );
try
{

if ( curr_dir )
{
while ( ( file = readdir( curr_dir ) ) != NULL )
{
std::string krb_cc_name = file->d_name;
if ( !krb_cc_name.empty() && krb_cc_name.find( "ccname" ) != std::string::npos )
std::string filename = file->d_name;
if ( !filename.empty() && filename.find( "_metadata" ) != std::string::npos )
{
std::string cmd = "export KRB5CCNAME=" + krb_tickets_path + "/" + krb_cc_name +
" && kdestroy";
std::string file_path = krb_tickets_path + "/" + filename;
std::list<creds_fetcher::krb_ticket_info*> krb_ticket_info_list =
read_meta_data_json( file_path );

std::pair<int, std::string> krb_ticket_destroy_result = exec_shell_cmd( cmd );
if ( krb_ticket_destroy_result.first == 0 )
{
delete_krb_ticket_paths.push_back( krb_cc_name );
}
else
for ( auto krb_ticket : krb_ticket_info_list )
{
// log ticket deletion failure
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 =
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::cout << "Delete kerberos ticket failed" + krb_file_path
<< std::endl;
}
}
}
}
Expand Down

0 comments on commit 3c03790

Please sign in to comment.