All to change krb5_get_credentials() ..
authorChris Provenzano <proven@mit.edu>
Thu, 23 Feb 1995 13:35:36 +0000 (13:35 +0000)
committerChris Provenzano <proven@mit.edu>
Thu, 23 Feb 1995 13:35:36 +0000 (13:35 +0000)
* send_tgs.c (krb5_send_tgs()) Added check for a valid krb5_creds * arg.

* mk_req_ext.c (krb5_mk_req_extended()) Require caller to pass in a
valid krb5_creds * arg, and removed kdc_options krb5_flags
and krb5_ccache from arg list.
* send_tgs.c (krb5_send_tgs())
* sendauth.c (krb5_sendauth())
Fix calls to krb5_mk_req_extended()

* gc_frm_kdc.c (krb5_get_cred_from_kdc()) Changed krb5_creds * in/out
arg to be an in only arg and added krb5_creds ** out arg.

* gc_via_tgt.c (krb5_get_cred_via_tgt()) Changed krb5_creds * in/out
arg to be an in only arg and added krb5_creds ** out arg.

* gc_2tgt.c (krb5_get_cred_via_2tgt()) Changed krb5_creds * in/out
arg to be an in only arg and added krb5_creds ** out arg.

* int-proto.h Updated prototypes for krb5_get_cred_via_tgt() and
krb5_get_cred_via_2tgt().

* get_creds.c (krb5_get_credentials()) Changed krb5_creds * in/out
arg to be an in only arg and added krb5_creds ** out arg.
* sendauth.c (krb5_sendauth())
Routines that also require krb5_creds * in/out arg to be
appropriately changed because krb5_get_credentials() changed.
* gc_frm_kdc.c (krb5_get_cred_from_kdc())
* get_fcreds.c (krb5_get_for_creds())
* mk_req.c (krb5_mk_req())
Other routines that needed adjusting because
krb5_get_credentials() changed but didn't need an API change.

* int-proto.h Don't prototype krb5_get_cred_via_tgt() twice. Use the
second to prototype krb5_get_cred_via_2tgt().

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4993 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/gc_2tgt.c
src/lib/krb5/krb/gc_frm_kdc.c
src/lib/krb5/krb/gc_via_tgt.c
src/lib/krb5/krb/get_creds.c
src/lib/krb5/krb/get_fcreds.c
src/lib/krb5/krb/int-proto.h
src/lib/krb5/krb/mk_req.c
src/lib/krb5/krb/mk_req_ext.c
src/lib/krb5/krb/send_tgs.c
src/lib/krb5/krb/sendauth.c

index 3f5518254640cd5376cda239ec618f981c0f212d..8223b84a9a09e3654f11bafd6032380be19ccac2 100644 (file)
@@ -3,6 +3,43 @@ Tue Feb 21 23:38:34 1995  Theodore Y. Ts'o  (tytso@dcl)
        * mk_cred.c (krb5_mk_cred): Fix argument type to
                krb5_free_cred_enc_part().
 
+Thu Feb 16 00:22:03 1995 Chris Provenzano  (proven@mit.edu)
+
+       * send_tgs.c (krb5_send_tgs()) Added check for a valid krb5_creds * arg.
+
+       * mk_req_ext.c (krb5_mk_req_extended()) Require caller to pass in a
+               valid krb5_creds * arg, and removed kdc_options krb5_flags
+               and krb5_ccache from arg list.
+       * send_tgs.c (krb5_send_tgs())
+       * sendauth.c (krb5_sendauth())
+               Fix calls to krb5_mk_req_extended()
+
+       * gc_frm_kdc.c (krb5_get_cred_from_kdc()) Changed krb5_creds * in/out
+               arg to be an in only arg and added krb5_creds ** out arg.
+               
+       * gc_via_tgt.c (krb5_get_cred_via_tgt()) Changed krb5_creds * in/out
+               arg to be an in only arg and added krb5_creds ** out arg.
+
+       * gc_2tgt.c (krb5_get_cred_via_2tgt()) Changed krb5_creds * in/out
+               arg to be an in only arg and added krb5_creds ** out arg.
+
+       * int-proto.h Updated prototypes for krb5_get_cred_via_tgt() and
+               krb5_get_cred_via_2tgt().
+
+       * get_creds.c (krb5_get_credentials()) Changed krb5_creds * in/out
+               arg to be an in only arg and added krb5_creds ** out arg.
+       * sendauth.c (krb5_sendauth())
+               Routines that also require krb5_creds * in/out arg to be 
+               appropriately changed because krb5_get_credentials() changed.
+       * gc_frm_kdc.c (krb5_get_cred_from_kdc())
+       * get_fcreds.c (krb5_get_for_creds())
+       * mk_req.c (krb5_mk_req())
+               Other routines that needed adjusting because 
+               krb5_get_credentials() changed but didn't need an API change.
+
+       * int-proto.h Don't prototype krb5_get_cred_via_tgt() twice. Use the
+               second to prototype krb5_get_cred_via_2tgt().
+
 Mon Feb 13 20:25:20 1995  Theodore Y. Ts'o  (tytso@dcl)
 
        * get_in_tkt.c (krb5_get_in_tkt): Fix memory leak --- the default
index 8cf6be0e9a5789e63449047858f68c50b29aafd2..7503ee76fcd462118a29b780f3cc351b0481b92e 100644 (file)
 #include "int-proto.h"
 
 krb5_error_code
-krb5_get_cred_via_2tgt (context, tgt, kdcoptions, sumtype, cred)
+krb5_get_cred_via_2tgt (context, tgt, kdcoptions, sumtype, in_cred, out_cred)
     krb5_context context;
     krb5_creds *tgt;
     const krb5_flags kdcoptions;
     const krb5_cksumtype sumtype;
