Handle picky windows RODC servers
[abartlet/lorikeet-heimdal.git/.git] / lib / krb5 / init_creds_pw.c
index f4437880757b9e30f0d9e448a6029ff8675d735b..29b882d053117c878022ab4af49669a5915c3778 100644 (file)
@@ -94,7 +94,7 @@ free_paid(krb5_context context, struct pa_info_data *ppaid)
        krb5_free_data(context, ppaid->s2kparams);
 }
 
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
 default_s2k_func(krb5_context context, krb5_enctype type,
                 krb5_const_pointer keyseed,
                 krb5_salt salt, krb5_data *s2kparms,
@@ -234,11 +234,12 @@ report_expiration (krb5_context context,
                   const char *str,
                   time_t now)
 {
-    char *p;
+    char *p = NULL;
 
-    asprintf (&p, "%s%s", str, ctime(&now));
-    (*prompter) (context, data, NULL, p, 0, NULL);
-    free (p);
+    if (asprintf(&p, "%s%s", str, ctime(&now)) < 0 || p == NULL)
+       return;
+    (*prompter)(context, data, NULL, p, 0, NULL);
+    free(p);
 }
 
 /*
@@ -562,10 +563,14 @@ change_password (krb5_context context,
                             &result_string);
     if (ret)
        goto out;
-    asprintf (&p, "%s: %.*s\n",
-             result_code ? "Error" : "Success",
-             (int)result_string.length,
-             result_string.length > 0 ? (char*)result_string.data : "");
+    if (asprintf(&p, "%s: %.*s\n",
+                result_code ? "Error" : "Success",
+                (int)result_string.length,
+                result_string.length > 0 ? (char*)result_string.data : "") < 0)
+    {
+       ret = ENOMEM;
+       goto out;
+    }
 
     /* return the result */
     (*prompter) (context, data, NULL, p, 0, NULL);
@@ -1413,6 +1418,17 @@ krb5_init_creds_set_service(krb5_context context,
        if (ret)
            return ret;
     }
+
+    /*
+     * This is for Windows RODC that are picky about what name type
+     * the server principal have, and the really strange part is that
+     * they are picky about the AS-REQ name type and not the TGS-REQ
+     * later. Oh well.
+     */
+
+    if (krb5_principal_is_krbtgt(context, principal))
+       krb5_principal_set_type(context, principal, KRB5_NT_SRV_INST);
+
     krb5_free_principal(context, ctx->cred.server);
     ctx->cred.server = principal;
 
@@ -1454,7 +1470,7 @@ krb5_init_creds_set_password(krb5_context context,
     return 0;
 }
 
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
 keytab_key_proc(krb5_context context, krb5_enctype enctype,
                krb5_const_pointer keyseed,
                krb5_salt salt, krb5_data *s2kparms,
@@ -1581,7 +1597,7 @@ krb5_init_creds_set_keytab(krb5_context context,
     return 0;
 }
 
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
 keyblock_key_proc(krb5_context context, krb5_enctype enctype,
                  krb5_const_pointer keyseed,
                  krb5_salt salt, krb5_data *s2kparms,
@@ -1613,7 +1629,8 @@ krb5_init_creds_set_keyblock(krb5_context context,
  * @param in input data from KDC, first round it should be reset by krb5_data_zer().
  * @param out reply to KDC.
  * @param hostinfo KDC address info, first round it can be NULL.
- * @param flags status of the round, if 1 is set, continue one more round.
+ * @param flags status of the round, if
+ *        KRB5_INIT_CREDS_STEP_FLAG_CONTINUE is set, continue one more round.
  *
  * @return 0 for success, or an Kerberos 5 error code, see
  *     krb5_get_error_message().
@@ -1816,7 +1833,7 @@ krb5_init_creds_step(krb5_context context,
     out->data = ctx->req_buffer.data;
     out->length = ctx->req_buffer.length;
 
-    *flags = 1;
+    *flags = KRB5_INIT_CREDS_STEP_FLAG_CONTINUE;
 
     return 0;
  out: