/* * Class: sun_security_krb5_Credentials * Method: acquireDefaultNativeCreds * Signature: ([I])Lsun/security/krb5/Credentials; */ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds (JNIEnv *env, jclass krbcredsClass, jintArray jetypes) { jobject krbCreds = NULL; krb5_error_code err = 0; krb5_ccache ccache = NULL; krb5_cc_cursor cursor = NULL; krb5_creds creds; krb5_flags flags = 0; krb5_context kcontext = NULL; int netypes; jint *etypes = NULL; /* Initialize the Kerberos 5 context */ err = krb5_init_context (&kcontext); if (!err) { err = krb5_cc_default (kcontext, &ccache); } if (!err) { err = krb5_cc_set_flags (kcontext, ccache, flags); /* turn off OPENCLOSE */ } if (!err) { err = krb5_cc_start_seq_get (kcontext, ccache, &cursor); } netypes = (*env)->GetArrayLength(env, jetypes); etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL); if (etypes != NULL && !err) { while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) { char *serverName = NULL; if (!err) { err = krb5_unparse_name (kcontext, creds.server, &serverName); printiferr (err, "while unparsing server name"); } if (!err) { char* slash = strchr(serverName, '/'); char* at = strchr(serverName, '@'); // Make sure the server's name is krbtgt/REALM@REALM, the etype // is supported, and the ticket has not expired if (slash && at && strncmp (serverName, "krbtgt", slash-serverName) == 0 && // the ablove line shows at must be after slash strncmp (slash+1, at+1, at-slash-1) == 0 && isIn (creds.keyblock.enctype, netypes, etypes) && creds.times.endtime > time(0)) { jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; jobject ticketFlags, startTime, endTime; jobject authTime, renewTillTime, hostAddresses; ticket = clientPrincipal = targetPrincipal = encryptionKey = NULL; ticketFlags = startTime = endTime = NULL; authTime = renewTillTime = hostAddresses = NULL; // For the default credentials we're only interested in the krbtgt server. clientPrincipal = BuildClientPrincipal(env, kcontext, creds.client); if (clientPrincipal == NULL) goto cleanup; targetPrincipal = BuildClientPrincipal(env, kcontext, creds.server); if (targetPrincipal == NULL) goto cleanup; // Build a sun/security/krb5/internal/Ticket ticket = BuildTicket(env, &creds.ticket); if (ticket == NULL) goto cleanup; // Get the encryption key encryptionKey = BuildEncryptionKey(env, &creds.keyblock); if (encryptionKey == NULL) goto cleanup; // and the ticket flags ticketFlags = BuildTicketFlags(env, creds.ticket_flags); if (ticketFlags == NULL) goto cleanup; // Get the timestamps out. startTime = BuildKerberosTime(env, creds.times.starttime); if (startTime == NULL) goto cleanup; authTime = BuildKerberosTime(env, creds.times.authtime); if (authTime == NULL) goto cleanup; endTime = BuildKerberosTime(env, creds.times.endtime); if (endTime == NULL) goto cleanup; renewTillTime = BuildKerberosTime(env, creds.times.renew_till); if (renewTillTime == NULL) goto cleanup; // Create the addresses object. hostAddresses = BuildAddressList(env, creds.addresses); if (krbcredsConstructor == 0) { krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>", "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); if (krbcredsConstructor == 0) { printf("Couldn't find sun.security.krb5.internal.Ticket constructor\n"); break; } } // and now go build a KrbCreds object krbCreds = (*env)->NewObject( env, krbcredsClass, krbcredsConstructor, ticket, clientPrincipal, targetPrincipal, encryptionKey, ticketFlags, authTime, startTime, endTime, renewTillTime, hostAddresses); cleanup: if (ticket) (*env)->DeleteLocalRef(env, ticket); if (clientPrincipal) (*env)->DeleteLocalRef(env, clientPrincipal); if (targetPrincipal) (*env)->DeleteLocalRef(env, targetPrincipal); if (encryptionKey) (*env)->DeleteLocalRef(env, encryptionKey); if (ticketFlags) (*env)->DeleteLocalRef(env, ticketFlags); if (authTime) (*env)->DeleteLocalRef(env, authTime); if (startTime) (*env)->DeleteLocalRef(env, startTime); if (endTime) (*env)->DeleteLocalRef(env, endTime); if (renewTillTime) (*env)->DeleteLocalRef(env, renewTillTime); if (hostAddresses) (*env)->DeleteLocalRef(env, hostAddresses); // Stop if there is an exception or we already found the initial TGT if ((*env)->ExceptionCheck(env) || krbCreds) { break; } } } if (serverName != NULL) { krb5_free_unparsed_name (kcontext, serverName); } krb5_free_cred_contents (kcontext, &creds); } if (err == KRB5_CC_END) { err = 0; } printiferr (err, "while retrieving a ticket"); } if (!err) { err = krb5_cc_end_seq_get (kcontext, ccache, &cursor); printiferr (err, "while finishing ticket retrieval"); } if (!err) { flags = KRB5_TC_OPENCLOSE; /* restore OPENCLOSE mode */ err = krb5_cc_set_flags (kcontext, ccache, flags); printiferr (err, "while finishing ticket retrieval"); } if (etypes != NULL) { (*env)->ReleaseIntArrayElements(env, jetypes, etypes, 0); } krb5_free_context (kcontext); return krbCreds; }
/* * Class: sun_security_krb5_Credentials * Method: acquireDefaultNativeCreds * Signature: ()Lsun/security/krb5/Credentials; */ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds( JNIEnv *env, jclass krbcredsClass) { KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL; PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; NTSTATUS Status, SubStatus; ULONG requestSize = 0; ULONG responseSize = 0; ULONG rspSize = 0; HANDLE LogonHandle = NULL; ULONG PackageId; jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; jobject ticketFlags, startTime, endTime, krbCreds = NULL; jobject authTime, renewTillTime, hostAddresses = NULL; KERB_EXTERNAL_TICKET *msticket; int ignore_cache = 0; FILETIME Now, EndTime, LocalEndTime; while (TRUE) { if (krbcredsConstructor == 0) { krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>", "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); if (krbcredsConstructor == 0) { printf("Couldn't find sun.security.krb5.Credentials constructor\n"); break; } } #ifdef DEBUG printf("Found KrbCreds constructor\n"); #endif // // Get the logon handle and package ID from the // Kerberos package // if (!PackageConnectLookup(&LogonHandle, &PackageId)) break; #ifdef DEBUG printf("Got handle to Kerberos package\n"); #endif /* DEBUG */ // Get the MS TGT from cache CacheRequest.MessageType = KerbRetrieveTicketMessage; CacheRequest.LogonId.LowPart = 0; CacheRequest.LogonId.HighPart = 0; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, &CacheRequest, sizeof(CacheRequest), &TktCacheResponse, &rspSize, &SubStatus ); #ifdef DEBUG printf("Response size is %d\n", rspSize); #endif if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) { if (!LSA_SUCCESS(Status)) { ShowNTError("LsaCallAuthenticationPackage", Status); } else { ShowNTError("Protocol status", SubStatus); } break; } // got the native MS TGT msticket = &(TktCacheResponse->Ticket); // check TGT validity switch (msticket->SessionKey.KeyType) { case KERB_ETYPE_DES_CBC_CRC: case KERB_ETYPE_DES_CBC_MD5: case KERB_ETYPE_NULL: case KERB_ETYPE_RC4_HMAC_NT: GetSystemTimeAsFileTime(&Now); EndTime.dwLowDateTime = msticket->EndTime.LowPart; EndTime.dwHighDateTime = msticket->EndTime.HighPart; FileTimeToLocalFileTime(&EndTime, &LocalEndTime); if (CompareFileTime(&Now, &LocalEndTime) >= 0) { ignore_cache = 1; } if (msticket->TicketFlags & KERB_TICKET_FLAGS_invalid) { ignore_cache = 1; } break; case KERB_ETYPE_RC4_MD4: default: // not supported ignore_cache = 1; break; } if (ignore_cache) { #ifdef DEBUG printf("MS TGT in cache is invalid/not supported; request new ticket\n"); #endif /* DEBUG */ // use domain to request Ticket Status = ConstructTicketRequest(msticket->TargetDomainName, &pTicketRequest, &requestSize); if (!LSA_SUCCESS(Status)) { ShowNTError("ConstructTicketRequest status", Status); break; } pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage; pTicketRequest->EncryptionType = KERB_ETYPE_DES_CBC_MD5; pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pTicketRequest, requestSize, &pTicketResponse, &responseSize, &SubStatus ); #ifdef DEBUG printf("Response size is %d\n", responseSize); #endif /* DEBUG */ if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) { if (!LSA_SUCCESS(Status)) { ShowNTError("LsaCallAuthenticationPackage", Status); } else { ShowNTError("Protocol status", SubStatus); } break; } // got the native MS Kerberos TGT msticket = &(pTicketResponse->Ticket); } /* typedef struct _KERB_RETRIEVE_TKT_RESPONSE { KERB_EXTERNAL_TICKET Ticket; } KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE; typedef struct _KERB_EXTERNAL_TICKET { PKERB_EXTERNAL_NAME ServiceName; PKERB_EXTERNAL_NAME TargetName; PKERB_EXTERNAL_NAME ClientName; UNICODE_STRING DomainName; UNICODE_STRING TargetDomainName; UNICODE_STRING AltTargetDomainName; KERB_CRYPTO_KEY SessionKey; ULONG TicketFlags; ULONG Flags; LARGE_INTEGER KeyExpirationTime; LARGE_INTEGER StartTime; LARGE_INTEGER EndTime; LARGE_INTEGER RenewUntil; LARGE_INTEGER TimeSkew; ULONG EncodedTicketSize; PUCHAR EncodedTicket; <========== Here's the good stuff } KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET; typedef struct _KERB_EXTERNAL_NAME { SHORT NameType; USHORT NameCount; UNICODE_STRING Names[ANYSIZE_ARRAY]; } KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME; typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef struct KERB_CRYPTO_KEY { LONG KeyType; ULONG Length; PUCHAR Value; } KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY; */ // Build a com.sun.security.krb5.Ticket ticket = BuildTicket(env, msticket->EncodedTicket, msticket->EncodedTicketSize); if (ticket == NULL) { break; } // OK, have a Ticket, now need to get the client name clientPrincipal = BuildPrincipal(env, msticket->ClientName, msticket->TargetDomainName); // mdu if (clientPrincipal == NULL) { break; } // and the "name" of tgt targetPrincipal = BuildPrincipal(env, msticket->ServiceName, msticket->DomainName); if (targetPrincipal == NULL) { break; } // Get the encryption key encryptionKey = BuildEncryptionKey(env, &(msticket->SessionKey)); if (encryptionKey == NULL) { break; } // and the ticket flags ticketFlags = BuildTicketFlags(env, &(msticket->TicketFlags)); if (ticketFlags == NULL) { break; } // Get the start time startTime = BuildKerberosTime(env, &(msticket->StartTime)); if (startTime == NULL) { break; } /* * mdu: No point storing the eky expiration time in the auth * time field. Set it to be same as startTime. Looks like * windows does not have post-dated tickets. */ authTime = startTime; // and the end time endTime = BuildKerberosTime(env, &(msticket->EndTime)); if (endTime == NULL) { break; } // Get the renew till time renewTillTime = BuildKerberosTime(env, &(msticket->RenewUntil)); if (renewTillTime == NULL) { break; } // and now go build a KrbCreds object krbCreds = (*env)->NewObject( env, krbcredsClass, krbcredsConstructor, ticket, clientPrincipal, targetPrincipal, encryptionKey, ticketFlags, authTime, // mdu startTime, endTime, renewTillTime, //mdu hostAddresses); break; } // end of WHILE // clean up resources if (TktCacheResponse != NULL) { LsaFreeReturnBuffer(TktCacheResponse); } if (pTicketRequest) { LocalFree(pTicketRequest); } if (pTicketResponse != NULL) { LsaFreeReturnBuffer(pTicketResponse); } return krbCreds; }
/* * Class: sun_security_krb5_Credentials * Method: acquireDefaultNativeCreds * Signature: ()Lsun/security/krb5/Credentials; */ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds (JNIEnv *env, jclass krbcredsClass) { jobject krbCreds = NULL; krb5_error_code err = 0; krb5_ccache ccache = NULL; krb5_cc_cursor cursor = NULL; krb5_creds creds; krb5_flags flags = 0; krb5_context kcontext = NULL; /* Initialize the Kerberos 5 context */ err = krb5_init_context (&kcontext); if (!err) { err = krb5_cc_default (kcontext, &ccache); } if (!err) { err = krb5_cc_set_flags (kcontext, ccache, flags); /* turn off OPENCLOSE */ } if (!err) { err = krb5_cc_start_seq_get (kcontext, ccache, &cursor); } if (!err) { while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) { char *serverName = NULL; if (!err) { err = krb5_unparse_name (kcontext, creds.server, &serverName); printiferr (err, "while unparsing server name"); } if (!err) { if (strncmp (serverName, "krbtgt", strlen("krbtgt")) == 0) { jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; jobject ticketFlags, startTime, endTime; jobject authTime, renewTillTime, hostAddresses; ticket = clientPrincipal = targetPrincipal = encryptionKey = NULL; ticketFlags = startTime = endTime = NULL; authTime = renewTillTime = hostAddresses = NULL; // For the default credentials we're only interested in the krbtgt server. clientPrincipal = BuildClientPrincipal(env, kcontext, creds.client); if (clientPrincipal == NULL) goto cleanup; targetPrincipal = BuildClientPrincipal(env, kcontext, creds.server); if (targetPrincipal == NULL) goto cleanup; // Build a com.ibm.security.krb5.Ticket ticket = BuildTicket(env, &creds.ticket); if (ticket == NULL) goto cleanup; // Get the encryption key encryptionKey = BuildEncryptionKey(env, &creds.keyblock); if (encryptionKey == NULL) goto cleanup; // and the ticket flags ticketFlags = BuildTicketFlags(env, creds.ticket_flags); if (ticketFlags == NULL) goto cleanup; // Get the timestamps out. startTime = BuildKerberosTime(env, creds.times.starttime); if (startTime == NULL) goto cleanup; authTime = BuildKerberosTime(env, creds.times.authtime); if (authTime == NULL) goto cleanup; endTime = BuildKerberosTime(env, creds.times.endtime); if (endTime == NULL) goto cleanup; renewTillTime = BuildKerberosTime(env, creds.times.renew_till); if (renewTillTime == NULL) goto cleanup; // Create the addresses object. hostAddresses = BuildAddressList(env, creds.addresses); if (krbcredsConstructor == 0) { krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>", "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); if (krbcredsConstructor == 0) { printf("Couldn't find com.ibm.security.krb5.Credentials constructor\n"); break; } } // and now go build a KrbCreds object krbCreds = (*env)->NewObject( env, krbcredsClass, krbcredsConstructor, ticket, clientPrincipal, targetPrincipal, encryptionKey, ticketFlags, authTime, startTime, endTime, renewTillTime, hostAddresses); cleanup: if (ticket) (*env)->DeleteLocalRef(env, ticket); if (clientPrincipal) (*env)->DeleteLocalRef(env, clientPrincipal); if (targetPrincipal) (*env)->DeleteLocalRef(env, targetPrincipal); if (encryptionKey) (*env)->DeleteLocalRef(env, encryptionKey); if (ticketFlags) (*env)->DeleteLocalRef(env, ticketFlags); if (authTime) (*env)->DeleteLocalRef(env, authTime); if (startTime) (*env)->DeleteLocalRef(env, startTime); if (endTime) (*env)->DeleteLocalRef(env, endTime); if (renewTillTime) (*env)->DeleteLocalRef(env, renewTillTime); if (hostAddresses) (*env)->DeleteLocalRef(env, hostAddresses); } } if (serverName != NULL) { krb5_free_unparsed_name (kcontext, serverName); } krb5_free_cred_contents (kcontext, &creds); } if (err == KRB5_CC_END) { err = 0; } printiferr (err, "while retrieving a ticket"); } if (!err) { err = krb5_cc_end_seq_get (kcontext, ccache, &cursor); printiferr (err, "while finishing ticket retrieval"); } if (!err) { flags = KRB5_TC_OPENCLOSE; /* restore OPENCLOSE mode */ err = krb5_cc_set_flags (kcontext, ccache, flags); printiferr (err, "while finishing ticket retrieval"); } krb5_free_context (kcontext); return krbCreds; }
/* * Class: sun_security_krb5_Credentials * Method: acquireDefaultNativeCreds * Signature: ()Lsun/security/krb5/Credentials; */ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds( JNIEnv *env, jclass krbcredsClass) { HANDLE LogonHandle = NULL; ULONG PackageId; PKERB_RETRIEVE_TKT_REQUEST CacheRequest = NULL; PKERB_RETRIEVE_TKT_RESPONSE CacheResponse = NULL; ULONG rspSize = 0; DWORD errorCode; NTSTATUS Status,SubStatus; PUCHAR pEncodedTicket = NULL; jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; jobject ticketFlags, startTime, endTime, krbCreds = NULL; jobject authTime, renewTillTime, hostAddresses = NULL; UNICODE_STRING Target = {0}; UNICODE_STRING Target2 = {0}; PDOMAIN_CONTROLLER_INFO DomainControllerInfo = NULL; WCHAR *tgtName = L"krbtgt"; WCHAR *fullName; while (TRUE) { if (krbcredsConstructor == 0) { krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>", "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); if (krbcredsConstructor == 0) { printf("Couldn't find com.ibm.security.krb5.Credentials constructor\n"); break; } } //printf("Found KrbCreds constructor\n"); // // Get the logon handle and package ID from the // Kerberos package // if(!PackageConnectLookup(&LogonHandle, &PackageId)) break; #ifdef DEBUG printf("Got handle to Kerberos package\n"); #endif /* DEBUG */ //InitUnicodeString(&Target2, L"krbtgt"); // this doesn't work 'cause I need the domain name too // OK, I don't give up that easily // Go get the current domain name errorCode = DsGetDcName( (LPCTSTR) NULL, // machine name (LPCTSTR) NULL, // DomainName, if NULL, I'm asking what it is (GUID *) NULL, // DomainGuid, (LPCTSTR) NULL, // SiteName, DS_GC_SERVER_REQUIRED, //Flags &DomainControllerInfo); if (errorCode != NO_ERROR) { printf("DsGetDcName returned %d\n", errorCode); break; } #ifdef DEBUG printf("The domain name is %S\n", DomainControllerInfo->DomainName); #endif /* DEBUG */ // Build a fully-qualified name fullName = (WCHAR *) LocalAlloc(LMEM_ZEROINIT,((wcslen(tgtName)+wcslen(L"/")+wcslen(DomainControllerInfo->DomainName)) * sizeof(WCHAR) + sizeof(UNICODE_NULL))); wcscat(fullName, tgtName); wcscat(fullName, L"/"); wcscat(fullName, DomainControllerInfo->DomainName); #ifdef DEBUG printf("The fully-qualified name is %S\n", fullName); #endif /* DEBUG */ InitUnicodeString(&Target2, fullName); CacheRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST)); CacheRequest->MessageType = KerbRetrieveEncodedTicketMessage ; Target.Buffer = (LPWSTR) (CacheRequest + 1); Target.Length = Target2.Length; Target.MaximumLength = Target2.MaximumLength; CopyMemory( Target.Buffer, Target2.Buffer, Target2.Length ); CacheRequest->TargetName = Target; CacheRequest->EncryptionType = KERB_ETYPE_DES_CBC_MD5; // mdu Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, CacheRequest, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST), (PVOID *) &CacheResponse, &rspSize, &SubStatus ); #ifdef DEBUG printf("Response size is %d\n", rspSize); #endif /* DEBUG */ LocalFree(fullName); if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) { if (!LSA_SUCCESS(Status)) { ShowNTError("LsaCallAuthenticationPackage", Status); } else { ShowNTError("Protocol status", SubStatus); } break; } // Now we need to skip over most of the junk in the buffer to get to the ticket // Here's what we're looking at... /* typedef struct _KERB_RETRIEVE_TKT_RESPONSE { KERB_EXTERNAL_TICKET Ticket; } KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE; typedef struct _KERB_EXTERNAL_TICKET { PKERB_EXTERNAL_NAME ServiceName; PKERB_EXTERNAL_NAME TargetName; PKERB_EXTERNAL_NAME ClientName; UNICODE_STRING DomainName; UNICODE_STRING TargetDomainName; UNICODE_STRING AltTargetDomainName; KERB_CRYPTO_KEY SessionKey; ULONG TicketFlags; ULONG Flags; LARGE_INTEGER KeyExpirationTime; LARGE_INTEGER StartTime; LARGE_INTEGER EndTime; LARGE_INTEGER RenewUntil; LARGE_INTEGER TimeSkew; ULONG EncodedTicketSize; PUCHAR EncodedTicket; <========== Here's the good stuff } KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET; typedef struct _KERB_EXTERNAL_NAME { SHORT NameType; USHORT NameCount; UNICODE_STRING Names[ANYSIZE_ARRAY]; } KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME; typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef struct KERB_CRYPTO_KEY { LONG KeyType; ULONG Length; PUCHAR Value; } KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY; */ // Build a com.ibm.security.krb5.Ticket ticket = BuildTicket(env, CacheResponse->Ticket.EncodedTicket, CacheResponse->Ticket.EncodedTicketSize); if (ticket == NULL) { break; } // OK, have a Ticket, now need to get the client name clientPrincipal = BuildClientPrincipal(env, CacheResponse->Ticket.ClientName); // mdu if (clientPrincipal == NULL) break; // and the "name" of tgt targetPrincipal = BuildTGSPrincipal(env, CacheResponse->Ticket.TargetDomainName); // mdu if (targetPrincipal == NULL) break; // Get the encryption key encryptionKey = BuildEncryptionKey(env, &(CacheResponse->Ticket.SessionKey)); if (encryptionKey == NULL) break; // and the ticket flags ticketFlags = BuildTicketFlags(env, &(CacheResponse->Ticket.TicketFlags)); if (ticketFlags == NULL) break; // Get the start time startTime = BuildKerberosTime(env, &(CacheResponse->Ticket.StartTime)); if (startTime == NULL) break; /* * mdu: No point storing the eky expiration time in the auth * time field. Set it to be same as startTime. Looks like * windows does not have post-dated tickets. */ authTime = startTime; // and the end time endTime = BuildKerberosTime(env, &(CacheResponse->Ticket.EndTime)); if (endTime == NULL) break; // Get the renew till time renewTillTime = BuildKerberosTime(env, &(CacheResponse->Ticket.RenewUntil)); if (renewTillTime == NULL) break; // and now go build a KrbCreds object krbCreds = (*env)->NewObject( env, krbcredsClass, krbcredsConstructor, ticket, clientPrincipal, targetPrincipal, encryptionKey, ticketFlags, authTime, // mdu startTime, endTime, renewTillTime, //mdu hostAddresses); break; } // end of WHILE if (DomainControllerInfo != NULL) { NetApiBufferFree(DomainControllerInfo); } if (CacheResponse != NULL) { LsaFreeReturnBuffer(CacheResponse); } if (CacheRequest) { LocalFree(CacheRequest); } return krbCreds; }