-    register krb5_creds * cred;
+    krb5_creds * in_cred;
+    krb5_creds ** out_cred;
 {
     krb5_error_code retval;
 #if 0
@@ -49,20 +50,20 @@ krb5_get_cred_via_2tgt (context, tgt, kdcoptions, sumtype, cred)
     krb5_response tgsrep;
     krb5_enctype etype;
 
-    /* tgt->client must be equal to cred->client */
+    /* tgt->client must be equal to in_cred->client */
     /* tgt->server must be equal to krbtgt/realmof(cred->client) */
-    if (!krb5_principal_compare(context, tgt->client, cred->client))
+    if (!krb5_principal_compare(context, tgt->client, in_cred->client))
        return KRB5_PRINC_NOMATCH;
 
     if (!tgt->ticket.length)
        return(KRB5_NO_TKT_SUPPLIED);
 
-    if (!cred->second_ticket.length)
+    if (!in_cred->second_ticket.length)
        return(KRB5_NO_2ND_TKT);
 
 #if 0  /* What does this do? */
-    if (retval = krb5_tgtname(context, krb5_princ_realm(cred->server),
-                             krb5_princ_realm(context, cred->client), &tempprinc))
+    if (retval = krb5_tgtname(context, krb5_princ_realm(in_cred->server),
+                             krb5_princ_realm(context, in_cred->client), &tempprinc))
        return(retval);
 
     if (!krb5_principal_compare(context, tempprinc, tgt->server)) {
@@ -75,14 +76,11 @@ krb5_get_cred_via_2tgt (context, tgt, kdcoptions, sumtype, cred)
     if (!(kdcoptions & KDC_OPT_ENC_TKT_IN_SKEY))
        return KRB5_INVALID_FLAGS;
 
-    if (retval = krb5_send_tgs(context, kdcoptions, &cred->times, NULL, 
-                              sumtype,
-                              cred->server,
-                              tgt->addresses,
-                              cred->authdata,
+    if (retval = krb5_send_tgs(context, kdcoptions, &in_cred->times, NULL, 
+                              sumtype, in_cred->server, tgt->addresses,
+                              in_cred->authdata,
                               0,               /* no padata */
-                              &cred->second_ticket,
-                              tgt, &tgsrep))
+                              &in_cred->second_ticket, tgt, &tgsrep))
        return retval;
 
     if (tgsrep.message_type != KRB5_TGS_REP)
@@ -120,58 +118,71 @@ krb5_get_cred_via_2tgt (context, tgt, kdcoptions, sumtype, cred)
        retval = KRB5_KDCREP_MODIFIED;
        goto errout;
     }
-    /* put pieces into cred-> */
-    if (cred->keyblock.contents) {
-       memset(&cred->keyblock.contents, 0, cred->keyblock.length);
-       krb5_xfree(cred->keyblock.contents);
+
+    /*
+     * get a cred structure 
+     * The caller is responsible for cleaning up 
+     */
+    if (((*out_cred) = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL) {
+       retval = ENOMEM;
+       goto errout;
+    }
+
+    /* Copy the client straig from in_cred */
+    if (retval = krb5_copy_principal(context, in_cred->client, 
+                                    &(*out_cred)->client)) {
+       goto errout;
     }
-    cred->keyblock.magic = KV5M_KEYBLOCK;
-    cred->keyblock.etype = dec_rep->ticket->enc_part.etype;
-    if (retval = krb5_copy_keyblock_contents(context, dec_rep->enc_part2->session,
-                                            &cred->keyblock))
+
+    /* put pieces into out_cred-> */
+    (*out_cred)->keyblock.magic = KV5M_KEYBLOCK;
+    (*out_cred)->keyblock.etype = dec_rep->ticket->enc_part.etype;
+    if (retval = krb5_copy_keyblock_contents(context, 
+                                            dec_rep->enc_part2->session,
+                                            &(*out_cred)->keyblock))
        goto errout;
 
     /* Should verify that the ticket is what we asked for. */
-    cred->times = dec_rep->enc_part2->times;
-    cred->ticket_flags = dec_rep->enc_part2->flags;
-    cred->is_skey = TRUE;
-    if (cred->addresses)
-       krb5_free_addresses(context, cred->addresses);
+    (*out_cred)->times = dec_rep->enc_part2->times;
+    (*out_cred)->ticket_flags = dec_rep->enc_part2->flags;
+    (*out_cred)->is_skey = TRUE;
     if (dec_rep->enc_part2->caddrs)
        retval = krb5_copy_addresses(context, dec_rep->enc_part2->caddrs,
-                                    &cred->addresses);
+                                    &(*out_cred)->addresses);
     else
        /* no addresses in the list means we got what we had */
-       retval = krb5_copy_addresses(context, tgt->addresses, &cred->addresses);
+       retval = krb5_copy_addresses(context, tgt->addresses, &(*out_cred)->addresses);
     if (retval)
            goto errout;
     
-    if (cred->server)
-       krb5_free_principal(context, cred->server);
     if (retval = krb5_copy_principal(context, dec_rep->enc_part2->server,
-                                    &cred->server))
+                                    &(*out_cred)->server))
        goto errout;
 
     if (retval = encode_krb5_ticket(dec_rep->ticket, &scratch))
        goto errout;
 
