URL: https://github.com/freeipa/freeipa/pull/4910
Author: Carbenium
 Title: #4910:  ipa-join: handle JSON-RPC error codes 
Action: opened

PR body:
"""
Handling of IPA error codes was missing from the JSON-RPC code paths.
Add parsing support for the `error` object and handle `ACIError` explicitly to 
match XML-RPC behaviour.

Fixes: https://pagure.io/freeipa/issue/8408
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/4910/head:pr4910
git checkout pr4910
From 1c736a1db7756111c72882b72d9608e3d44cbaf7 Mon Sep 17 00:00:00 2001
From: Peter Keresztes Schmidt <[email protected]>
Date: Fri, 10 Jul 2020 19:55:31 +0200
Subject: [PATCH 1/2] ipa-join: extract common JSON-RPC response parsing to
 common function

In preparation for handling JSON-RPC error codes.

Related: https://pagure.io/freeipa/issue/8408
---
 client/ipa-join.c | 53 +++++++++++++++++++++++++++++++----------------
 1 file changed, 35 insertions(+), 18 deletions(-)

diff --git a/client/ipa-join.c b/client/ipa-join.c
index 7be9680a34..54dba2c992 100644
--- a/client/ipa-join.c
+++ b/client/ipa-join.c
@@ -811,13 +811,12 @@ jsonrpc_request(const char *ipaserver, const json_t *json, curl_buffer *response
 }
 
 static int
-jsonrpc_parse_join_response(const char *payload, join_info *join_i, bool quiet) {
+jsonrpc_parse_response(const char *payload, json_t** j_result_obj, bool quiet) {
     int rval = 0;
 
     json_error_t j_error;
 
     json_t *j_root = NULL;
-    json_t *j_result = NULL;
 
     j_root = json_loads(payload, 0, &j_error);
     if (!j_root) {
@@ -828,12 +827,38 @@ jsonrpc_parse_join_response(const char *payload, join_info *join_i, bool quiet)
         goto cleanup;
     }
 
-    j_result = json_object_get(j_root, "result");
+    *j_result_obj = json_object_get(j_root, "result");
+    if (!*j_result_obj) {
+        if (debug)
+            fprintf(stderr, _("Parsing JSON-RPC response failed: no 'result' value found.\n"));
+
+        rval = 17;
+        goto cleanup;
+    }
+    json_incref(*j_result_obj);
+
+cleanup:
+    json_decref(j_root);
+
+    return rval;
+}
+
+static int
+jsonrpc_parse_join_response(const char *payload, join_info *join_i, bool quiet) {
+    int rval = 0;
+
+    json_error_t j_error;
+
+    json_t *j_result_obj = NULL;
+
+    rval = jsonrpc_parse_response(payload, &j_result_obj, quiet);
+    if (rval)
+        goto cleanup;
 
     char *tmp_hostdn = NULL;
     char *tmp_princ = NULL;
     char *tmp_pwdch = NULL;
-    if (json_unpack_ex(j_result, &j_error, 0, "[s, {s:[s], s?:[s]}]",
+    if (json_unpack_ex(j_result_obj, &j_error, 0, "[s, {s:[s], s?:[s]}]",
                        &tmp_hostdn,
                        "krbprincipalname", &tmp_princ,
                        "krblastpwdchange", &tmp_pwdch) != 0) {
@@ -849,7 +874,7 @@ jsonrpc_parse_join_response(const char *payload, join_info *join_i, bool quiet)
     join_i->is_provisioned = tmp_pwdch != NULL;
 
 cleanup:
-    json_decref(j_root);
+    json_decref(j_result_obj);
 
     return rval;
 }
@@ -940,21 +965,13 @@ jsonrpc_parse_unenroll_response(const char *payload, bool* result, bool quiet) {
 
     json_error_t j_error;
 
-    json_t *j_root = NULL;
-    json_t *j_result = NULL;
-
-    j_root = json_loads(payload, 0, &j_error);
-    if (!j_root) {
-        if (debug)
-            fprintf(stderr, _("Parsing JSON-RPC response failed: %s\n"), j_error.text);
+    json_t *j_result_obj = NULL;
 
-        rval = 17;
+    rval = jsonrpc_parse_response(payload, &j_result_obj, quiet);
+    if (rval)
         goto cleanup;
-    }
 
-    j_result = json_object_get(j_root, "result");
-
-    if (json_unpack_ex(j_result, &j_error, 0, "{s:b}",
+    if (json_unpack_ex(j_result_obj, &j_error, 0, "{s:b}",
                        "result", result) != 0) {
         if (debug)
             fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
@@ -964,7 +981,7 @@ jsonrpc_parse_unenroll_response(const char *payload, bool* result, bool quiet) {
     }
 
 cleanup:
-    json_decref(j_root);
+    json_decref(j_result_obj);
 
     return rval;
 }

From d839f68633eeec07e1d21152247ab715ac429992 Mon Sep 17 00:00:00 2001
From: Peter Keresztes Schmidt <[email protected]>
Date: Fri, 10 Jul 2020 20:08:10 +0200
Subject: [PATCH 2/2] ipa-join: handle JSON-RPC error codes

Error code 2100 (ACIError) is handled explicitly to match XML-RPC behaviour.

Fixes: https://pagure.io/freeipa/issue/8408
---
 client/ipa-join.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/client/ipa-join.c b/client/ipa-join.c
index 54dba2c992..4deb7d932d 100644
--- a/client/ipa-join.c
+++ b/client/ipa-join.c
@@ -810,6 +810,40 @@ jsonrpc_request(const char *ipaserver, const json_t *json, curl_buffer *response
     return rval;
 }
 
+static int
+jsonrpc_parse_error(json_t *j_error_obj) {
+    int rval = 0;
+
+    json_error_t j_error;
+
+    int error_code = 0;
+    char *error_message = NULL;
+    if (json_unpack_ex(j_error_obj, &j_error, 0, "{s:i, s:s}",
+                       "code", &error_code,
+                       "message", &error_message) != 0) {
+        if (debug)
+            fprintf(stderr, _("Extracting the error from the JSON-RPC response failed: %s\n"), j_error.text);
+
+        rval = 17;
+        goto cleanup;
+    }
+
+    switch (error_code) {
+    case 2100:
+        fprintf(stderr, _("No permission to join this host to the IPA domain.\n"));
+        rval = 1;
+        break;
+    default:
+        if (error_message)
+            fprintf(stderr, "%s\n", error_message);
+        rval = 1;
+        break;
+    }
+
+cleanup:
+    return rval;
+}
+
 static int
 jsonrpc_parse_response(const char *payload, json_t** j_result_obj, bool quiet) {
     int rval = 0;
@@ -817,6 +851,7 @@ jsonrpc_parse_response(const char *payload, json_t** j_result_obj, bool quiet) {
     json_error_t j_error;
 
     json_t *j_root = NULL;
+    json_t *j_error_obj = NULL;
 
     j_root = json_loads(payload, 0, &j_error);
     if (!j_root) {
@@ -827,6 +862,13 @@ jsonrpc_parse_response(const char *payload, json_t** j_result_obj, bool quiet) {
         goto cleanup;
     }
 
+    j_error_obj = json_object_get(j_root, "error");
+    if (j_error_obj && !json_is_null(j_error_obj))
+    {
+        rval = jsonrpc_parse_error(j_error_obj);
+        goto cleanup;
+    }
+
     *j_result_obj = json_object_get(j_root, "result");
     if (!*j_result_obj) {
         if (debug)
_______________________________________________
FreeIPA-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/[email protected]

Reply via email to