>From 5c074b4475838df31cd1d5cd4c11bc9bc7466bf7 Mon Sep 17 00:00:00 2001
From: Simo Sorce <ssorce@redhat.com>
Date: Tue, 5 Jul 2011 22:24:11 -0400
Subject: [PATCH] Improve error code reporting in chpass_util.c

Simplify error string generation by using a single snprintf instead of using
multiple string manipulation calls.

Return better error messages if password quality errors are returned and the
kadm5 style policy is not in use.
Currently custom DAL drivers as they can't generate a KADM5_POLICY structure
as it is not exposed in public headers, and they may also have different
policies that cannot be easily mapped anyways, but still return standard
error codes.
---
 src/lib/kadm5/chpass_util.c |   60 ++++++++++++++++++------------------------
 1 files changed, 26 insertions(+), 34 deletions(-)

diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c
index 9e8111b3c793eb5df44cec6e1d5becb2f1af6ba5..640d9e7557bf22cc876fd231cd67106b4543c0e3 100644
--- a/src/lib/kadm5/chpass_util.c
+++ b/src/lib/kadm5/chpass_util.c
@@ -102,12 +102,10 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
                 msg_ret[msg_len - 1] = '\0';
                 return(code);
             } else {
-                strncpy(msg_ret, error_message(code), msg_len - 1);
-                strncat(msg_ret, " ", msg_len - 1);
-                strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
-                        msg_len - 1);
-                strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
-                        msg_len - 1);
+                snprintf(msg_ret, msg_len, "%s %s\n\n%s",
+                         error_message(code),
+                         string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
+                         string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
                 msg_ret[msg_len - 1] = '\0';
                 return(code);
             }
@@ -142,11 +140,10 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
         (code != KADM5_PASS_REUSE) &&(code != KADM5_PASS_Q_CLASS) &&
         (code != KADM5_PASS_Q_DICT) && (code != KADM5_PASS_TOOSOON)) {
         /* Can't get more info for other errors */
-        snprintf(buffer, sizeof(buffer), "%s %s", error_message(code),
-                 string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE));
-        snprintf(msg_ret, msg_len, "%s\n%s\n",
+        snprintf(msg_ret, msg_len, "%s\n%s %s\n",
                  string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
-                 buffer);
+                 error_message(code),
+                 string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE));
         return(code);
     }
 
@@ -170,32 +167,28 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
     code2 = kadm5_get_principal (lhandle, princ, &princ_ent,
                                  KADM5_PRINCIPAL_NORMAL_MASK);
     if (code2 != 0) {
-        strncpy(msg_ret, error_message(code2), msg_len - 1);
-        strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, string_text(CHPASS_UTIL_GET_PRINC_INFO), msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
-                msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
-                msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret));
+        snprintf(msg_ret, msg_len, "%s %s\n%s %s\n\n%s\n",
+                 error_message(code2),
+                 string_text(CHPASS_UTIL_GET_PRINC_INFO),
+                 error_message(code),
+                 string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
+                 string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
         msg_ret[msg_len - 1] = '\0';
         return(code);
     }
 
     if ((princ_ent.aux_attributes & KADM5_POLICY) == 0) {
-        strncpy(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
-        strncpy(msg_ret, string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR),
-                msg_len - 1 - strlen(msg_ret));
-        strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret));
-        strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
-                msg_len - 1 - strlen(msg_ret));
+        /*
+         * If there is no policy but we still have policy specific errors it
+         * means some module implements password policies on itsown. In this
+         * case try to return meaningful errors.
+         *
+         * Only fail with a generic message if error codes are not recognized.
+         */
+        snprintf(msg_ret, msg_len, "%s\n\n%s",
+                 error_message(code),
+                 string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
         msg_ret[msg_len - 1] = '\0';
-
         (void) kadm5_free_principal_ent(lhandle, &princ_ent);
         return(code);
     }
@@ -248,11 +241,10 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
     }
 
     /* We should never get here, but just in case ... */
-    snprintf(buffer, sizeof(buffer), "%s %s", error_message(code),
-             string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE));
-    snprintf(msg_ret, msg_len, "%s\n%s\n",
+    snprintf(msg_ret, msg_len, "%s\n%s %s\n",
              string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
-             buffer);
+             error_message(code),
+             string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE));
     (void) kadm5_free_principal_ent(lhandle, &princ_ent);
     (void) kadm5_free_policy_ent(lhandle, &policy_ent);
     return(code);
-- 
1.7.6