-    cred->ticket = *scratch;
+    (*out_cred)->ticket = *scratch;
     krb5_xfree(scratch);
 
 errout:
     if (retval) {
-       if (cred->keyblock.contents) {
-           memset((char *)cred->keyblock.contents, 0, cred->keyblock.length);
-           krb5_xfree(cred->keyblock.contents);
-           cred->keyblock.contents = 0;
-       }
-       if (cred->addresses) {
-           krb5_free_addresses(context, cred->addresses);
-           cred->addresses = 0;
-       }
-       if (cred->server) {
-           krb5_free_principal(context, cred->server);
-           cred->server = 0;
+       if (*out_cred) {
+           if ((*out_cred)->keyblock.contents) {
+               memset((*out_cred)->keyblock.contents, 0, 
+                  (*out_cred)->keyblock.length);
+               krb5_xfree((*out_cred)->keyblock.contents);
+               (*out_cred)->keyblock.contents = 0;
+           }
+           if ((*out_cred)->addresses) {
+               krb5_free_addresses(context, (*out_cred)->addresses);
+               (*out_cred)->addresses = 0;
+           }
+           if ((*out_cred)->server) {
+               krb5_free_principal(context, (*out_cred)->server);
+               (*out_cred)->server = 0;
+           }
+           krb5_free_creds(context, *out_cred);
        }
     }
     memset((char *)dec_rep->enc_part2->session->contents, 0,
index 5b3a909706b38dc7a098f17f2135f00a299358e0..865d0739563e8a1a549d8db2163bca5140026f66 100644 (file)
@@ -65,16 +65,17 @@ extern krb5_cksumtype krb5_kdc_req_sumtype;
 #define TGT_ETYPE \
       krb5_keytype_array[tgt.keyblock.keytype]->system->proto_enctype;
 
-krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
+krb5_error_code krb5_get_cred_from_kdc(context, ccache, in_cred, out_cred, tgts)
     krb5_context context;
     krb5_ccache ccache;
-    krb5_creds  *cred;
+    krb5_creds  *in_cred;
+    krb5_creds  **out_cred;
     krb5_creds  ***tgts;
 {
   krb5_creds      **ret_tgts = NULL;
   int             ntgts = 0;
 
-  krb5_creds      tgt, tgtq;
+  krb5_creds      tgt, tgtq, *tgtr = NULL;
   krb5_enctype    etype;
   krb5_error_code retval;
   krb5_principal  int_server = NULL;    /* Intermediate server for request */
@@ -107,12 +108,12 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
    * (the ticket may be issued by some other intermediate
    *  realm's KDC; so we use KRB5_TC_MATCH_SRV_NAMEONLY)
    */
-  if (retval = krb5_copy_principal(context, cred->client, &tgtq.client))
+  if (retval = krb5_copy_principal(context, in_cred->client, &tgtq.client))
       goto cleanup;
 
   /* get target tgt from cache */
-  if (retval = krb5_tgtname(context, krb5_princ_realm(context, cred->server),
-                            krb5_princ_realm(context, cred->client),
+  if (retval = krb5_tgtname(context, krb5_princ_realm(context, in_cred->server),
+                            krb5_princ_realm(context, in_cred->client),
                             &int_server)) {
       goto cleanup;
   }
@@ -145,15 +146,15 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
     krb5_free_principal(context, int_server);
     int_server = NULL;
     if (retval = krb5_tgtname(context, 
-                             krb5_princ_realm(context, cred->client),
-                              krb5_princ_realm(context, cred->client),
+                             krb5_princ_realm(context, in_cred->client),
+                              krb5_princ_realm(context, in_cred->client),
                               &int_server)) {
        goto cleanup;
     }
   
     krb5_free_cred_contents(context, &tgtq);
     memset((char *)&tgtq, 0, sizeof(tgtq));
-    if(retval = krb5_copy_principal(context, cred->client, &tgtq.client))
+    if(retval = krb5_copy_principal(context, in_cred->client, &tgtq.client))
        goto cleanup;
     if(retval = krb5_copy_principal(context, int_server, &tgtq.server))
        goto cleanup;
@@ -168,8 +169,8 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
     /* get a list of realms to consult */
   
     if (retval = krb5_walk_realm_tree(context, 
-                                     krb5_princ_realm(context, cred->client),
-                                      krb5_princ_realm(context, cred->server),
+                                     krb5_princ_realm(context,in_cred->client),
+                                      krb5_princ_realm(context,in_cred->server),
                                       &tgs_list, 
                                       KRB5_REALM_BRANCH_CHAR)) {
        goto cleanup;
@@ -213,7 +214,7 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
       krb5_free_principal(context, int_server);
       int_server = NULL;
       if (retval = krb5_tgtname(context, 
-                               krb5_princ_realm(context, cred->server),
+                               krb5_princ_realm(context, in_cred->server),
                                krb5_princ_realm(context, *top_server),
                                &int_server)) {
          goto cleanup;
@@ -252,7 +253,7 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
        if(retval = krb5_get_cred_via_tgt(context, &tgt,
                                          FLAGS2OPTS(tgtq.ticket_flags),
                                          krb5_kdc_req_sumtype,
-                                         &tgtq)) {
+                                         &tgtq, &tgtr)) {
              
        /*
        * couldn't get one so now loop backwards through the realms
@@ -283,8 +284,7 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
 
            if(retval = krb5_cc_retrieve_cred(context, ccache,
                                              KRB5_TC_MATCH_SRV_NAMEONLY,
-                                             &tgtq,
-                                             &tgt)) {
+                                             &tgtq, &tgt)) {
              if (retval != KRB5_CC_NOTFOUND) {
                  goto cleanup;
              }
@@ -299,9 +299,9 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
              krb5_free_cred_contents(context, &tgtq);
              memset(&tgtq, 0, sizeof(tgtq));
              tgtq.times        = tgt.times;
-             if (retval = krb5_copy_principal(context, tgt.client, &tgtq.client))
+             if (retval = krb5_copy_principal(context,tgt.client,&tgtq.client))
                  goto cleanup;
-             if(retval = krb5_copy_principal(context, int_server, &tgtq.server))
+             if(retval = krb5_copy_principal(context,int_server,&tgtq.server))
                  goto cleanup;
              tgtq.is_skey      = FALSE;
              tgtq.ticket_flags = tgt.ticket_flags;
@@ -309,14 +309,16 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
              if (retval = krb5_get_cred_via_tgt(context, &tgt,
                                                  FLAGS2OPTS(tgtq.ticket_flags),
                                                  krb5_kdc_req_sumtype,
-                                                 &tgtq)) {
+                                                 &tgtq, &tgtr)) {
                  continue;
              }
              
              /* save tgt in return array */
-             if (retval = krb5_copy_creds(context, &tgtq, &ret_tgts[ntgts])) {
+             if (retval = krb5_copy_creds(context, tgtr, &ret_tgts[ntgts])) {
                  goto cleanup;
              }
+             krb5_free_creds(context, tgtr);
+             tgtr = NULL;
              
              tgt = *ret_tgts[ntgts++];
            }
@@ -342,7 +344,7 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
     
        for (next_server = top_server; *next_server; next_server++) {
             krb5_data *realm_1 = krb5_princ_component(context, next_server[0], 1);
-            krb5_data *realm_2 = krb5_princ_component(context, tgtq.server, 1);
+            krb5_data *realm_2 = krb5_princ_component(context, tgtr->server, 1);
             if (realm_1->length == realm_2->length &&
                 !memcmp(realm_1->data, realm_2->data, realm_1->length)) {
                break;
@@ -354,9 +356,11 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
            goto cleanup;
        }
 
-       if (retval = krb5_copy_creds(context, &tgtq, &ret_tgts[ntgts])) {
+       if (retval = krb5_copy_creds(context, tgtr, &ret_tgts[ntgts])) {
            goto cleanup;
        }
+       krb5_free_creds(context, tgtr);
+       tgtr = NULL;
     
         tgt = *ret_tgts[ntgts++];
 
@@ -375,25 +379,22 @@ krb5_error_code krb5_get_cred_from_kdc(context, ccache, cred, tgts)
   }
 
   etype = TGT_ETYPE;
-  if (cred->second_ticket.length) {
+  if (in_cred->second_ticket.length) {
       retval = krb5_get_cred_via_2tgt(context, &tgt,
                                      KDC_OPT_ENC_TKT_IN_SKEY |
                                      FLAGS2OPTS(tgt.ticket_flags),
-                                     etype,
-                                     krb5_kdc_req_sumtype,
-                                     cred);
-  }
-  else {
+                                     krb5_kdc_req_sumtype, in_cred, out_cred);
+  } else {
       retval = krb5_get_cred_via_tgt(context, &tgt,
-                                   FLAGS2OPTS(tgt.ticket_flags), 
-                                   krb5_kdc_req_sumtype,
-                                   cred);
+                                     FLAGS2OPTS(tgt.ticket_flags), 
+                                     krb5_kdc_req_sumtype, in_cred, out_cred);
   }
 
   /* cleanup and return */
 
 cleanup:
 
+  if (tgtr) krb5_free_creds(context, tgtr);
   if(tgs_list)  krb5_free_realm_tree(context, tgs_list);
   krb5_free_cred_contents(context, &tgtq); 
   if (int_server) krb5_free_principal(context, int_server); 
index 1e9b8da53b0e0716a6cf73c7a0651c0230214e93..620a50db261be6370d884dc19ce5d896dd8efa45 100644 (file)
 #include "int-proto.h"
 
 krb5_error_code
-krb5_get_cred_via_tgt (context, tgt, kdcoptions, sumtype, cred)
+krb5_get_cred_via_tgt (context, tgt, kdcoptions, sumtype, in_cred, out_cred)
     krb5_context context;
     krb5_creds * tgt;
     const krb5_flags kdcoptions;
     const krb5_cksumtype sumtype;
-    krb5_creds * cred;
+    krb5_creds * in_cred;
+    krb5_creds ** out_cred;
 {
     krb5_error_code retval;
     krb5_principal tempprinc;
     krb5_data *scratch;
-    krb5_enctype etype;
     krb5_kdc_rep *dec_rep;
     krb5_error *err_reply;
     krb5_response tgsrep;
 
-    /* tgt->client must be equal to cred->client */
-
-    if (!krb5_principal_compare(context, tgt->client, cred->client))
+    /* tgt->client must be equal to in_cred->client */
+    if (!krb5_principal_compare(context, tgt->client, in_cred->client))
        return KRB5_PRINC_NOMATCH;
 
     if (!tgt->ticket.length)
@@ -61,43 +60,36 @@ krb5_get_cred_via_tgt (context, tgt, kdcoptions, sumtype, cred)
     /* tgt->server must be equal to                      */
     /* krbtgt/realmof(cred->server)@realmof(tgt->server) */
 
-    if(retval = krb5_tgtname(context, 
-                    krb5_princ_realm(context, cred->server),
+    if (retval = krb5_tgtname(context, 
+                    krb5_princ_realm(context, in_cred->server),
                     krb5_princ_realm(context, tgt->server), &tempprinc))
        return(retval);
+
     if (!krb5_principal_compare(context, tempprinc, tgt->server)) {
-       krb5_free_principal(context, tempprinc);
-       return KRB5_PRINC_NOMATCH;
+       retval = KRB5_PRINC_NOMATCH;
+       goto error_5;
     }
-    krb5_free_principal(context, tempprinc);
 
-
-    if (retval = krb5_send_tgs(context, kdcoptions, &cred->times, NULL, 
-                              sumtype,
-                              cred->server,
-                              tgt->addresses,
-                              cred->authdata,
+    if (retval = krb5_send_tgs(context, kdcoptions, &in_cred->times, NULL, 
+                              sumtype, in_cred->server, tgt->addresses,
+                              in_cred->authdata,
                               0,               /* no padata */
                               0,               /* no second ticket */
                               tgt, &tgsrep))
-       return retval;
-
-#undef cleanup
-#define cleanup() free(tgsrep.response.data)
+       goto error_5;
 
     switch (tgsrep.message_type) {
     case KRB5_TGS_REP:
        break;
     case KRB5_ERROR:
     default:
-       if (!krb5_is_krb_error(&tgsrep.response)) {
-           retval = KRB5KRB_AP_ERR_MSG_TYPE;
-       } else
+       if (krb5_is_krb_error(&tgsrep.response))
            retval = decode_krb5_error(&tgsrep.response, &err_reply);
-       if (retval) {
-           cleanup();
-           return retval;              /* neither proper reply nor error! */
-       }
+       else
+           retval = KRB5KRB_AP_ERR_MSG_TYPE;
+
+       if (retval)                     /* neither proper reply nor error! */
+           goto error_4;
 
 #if 0
        /* XXX need access to the actual assembled request...
@@ -111,56 +103,47 @@ krb5_get_cred_via_tgt (context, tgt, kdcoptions, sumtype, cred)
            retval = err_reply->error + ERROR_TABLE_BASE_krb5;
 
        krb5_free_error(context, err_reply);
-       cleanup();
-       return retval;
+       goto error_4;
     }
 
-    etype = tgt->keyblock.etype;
-    retval = krb5_decode_kdc_rep(context, &tgsrep.response,
-                                &tgt->keyblock,
-                                etype, /* enctype */
-                                &dec_rep);
-    cleanup();
-    if (retval)
-       return retval;
-#undef cleanup
-#define cleanup() {\
-       memset((char *)dec_rep->enc_part2->session->contents, 0,\
-             dec_rep->enc_part2->session->length);\
-                 krb5_free_kdc_rep(context, dec_rep); }
+    if (retval = krb5_decode_kdc_rep(context, &tgsrep.response, &tgt->keyblock,
+                                    tgt->keyblock.etype, &dec_rep))
+       goto error_4;
 
     if (dec_rep->msg_type != KRB5_TGS_REP) {
        retval = KRB5KRB_AP_ERR_MSG_TYPE;
-       cleanup();
-       return retval;
+       goto error_3;
     }
     
     /* now it's decrypted and ready for prime time */
-
     if (!krb5_principal_compare(context, dec_rep->client, tgt->client)) {
-       cleanup();
-       return KRB5_KDCREP_MODIFIED;
+       retval = KRB5_KDCREP_MODIFIED;
+       goto error_3;
     }
-    /* put pieces into cred-> */
-    if (cred->keyblock.contents) {
-       memset(&cred->keyblock.contents, 0, cred->keyblock.length);
-       krb5_xfree(cred->keyblock.contents);
+
+    /* get a cred structure */
+    /* The caller is responsible for cleaning up */
+    if (((*out_cred) = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL) {
+       retval = ENOMEM;
+       goto error_2;
     }
-    if (retval = krb5_copy_keyblock_contents(context, dec_rep->enc_part2->session,
-                                            &cred->keyblock)) {
-       cleanup();
-       return retval;
+    memset((*out_cred), 0, sizeof(krb5_creds));
+
+    /* Copy the client straigt from in_cred */
+    if (retval = krb5_copy_principal(context, in_cred->client, 
+                                    &(*out_cred)->client)) {
+       goto error_2;
     }
-    cred->keyblock.etype = dec_rep->ticket->enc_part.etype;
-    memset((char *)dec_rep->enc_part2->session->contents, 0,
-         dec_rep->enc_part2->session->length);
 
-#undef cleanup
-#define cleanup() {\
-       memset((char *)cred->keyblock.contents, 0, cred->keyblock.length);\
-                 krb5_free_kdc_rep(context, dec_rep); }
+    /* put pieces into out_cred-> */
+    if (retval = krb5_copy_keyblock_contents(context, 
+                                            dec_rep->enc_part2->session,
+                                            &(*out_cred)->keyblock)) {
+       goto error_2;
+    }
 
-    cred->times = dec_rep->enc_part2->times;
+    (*out_cred)->keyblock.etype = dec_rep->ticket->enc_part.etype;
+    (*out_cred)->times = dec_rep->enc_part2->times;
 
 #if 0
     /* XXX probably need access to the request */
@@ -185,56 +168,57 @@ krb5_get_cred_via_tgt (context, tgt, kdcoptions, sumtype, cred)
        )
        retval = KRB5_KDCREP_MODIFIED;
 
-    if ((request.from == 0) &&
-       !in_clock_skew(dec_rep->enc_part2->times.starttime))
+    if (!request.from && !in_clock_skew(dec_rep->enc_part2->times.starttime)) {
        retval = KRB5_KDCREP_SKEW;
-    
-    if (retval) {
-       cleanup();
-       return retval;
+       goto error_1;
     }
     
 #endif
 
-    cred->ticket_flags = dec_rep->enc_part2->flags;
-    cred->is_skey = FALSE;
-    if (cred->addresses) {
-       krb5_free_addresses(context, cred->addresses);
-    }
+    (*out_cred)->ticket_flags = dec_rep->enc_part2->flags;
+    (*out_cred)->is_skey = FALSE;
     if (dec_rep->enc_part2->caddrs) {
        if (retval = krb5_copy_addresses(context, dec_rep->enc_part2->caddrs,
-                                        &cred->addresses)) {
-           cleanup();
-           return retval;
+                                        &(*out_cred)->addresses)) {
+           goto error_1;
        }
     } else {
        /* no addresses in the list means we got what we had */
        if (retval = krb5_copy_addresses(context, tgt->addresses,
-                                        &cred->addresses)) {
-           cleanup();
-           return retval;
+                                        &(*out_cred)->addresses)) {
+           goto error_1;
        }
     }
-    /*
-     * Free cred->server before overwriting it.
-     */
-    if (cred->server)
-       krb5_free_principal(context, cred->server);
     if (retval = krb5_copy_principal(context, dec_rep->enc_part2->server,
-                                    &cred->server)) {
-       cleanup();
-       return retval;
+                                    &(*out_cred)->server)) {
+       goto error_1;
     }
 
     if (retval = encode_krb5_ticket(dec_rep->ticket, &scratch)) {
-       cleanup();
-       krb5_free_addresses(context, cred->addresses);
-       return retval;
+       krb5_free_addresses(context, (*out_cred)->addresses);
+       goto error_1;
     }
 
-    cred->ticket = *scratch;
+    (*out_cred)->ticket = *scratch;
     krb5_xfree(scratch);
 
+error_1:;
+    if (retval)
+       memset((*out_cred)->keyblock.contents, 0, (*out_cred)->keyblock.length);
+
+error_2:;
+    if (retval)
+       krb5_free_creds(context, *out_cred);
+
+error_3:;
+    memset(dec_rep->enc_part2->session->contents, 0,
+          dec_rep->enc_part2->session->length);
     krb5_free_kdc_rep(context, dec_rep);
+
+error_4:;
+    free(tgsrep.response.data);
+
+error_5:;
+    krb5_free_principal(context, tempprinc);
     return retval;
 }
index 21f043e15285c069721af60991ce998b79c5f010..14f44b2333193953a3ae4a542d5c19b5be9bdce5 100644 (file)
 #include <krb5/ext-proto.h>
 
 krb5_error_code
-krb5_get_credentials(context, options, ccache, creds)
+krb5_get_credentials(context, options, ccache, in_creds, out_creds)
     krb5_context context;
     const krb5_flags options;
     krb5_ccache ccache;
-    krb5_creds *creds;
+    krb5_creds *in_creds;
+    krb5_creds **out_creds;
 {
     krb5_error_code retval, rv2;
     krb5_creds **tgts;
-    krb5_creds mcreds, ncreds;
+    krb5_creds *ncreds;
+    krb5_creds mcreds;
     krb5_flags fields;
 
-    if (!creds || !creds->server || !creds->client)
-           return -EINVAL;
+    if (!in_creds || !in_creds->server || !in_creds->client)
+        return -EINVAL;
 
-    memset((char *)&mcreds, 0, sizeof(mcreds));
-    mcreds.server = creds->server;
-    mcreds.client = creds->client;
-    mcreds.times.endtime = creds->times.endtime;
-    mcreds.keyblock = creds->keyblock;
-    mcreds.authdata = creds->authdata;
+    memset((char *)&mcreds, 0, sizeof(krb5_creds));
+    mcreds.times.endtime = in_creds->times.endtime;
+    mcreds.keyblock = in_creds->keyblock;
+    mcreds.authdata = in_creds->authdata;
+    mcreds.server = in_creds->server;
+    mcreds.client = in_creds->client;
     
     fields = KRB5_TC_MATCH_TIMES /*XXX |KRB5_TC_MATCH_SKEY_TYPE */
        | KRB5_TC_MATCH_AUTHDATA;
@@ -73,20 +75,28 @@ krb5_get_credentials(context, options, ccache, creds)
           session key */
        fields |= KRB5_TC_MATCH_2ND_TKT|KRB5_TC_MATCH_IS_SKEY;
        mcreds.is_skey = TRUE;
-       mcreds.second_ticket = creds->second_ticket;
-       if (!creds->second_ticket.length)
+       mcreds.second_ticket = in_creds->second_ticket;
+       if (!in_creds->second_ticket.length)
            return KRB5_NO_2ND_TKT;
     }
 
-    retval = krb5_cc_retrieve_cred(context, ccache, fields, &mcreds, &ncreds);
-    if (retval == 0) {
-           krb5_free_cred_contents(context, creds);
-           *creds = ncreds;
+    if ((ncreds = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL)
+       return -ENOMEM;
+
+    memset((char *)ncreds, 0, sizeof(krb5_creds));
+
+    /* The caller is now responsible for cleaning up in_creds */
+    if (retval = krb5_cc_retrieve_cred(context,ccache,fields,&mcreds,ncreds)) {
+       krb5_xfree(ncreds);
+       ncreds = in_creds;
+    } else {
+       *out_creds = ncreds;
     }
+
     if (retval != KRB5_CC_NOTFOUND || options & KRB5_GC_CACHED)
        return retval;
 
-    retval = krb5_get_cred_from_kdc(context, ccache, creds, &tgts);
+    retval = krb5_get_cred_from_kdc(context, ccache, ncreds, out_creds, &tgts);
     if (tgts) {
        register int i = 0;
        while (tgts[i]) {
@@ -99,6 +109,6 @@ krb5_get_credentials(context, options, ccache, creds)
        krb5_free_tgt_creds(context, tgts);
     }
     if (!retval)
-       retval = krb5_cc_store_cred(context, ccache, creds);
+       retval = krb5_cc_store_cred(context, ccache, *out_creds);
     return retval;
 }
index a7cfda724f4cd0eb29b20b696355974e8e22e33f..b5fea089dd9295ab7230b22aeea970f4a230e438 100644 (file)
@@ -143,10 +143,8 @@ krb5_get_for_creds(context, sumtype, rhost, client, enc_key,
        goto errout;
 
     /* fetch tgt directly from cache */
-    retval = krb5_cc_retrieve_cred (context, cc,
-                                   KRB5_TC_MATCH_SRV_NAMEONLY,
-                                   &creds,
-                                   &tgt);
+    retval = krb5_cc_retrieve_cred (context, cc, KRB5_TC_MATCH_SRV_NAMEONLY,
+                                   &creds, &tgt);
     krb5_cc_close(context, cc);
     if (retval)
        goto errout;
@@ -168,10 +166,7 @@ krb5_get_for_creds(context, sumtype, rhost, client, enc_key,
       kdcoptions &= ~(KDC_OPT_FORWARDABLE);
 
     if (retval = krb5_send_tgs(context, kdcoptions, &creds.times, NULL, 
-                              sumtype,
-                              tgt.server,
-                              addrs,
-                              creds.authdata,
+                              sumtype, tgt.server, addrs, creds.authdata,
                               0,               /* no padata */
                               0,               /* no second ticket */
                               &tgt, &tgsrep))
index fcf739acb971dc2b3c808ef104bec281f14a47aa..0a08e39cdc866fe48255db31741327a881a1106f 100644 (file)
@@ -38,13 +38,15 @@ krb5_error_code krb5_get_cred_via_tgt
                   krb5_creds *,
                   const krb5_flags,
                   const krb5_cksumtype,
-                  krb5_creds * ));
-krb5_error_code krb5_get_cred_via_tgt
+                  krb5_creds *,
+                  krb5_creds **));
+krb5_error_code krb5_get_cred_via_2tgt
        PROTOTYPE((krb5_context context,
                   krb5_creds *,
                   const krb5_flags,
                   const krb5_cksumtype,
-                  krb5_creds * ));
+                  krb5_creds *,
+                  krb5_creds **));
 
 #endif /* KRB5_INT_FUNC_PROTO__ */
 
index c99aa463b56bc3d1fbf35c5e7250b0e51f899941..178b2dd29576a77b7a7d7fd30d11ab1d4bd5a15a 100644 (file)
@@ -60,6 +60,7 @@ krb5_mk_req(context, server, ap_req_options, checksum, ccache, outbuf)
     krb5_data *outbuf;
 {
     krb5_error_code retval;
+    krb5_creds * credsp;
     krb5_creds creds;
 
     /* obtain ticket & session key */
@@ -76,21 +77,18 @@ krb5_mk_req(context, server, ap_req_options, checksum, ccache, outbuf)
                                      preference */
 
     if (retval = krb5_get_credentials(context, krb5_kdc_default_options,
-                                     ccache,
-                                     &creds))
+                                     ccache, &creds, &credsp))
        goto errout;
 
-    retval = krb5_mk_req_extended(context, ap_req_options,
-                                 checksum,
-                                 krb5_kdc_default_options,
+    retval = krb5_mk_req_extended(context, ap_req_options, checksum,
                                  0,    /* no sequence number */
                                  0,    /* no sub-key */
-                                 ccache,
-                                 &creds,
+                                 credsp,
                                  0,    /* We don't need the authenticator */
                                  outbuf);
 
 errout:
     krb5_free_cred_contents(context, &creds);
+    krb5_free_creds(context, credsp);
     return retval;
 }
index b4d60177a6071388a5a92e1794635e475175101d..9b5c060ec8e675adf541ada0a8fb003d3d138555 100644 (file)
@@ -73,16 +73,14 @@ krb5_generate_authenticator PROTOTYPE((krb5_context,
                                       krb5_int32, krb5_authdata ** ));
 
 krb5_error_code
-krb5_mk_req_extended(context, ap_req_options, checksum, kdc_options,
-                    sequence, newkey, ccache, creds, authentp, outbuf)
+krb5_mk_req_extended(context, ap_req_options, checksum, sequence, 
+                    newkey, in_creds, authentp, outbuf)
     krb5_context context;
     const krb5_flags ap_req_options;
     const krb5_checksum *checksum;
-    const krb5_flags kdc_options;
     krb5_int32 sequence;
     krb5_keyblock **newkey;
-    krb5_ccache ccache;
-    krb5_creds *creds;
+    krb5_creds *in_creds;
     krb5_authenticator *authentp;
     krb5_data *outbuf;
 {
@@ -102,19 +100,17 @@ krb5_mk_req_extended(context, ap_req_options, checksum, kdc_options,
     scratch = 0;
     
     if ((ap_req_options & AP_OPTS_USE_SESSION_KEY) &&
-       !creds->ticket.length)
+       !in_creds->ticket.length)
        return(KRB5_NO_TKT_SUPPLIED);
 
-    if (!creds->ticket.length) {
-       /* go get creds */
-       if (retval = krb5_get_credentials(context, kdc_options,
-                                         ccache,
-                                         creds))
-           return(retval);
-    }
+    if (!in_creds->ticket.length) 
+       return(KRB5_NO_TKT_SUPPLIED);
+
+/*     if (retval = krb5_get_credentials(context, kdc_options,
+                                         ccache, in_creds, out_creds)) */
 
     /* we need a native ticket */
-    if (retval = decode_krb5_ticket(&creds->ticket, &request.ticket))
+    if (retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket))
        return(retval);
     
     /* verify a valid etype is available */
@@ -127,13 +123,15 @@ krb5_mk_req_extended(context, ap_req_options, checksum, kdc_options,
 
     request.ap_options = ap_req_options;
     if (newkey) {
-       if (retval = krb5_generate_subkey(context, &creds->keyblock, newkey))
+       if (retval = krb5_generate_subkey(context, &(in_creds)->keyblock, 
+                                         newkey))
            goto cleanup;
     }
 
-    if (retval = krb5_generate_authenticator(context, &authent, creds->client, checksum,
-                                            newkey ? *newkey : 0,
-                                            sequence, creds->authdata))
+    if (retval = krb5_generate_authenticator(context, &authent, 
+                                            (in_creds)->client, checksum,
+                                            newkey ? *newkey : 0, sequence, 
+                                            (in_creds)->authdata))
        goto cleanup;
        
     /* encode the authenticator */
@@ -175,7 +173,7 @@ krb5_mk_req_extended(context, ap_req_options, checksum, kdc_options,
     }
 
     /* do any necessary key pre-processing */
-    if (retval = krb5_process_key(context, &eblock, &creds->keyblock))
+    if (retval = krb5_process_key(context, &eblock, &(in_creds)->keyblock))
        goto cleanup;
 
     cleanup_key++;
index 27fde8f00cfeef23c1056351c5db01fb11329678..a5e118d389cea6b13df137e3c4759885cc5a9e8e 100644 (file)
@@ -39,8 +39,8 @@
  addrs, if non-NULL, is used for addresses " " "
  authorization_dat, if non-NULL, is used for authorization_dat " " "
  second_ticket, if required by options, is used for the 2nd ticket in the req.
usecred is used for the ticket & session key in the KRB_AP_REQ header " " "
- (the KDC realm is extracted from usecred->server's realm)
in_cred is used for the ticket & session key in the KRB_AP_REQ header " " "
+ (the KDC realm is extracted from in_cred->server's realm)
  
  The response is placed into *rep.
  rep->response.data is set to point at allocated storage which should be
@@ -50,7 +50,7 @@
  */
 krb5_error_code
 krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
-             authorization_data, padata, second_ticket, usecred, rep)
+             authorization_data, padata, second_ticket, in_cred, rep)
     krb5_context context;
     const krb5_flags kdcoptions;
     const krb5_ticket_times * timestruct;
@@ -61,7 +61,7 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
     krb5_authdata * const * authorization_data;
     krb5_pa_data * const * padata;
     const krb5_data * second_ticket;
-    krb5_creds * usecred;
+    krb5_creds * in_cred;
     krb5_response * rep;
 {
     krb5_error_code retval;
@@ -74,20 +74,14 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
     krb5_pa_data **combined_padata;
     krb5_pa_data ap_req_padata;
 
-    memset((char *)&tgsreq, 0, sizeof(tgsreq));
+    /* 
+     * in_creds MUST be a valid credential NOT just a partially filled in
+     * place holder for us to get credentials for the caller.
+     */
+    if (!in_cred->ticket.length)
+        return(KRB5_NO_TKT_SUPPLIED);
 
-    if (etypes) {
-       /* Check passed etypes and make sure they're valid. */
-       for (tgsreq.netypes = 0; etypes[tgsreq.netypes]; tgsreq.netypes++) {
-           if (!valid_etype(etypes[tgsreq.netypes]))
-               return KRB5_PROG_ETYPE_NOSUPP;
-       }
-       tgsreq.etype = (krb5_enctype *)etypes;
-    } else {
-        /* Get the default etypes */
-        krb5_get_default_in_tkt_etypes(context, &(tgsreq.etype));
-       for(tgsreq.netypes = 0; tgsreq.etype[tgsreq.netypes]; tgsreq.netypes++);
-    }
+    memset((char *)&tgsreq, 0, sizeof(tgsreq));
 
     tgsreq.kdc_options = kdcoptions;
     tgsreq.server = (krb5_principal) sname;
@@ -104,20 +98,19 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
 
     if (authorization_data) {
        /* need to encrypt it in the request */
-
        krb5_encrypt_block eblock;
 
        if (retval = encode_krb5_authdata(authorization_data, &scratch))
            return(retval);
-       krb5_use_cstype(context, &eblock, usecred->keyblock.etype);
-       tgsreq.authorization_data.etype = usecred->keyblock.etype;
+       krb5_use_cstype(context, &eblock, in_cred->keyblock.etype);
+       tgsreq.authorization_data.etype = in_cred->keyblock.etype;
        tgsreq.authorization_data.kvno = 0; /* ticket session key has */
                                            /* no version */
        tgsreq.authorization_data.ciphertext.length =
            krb5_encrypt_size(scratch->length, eblock.crypto_entry);
        /* add padding area, and zero it */
        if (!(scratch->data = realloc(scratch->data,
-                                     tgsreq.authorization_data.ciphertext.length))) {
+                             tgsreq.authorization_data.ciphertext.length))) {
            /* may destroy scratch->data */
            krb5_xfree(scratch);
            return ENOMEM;
@@ -129,13 +122,13 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
            krb5_free_data(context, scratch);
            return ENOMEM;
        }
-       if (retval = krb5_process_key(context, &eblock, &usecred->keyblock)) {
+       if (retval = krb5_process_key(context, &eblock, &in_cred->keyblock)) {
            krb5_free_data(context, scratch);
            return retval;
        }
        /* call the encryption routine */
        if (retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
-                                 (krb5_pointer) tgsreq.authorization_data.ciphertext.data,
+                 (krb5_pointer) tgsreq.authorization_data.ciphertext.data,
                                  scratch->length, &eblock, 0)) {
            (void) krb5_finish_key(context, &eblock);
            krb5_xfree(tgsreq.authorization_data.ciphertext.data);
@@ -148,62 +141,52 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
            return retval;
        }
     }
-#define cleanup_authdata() { if (tgsreq.authorization_data.ciphertext.data) {\
-       (void) memset(tgsreq.authorization_data.ciphertext.data, 0,\
-             tgsreq.authorization_data.ciphertext.length); \
-           krb5_xfree(tgsreq.authorization_data.ciphertext.data);}}
-
 
+    /* Get the encryption types list */
+    if (etypes) {
+       /* Check passed etypes and make sure they're valid. */
+       for (tgsreq.netypes = 0; etypes[tgsreq.netypes]; tgsreq.netypes++) {
+           if (!valid_etype(etypes[tgsreq.netypes]))
+               return KRB5_PROG_ETYPE_NOSUPP;
+       }
+       tgsreq.etype = (krb5_enctype *)etypes;
+    } else {
+        /* Get the default etypes */
+        krb5_get_default_in_tkt_etypes(context, &(tgsreq.etype));
+       for(tgsreq.netypes = 0; tgsreq.etype[tgsreq.netypes]; tgsreq.netypes++);
+    }
 
     if (second_ticket) {
-       if (retval = decode_krb5_ticket(second_ticket, &sec_ticket)) {
-           cleanup_authdata();
-           return retval;
-       }
+       if (retval = decode_krb5_ticket(second_ticket, &sec_ticket))
+           goto send_tgs_error_1;
        sec_ticket_arr[0] = sec_ticket;
        sec_ticket_arr[1] = 0;
        tgsreq.second_ticket = sec_ticket_arr;
     } else
        tgsreq.second_ticket = 0;
 
-
     /* encode the body; then checksum it */
-
-    retval = encode_krb5_kdc_req_body(&tgsreq, &scratch);
-    if (retval) {
-       if (sec_ticket)
-           krb5_free_ticket(context, sec_ticket);
-       cleanup_authdata();
-       return(retval);
-    }
+    if (retval = encode_krb5_kdc_req_body(&tgsreq, &scratch))
+       goto send_tgs_error_2;
 
     if (!(ap_checksum.contents = (krb5_octet *)
          malloc(krb5_checksum_size(context, sumtype)))) {
-       if (sec_ticket)
-           krb5_free_ticket(context, sec_ticket);
        krb5_free_data(context, scratch);
-       cleanup_authdata();
-       return ENOMEM;
+       retval = ENOMEM;
+       goto send_tgs_error_2;
     }
 
-    if (retval = krb5_calculate_checksum(context, sumtype,
-                                        scratch->data,
+    if (retval = krb5_calculate_checksum(context, sumtype, scratch->data,
                                         scratch->length,
-                                        (krb5_pointer) usecred->keyblock.contents,
-                                        usecred->keyblock.length,
+                                (krb5_pointer) in_cred->keyblock.contents,
+                                        in_cred->keyblock.length,
                                         &ap_checksum)) {
-       if (sec_ticket)
-           krb5_free_ticket(context, sec_ticket);
-       krb5_xfree(ap_checksum.contents);
        krb5_free_data(context, scratch);
-       cleanup_authdata();
-       return retval;
+       goto send_tgs_error_3;
     }
     /* done with body */
     krb5_free_data(context, scratch);
 
-#define cleanup() {krb5_xfree(ap_checksum.contents);\
-                  if (sec_ticket) krb5_free_ticket(context, sec_ticket);}
     /* attach ap_req to the tgsreq */
 
     /*
@@ -212,16 +195,12 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
     if (retval = krb5_mk_req_extended (context,
                                       0L /* no ap options */,
                                       &ap_checksum,
-                                      0L, /* don't need kdc_options for this */
                                       0, /* no initial sequence */
                                       0, /* no new key */
-                                      0, /* no ccache--already have creds */
-                                      usecred,
+                                      in_cred,
                                       0, /* don't need authenticator */
                                       &scratch2)) {
-       cleanup();
-       cleanup_authdata();
-       return retval;
+       goto send_tgs_error_3;
     }
 
     ap_req_padata.pa_type = KRB5_PADATA_AP_REQ;
@@ -235,10 +214,9 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
        for (counter = padata; *counter; counter++, i++);
        combined_padata = (krb5_pa_data **)malloc(i+2);
        if (!combined_padata) {
-           cleanup();
-           cleanup_authdata();
            krb5_xfree(ap_req_padata.contents);
-           return ENOMEM;
+           retval = ENOMEM;
+           goto send_tgs_error_3;
        }
        combined_padata[0] = &ap_req_padata;
        for (i = 1, counter = padata; *counter; counter++, i++)
@@ -247,10 +225,9 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
     } else {
        combined_padata = (krb5_pa_data **)malloc(2*sizeof(*combined_padata));
        if (!combined_padata) {
-           cleanup();
-           cleanup_authdata();
            krb5_xfree(ap_req_padata.contents);
-           return ENOMEM;
+           retval = ENOMEM;
+           goto send_tgs_error_3;
        }
        combined_padata[0] = &ap_req_padata;
        combined_padata[1] = 0;
@@ -259,35 +236,42 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
 
     /* the TGS_REQ is assembled in tgsreq, so encode it */
     if (retval = encode_krb5_tgs_req(&tgsreq, &scratch)) {
-       cleanup();
-       cleanup_authdata();
-       krb5_xfree(combined_padata);
        krb5_xfree(ap_req_padata.contents);
-       return(retval);
+       krb5_xfree(combined_padata);
+       goto send_tgs_error_3;
     }
-    if (sec_ticket)
-       krb5_free_ticket(context, sec_ticket);
-    cleanup_authdata();
-    krb5_xfree(combined_padata);
     krb5_xfree(ap_req_padata.contents);
-#undef cleanup_authdata
-#undef cleanup
-#define cleanup() {krb5_xfree(ap_checksum.contents);}
+    krb5_xfree(combined_padata);
 
     /* now send request & get response from KDC */
     retval = krb5_sendto_kdc(context, scratch, 
                             krb5_princ_realm(context, sname),
                             &rep->response);
     krb5_free_data(context, scratch);
-    cleanup();
-    if (retval) {
-       return retval;
+
+    if (retval == 0) {
+        if (krb5_is_tgs_rep(&rep->response))
+           rep->message_type = KRB5_TGS_REP;
+        else /* assume it's an error */
+           rep->message_type = KRB5_ERROR;
     }
-#undef cleanup
 
-    if (krb5_is_tgs_rep(&rep->response))
-       rep->message_type = KRB5_TGS_REP;
-    else /* assume it's an error */
-       rep->message_type = KRB5_ERROR;
-    return 0;
+send_tgs_error_3:;
+    krb5_xfree(ap_checksum.contents);
+
+send_tgs_error_2:;
+    if (sec_ticket) 
+       krb5_free_ticket(context, sec_ticket);
+
+send_tgs_error_1:;
+    if (etypes == NULL)
+       krb5_xfree(tgsreq.etype);
+    if (tgsreq.authorization_data.ciphertext.data) {
+       memset(tgsreq.authorization_data.ciphertext.data, 0,
+               tgsreq.authorization_data.ciphertext.length); 
+       krb5_xfree(tgsreq.authorization_data.ciphertext.data);
+    }
+
+
+    return retval;
 }
index ec320698e6eef06d083fbb34d7bfe56aa76f5621..f5a1394249e7aecbac60d8ab5d41702dea1d3f19 100644 (file)
@@ -47,13 +47,12 @@ static char *sendauth_version = "KRB5_SENDAUTH_V1.0";
 krb5_error_code
 krb5_sendauth(context,
              /* IN */
-             fd, appl_version, client, server, ap_req_options,
-             checksump,
+             fd, appl_version, client, server, ap_req_options, checksump,
+             in_creds,
              /* IN/OUT */
-             credsp, ccache,
+             ccache,
              /* OUT */
-             sequence, newkey,
-             error, rep_result)
+             sequence, newkey, error, rep_result, out_creds)
        krb5_context context;
        krb5_pointer    fd;
        char    *appl_version;
@@ -63,14 +62,17 @@ krb5_sendauth(context,
        krb5_int32      *sequence;
        krb5_keyblock   **newkey;
        krb5_checksum   *checksump;
-       krb5_creds      *credsp;
+       krb5_creds      *in_creds;
        krb5_ccache     ccache;
        krb5_error      **error;
        krb5_ap_rep_enc_part    **rep_result;
+       krb5_creds      **out_creds;
 {
        krb5_flags              kdc_options = krb5_kdc_default_options;
        krb5_octet              result;
        krb5_creds              creds;
+       krb5_creds *            credsp = NULL;
+       krb5_creds *            credspout = NULL;
        krb5_error_code         retval = 0;
        krb5_authenticator      authent;
        krb5_data               inbuf, outbuf;
@@ -118,17 +120,18 @@ krb5_sendauth(context,
        /*
         * See if we need to access the credentials cache
         */
-       if (!credsp || !credsp->ticket.length) {
+       if (!in_creds || !in_creds->ticket.length) {
                if (ccache)
                        use_ccache = ccache;
                else if (retval = krb5_cc_default(context, &use_ccache))
                        goto error_return;
        }
-       if (!credsp) {
+       if (!in_creds) {
                if (retval = krb5_copy_principal(context, server, &creds.server))
                        goto error_return;
                if (client)
-                       retval = krb5_copy_principal(context, client, &creds.client);
+                       retval = krb5_copy_principal(context, client, 
+                                                    &creds.client);
                else
                        retval = krb5_cc_get_principal(context, use_ccache,
                                                       &creds.client);
@@ -141,30 +144,31 @@ krb5_sendauth(context,
                /* creds.keyblock.keytype = 0; -- as well as this.
                                        zero means no session keytype
                                        preference */
-               credsp = &creds;
+               in_creds = &creds;
        }
-       if (!credsp->ticket.length) {
-               if (retval = krb5_get_credentials(context, kdc_options,
-                                                 use_ccache,
-                                                 credsp))
+       if (!in_creds->ticket.length) {
+           if (retval = krb5_get_credentials(context, kdc_options, use_ccache,
+                                             in_creds, &credsp))
                    goto error_return;
+           credspout = credsp;
+       } else {
+           credsp = in_creds;
        }
 
        /*
         * Generate a random sequence number
         */
        if (sequence &&
-           (retval = krb5_generate_seq_number(context, &credsp->keyblock, sequence))) 
+           (retval = krb5_generate_seq_number(context, &credsp->keyblock,
+                                              sequence))) 
            goto error_return;
 
        /*
         * OK, get the authentication header!
         */
        if (retval = krb5_mk_req_extended(context, ap_req_options, checksump,
-                                         kdc_options,
                                          sequence ? *sequence : 0, newkey,
-                                         use_ccache, credsp, &authent,
-                                         &outbuf))
+                                         credsp, &authent, &outbuf))
            goto error_return;
 
        /*
@@ -227,13 +231,16 @@ krb5_sendauth(context,
                krb5_free_ap_rep_enc_part(context, repl);
        }
        retval = 0;             /* Normal return */
+       if (out_creds) {
+               *out_creds = credsp;
+       }
 error_return:
+       if (credspout)
+               krb5_free_creds(context, credspout); 
        if (!ccache && use_ccache)
                krb5_cc_close(context, use_ccache);
-       krb5_free_cred_contents(context, &creds);
        krb5_free_authenticator_contents(context, &authent);
        return(retval);
-       
 }