Windows: Build against KerbCompatSDK instead of KFW
[openafs.git] / src / WINNT / aklog / aklog.c
index 3def007..ecfa5dd 100644 (file)
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _WIN64
-#define HAVE_KRB4 1
-#endif
-
 #include <afsconfig.h>
 #include <afs/param.h>
 #include <roken.h>
@@ -82,6 +78,7 @@
 #include <afs\pioctl_nt.h>
 #include <afs\smb_iocons.h>
 #include <WINNT\afsreg.h>
+#include <krbcompat_delayload.h>
 
 #define DONT_HAVE_GET_AD_TKT
 #define MAXSYMLINKS 255
@@ -197,9 +194,6 @@ static int use524 = FALSE;  /* use krb524? */
 static krb5_context context = 0;
 static krb5_ccache _krb425_ccache = 0;
 
-static char * (KRB5_CALLCONV *pkrb5_get_error_message)(krb5_context context, krb5_error_code code)=NULL;
-static void (KRB5_CALLCONV *pkrb5_free_error_message)(krb5_context context, char *s) = NULL;
-
 void akexit(int exit_code)
 {
     if (_krb425_ccache)
@@ -225,16 +219,13 @@ redirect_errors(const char *who, afs_int32 code, const char *fmt, va_list ap)
         int freestr = 0;
         char *str = (char *)afs_error_message(code);
         if (strncmp(str, "unknown", strlen(str)) == 0) {
-            if (pkrb5_get_error_message) {
-                str = pkrb5_get_error_message(NULL, code);
-                freestr = 1;
-            } else
-                str = (char *)error_message(code);
+            str = krb5_get_error_message(NULL, code);
+            freestr = 1;
         }
         fputs(str, stderr);
         fputs(" ", stderr);
         if (freestr)
-            pkrb5_free_error_message(NULL, str);
+            krb5_free_error_message(NULL, str);
     }
     if (fmt) {
         vfprintf(stderr, fmt, ap);
@@ -514,15 +505,17 @@ static int get_v5cred(krb5_context context,
     increds.client = client_principal;
     increds.times.endtime = 0;
        /* Ask for DES since that is what V4 understands */
-    increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
+    increds.session.keytype = ENCTYPE_DES_CBC_CRC;
 
     r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);
     if (r) {
         return((int)r);
     }
+#ifdef HAVE_KRB4
     /* This requires krb524d to be running with the KDC */
     if (c != NULL)
         r = krb5_524_convert_creds(context, *creds, c);
+#endif
 
     return((int)r);
 }
@@ -647,7 +640,6 @@ static int get_v5_user_realm(krb5_context context,char *realm)
 {
     static krb5_principal client_principal = 0;
     krb5_error_code code;
-    int i;
 
     if (!_krb425_ccache) {
         code = krb5_cc_default(context, &_krb425_ccache);
@@ -659,29 +651,24 @@ static int get_v5_user_realm(krb5_context context,char *realm)
         if (code)
             return(code);
     }
-    i = krb5_princ_realm(context, client_principal)->length;
-    if (i < REALM_SZ-1) i = REALM_SZ-1;
-    strncpy(realm,krb5_princ_realm(context, client_principal)->data,i);
-    realm[i] = 0;
+    strncpy(realm, krb5_principal_get_realm(context, client_principal), REALM_SZ - 1);
+    realm[REALM_SZ - 1] = 0;
     return(KSUCCESS);
 }
 
 static void
 copy_realm_of_ticket(krb5_context context, char * dest, size_t destlen, krb5_creds *v5cred) {
-    krb5_error_code code;
-    krb5_ticket *ticket;
+    Ticket ticket;
     size_t len;
+    int ret;
 
-    code = krb5_decode_ticket(&v5cred->ticket, &ticket);
-    if (code == 0) {
-        len = krb5_princ_realm(context, ticket->server)->length;
-        if (len > destlen - 1)
-            len = destlen - 1;
-
-        strncpy(dest, krb5_princ_realm(context, ticket->server)->data, len);
-        dest[len] = '\0';
+    ret = decode_Ticket(v5cred->ticket.data, v5cred->ticket.length,
+                        &ticket, &len);
+    if (ret == 0) {
+        strncpy(dest, ticket.realm, destlen - 1);
+        dest[destlen - 1] = '\0';
 
-        krb5_free_ticket(context, ticket);
+        free_Ticket(&ticket);
     }
 }
 
@@ -834,14 +821,10 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm)
         if ((status = get_v5_user_realm(context, realm_of_user)) != KSUCCESS) {
             char * msg;
 
-            if (pkrb5_get_error_message)
-                msg = pkrb5_get_error_message(context, status);
-            else
-                msg = (char *)error_message(status);
+            msg = krb5_get_error_message(context, status);
             fprintf(stderr, "%s: Couldn't determine realm of user: %s\n",
-                     progname, msg);
-            if (pkrb5_free_error_message)
-                pkrb5_free_error_message(context, msg);
+                    progname, msg);
+            krb5_free_error_message(context, msg);
             status = AKLOG_KERBEROS;
             goto done;
         }
@@ -968,19 +951,16 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm)
             printf("Kerberos error code returned by get_cred: %d\n", status);
 
         if (usev5) {
-            if (pkrb5_get_error_message)
-                msg = pkrb5_get_error_message(context, status);
-            else
-                msg = (char *)error_message(status);
+            msg = krb5_get_error_message(context, status);
         }
 #ifdef HAVE_KRB4
         else
             msg = krb_err_text(status);
 #endif
         fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n",
-                 progname, cell_to_use, msg?msg:"(unknown error)");
-        if (usev5 && pkrb5_free_error_message)
-            pkrb5_free_error_message(context, msg);
+                progname, cell_to_use, msg?msg:"(unknown error)");
+        if (usev5)
+            krb5_free_error_message(context, msg);
         status = AKLOG_KERBEROS;
         goto done;
     }
@@ -996,16 +976,17 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm)
          */
         char * p;
         int len;
+        const char *un;
 
-        len = min(v5cred->client->data[0].length,MAXKTCNAMELEN - 1);
-        strncpy(username, v5cred->client->data[0].data, len);
-        username[len] = '\0';
+        un = krb5_principal_get_comp_string(context, v5cred->client, 0);
+        strncpy(username, un, MAXKTCNAMELEN - 1);
+        username[MAXKTCNAMELEN - 1] = '\0';
 
-        if ( v5cred->client->length > 1 ) {
+        if ( krb5_principal_get_num_comp(context, v5cred->client) > 1 ) {
             strcat(username, ".");
             p = username + strlen(username);
-            len = min(v5cred->client->data[1].length, (unsigned int)(MAXKTCNAMELEN - strlen(username) - 1));
-            strncpy(p, v5cred->client->data[1].data, len);
+            len = (unsigned int)(MAXKTCNAMELEN - strlen(username) - 1);
+            strncpy(p, krb5_principal_get_comp_string(context, v5cred->client, 1), len);
             p[len] = '\0';
         }
 
@@ -1013,7 +994,7 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm)
         atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
         atoken.startTime = v5cred->times.starttime;
         atoken.endTime = v5cred->times.endtime;
-        memcpy(&atoken.sessionKey, v5cred->keyblock.contents, v5cred->keyblock.length);
+        memcpy(&atoken.sessionKey, v5cred->session.keyvalue.data, v5cred->session.keyvalue.length);
         atoken.ticketLen = v5cred->ticket.length;
         memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
     } else {
@@ -1099,9 +1080,9 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm)
     strcpy(aclient.instance, "");
 
     if (usev5 && !use524) {
-        int len = min(v5cred->client->realm.length,MAXKTCNAMELEN - 1);
-        strncpy(aclient.cell, v5cred->client->realm.data, len);
-        aclient.cell[len] = '\0';
+        strncpy(aclient.cell,
+                krb5_principal_get_realm(context, v5cred->client), MAXKTCNAMELEN - 1);
+        aclient.cell[MAXKTCNAMELEN - 1] = '\0';
     }
 #ifdef HAVE_KRB4
     else
@@ -1431,29 +1412,11 @@ static void usage(void)
     akexit(AKLOG_USAGE);
 }
 
-#ifndef _WIN64
-#define KRB5LIB "krb5_32.dll"
-#else
-#define KRB5LIB "krb5_64.dll"
-#endif
-void
-load_krb5_error_message_funcs(void)
-{
-    HINSTANCE h = LoadLibrary(KRB5LIB);
-    if (h) {
-        (FARPROC)pkrb5_get_error_message = GetProcAddress(h, "krb5_get_error_message");
-        (FARPROC)pkrb5_free_error_message = GetProcAddress(h, "krb5_free_error_message");
-    }
-}
-
 void
 validate_krb5_availability(void)
 {
-    HINSTANCE h = LoadLibrary(KRB5LIB);
-    if (h)
-        FreeLibrary(h);
-    else {
-        fprintf(stderr, "Kerberos for Windows library %s is not available.\n", KRB5LIB);
+    if (!DelayLoadHeimdal()) {
+        fprintf(stderr, "Kerberos for Windows or Heimdal is not available.\n");
         akexit(AKLOG_KFW_NOT_INSTALLED);
     }
 }
@@ -1642,7 +1605,6 @@ int main(int argc, char *argv[])
         validate_krb5_availability();
         if (krb5_init_context(&context))
             return(AKLOG_KERBEROS);
-        load_krb5_error_message_funcs();
     } else
         validate_krb4_availability();
     afs_set_com_err_hook(redirect_errors);