From 489c57b6faa0c688f36e78173f379363558a1784 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 25 Oct 2010 15:14:24 +0200
Subject: [PATCH] Always use uint32_t for UID/GID numbers

---
 Makefile.am                              |    1 +
 src/db/sysdb.c                           |   14 +++++++-------
 src/db/sysdb.h                           |    4 ++--
 src/providers/ldap/ldap_id.c             |   11 +++++------
 src/providers/ldap/sdap_async_accounts.c |   29 ++++++++++++-----------------
 src/providers/proxy/proxy_id.c           |    7 +++----
 src/tests/strtonum-tests.c               |   10 +++++-----
 src/util/find_uid.c                      |    6 +++---
 src/util/strtonum.c                      |    2 +-
 9 files changed, 39 insertions(+), 45 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 294b174..9747712 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -635,6 +635,7 @@ ipa_timerules_tests_LDADD = \
 find_uid_tests_SOURCES = \
     src/tests/find_uid-tests.c \
     src/util/find_uid.c \
+    src/util/strtonum.c \
     $(SSSD_DEBUG_OBJ)
 find_uid_tests_CFLAGS = \
     $(AM_CFLAGS) \
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index ca053ae..bc6f8fc 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -20,6 +20,7 @@
 */
 
 #include "util/util.h"
+#include "util/strtonum.h"
 #include "db/sysdb_private.h"
 #include "confdb/confdb.h"
 #include <time.h>
@@ -171,13 +172,13 @@ int sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name,
     return EOK;
 }
 
-int sysdb_attrs_get_ulong(struct sysdb_attrs *attrs, const char *name,
-                          unsigned long *value)
+int sysdb_attrs_get_uint32_t(struct sysdb_attrs *attrs, const char *name,
+                             uint32_t *value)
 {
     struct ldb_message_element *el;
     int ret;
     char *endptr;
-    unsigned long val;
+    uint32_t val;
 
     ret = sysdb_attrs_get_el_int(attrs, name, false, &el);
     if (ret) {
@@ -189,10 +190,9 @@ int sysdb_attrs_get_ulong(struct sysdb_attrs *attrs, const char *name,
     }
 
     errno = 0;
-    val = strtoul((const char *) el->values[0].data, &endptr, 0);
-    if (errno || *endptr) {
-        return EINVAL;
-    }
+    val = strtouint32((const char *) el->values[0].data, &endptr, 0);
+    if (errno != 0) return errno;
+    if (*endptr) return EINVAL;
 
     *value = val;
     return EOK;
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 2ca9527..0d8b29c 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -196,8 +196,8 @@ int sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name,
                            const char **string);
 int sysdb_attrs_get_string_array(struct sysdb_attrs *attrs, const char *name,
                                  TALLOC_CTX *mem_ctx, const char ***string);
-int sysdb_attrs_get_ulong(struct sysdb_attrs *attrs, const char *name,
-                          unsigned long *value);
+int sysdb_attrs_get_uint32_t(struct sysdb_attrs *attrs, const char *name,
+                             uint32_t *value);
 
 int sysdb_attrs_replace_name(struct sysdb_attrs *attrs, const char *oldname,
                                  const char *newname);
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 135e370..91b6c8a 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -27,6 +27,7 @@
 #include <sys/time.h>
 
 #include "util/util.h"
+#include "util/strtonum.h"
 #include "db/sysdb.h"
 #include "providers/ldap/ldap_common.h"
 #include "providers/ldap/sdap_async.h"
@@ -219,10 +220,9 @@ static void users_get_done(struct tevent_req *subreq)
             break;
 
         case BE_FILTER_IDNUM:
-            errno = 0;
-            uid = (uid_t) strtoul(state->name, &endptr, 0);
+            uid = (uid_t) strtouint32(state->name, &endptr, 0);
             if (errno || *endptr || (state->name == endptr)) {
-                tevent_req_error(req, errno);
+                tevent_req_error(req, errno ? errno : EINVAL);
                 return;
             }
 
@@ -445,10 +445,9 @@ static void groups_get_done(struct tevent_req *subreq)
             break;
 
         case BE_FILTER_IDNUM:
-            errno = 0;
-            gid = (gid_t) strtoul(state->name, &endptr, 0);
+            gid = (gid_t) strtouint32(state->name, &endptr, 0);
             if (errno || *endptr || (state->name == endptr)) {
-                tevent_req_error(req, errno);
+                tevent_req_error(req, errno ? errno : EINVAL);
                 return;
             }
 
diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 62bafed..6b14161 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -43,7 +43,6 @@ static int sdap_save_user(TALLOC_CTX *memctx,
     const char *gecos;
     const char *homedir;
     const char *shell;
-    unsigned long l;
     uid_t uid;
     gid_t gid;
     struct sysdb_attrs *user_attrs;
@@ -90,16 +89,15 @@ static int sdap_save_user(TALLOC_CTX *memctx,
     if (el->num_values == 0) shell = NULL;
     else shell = (const char *)el->values[0].data;
 
-    ret = sysdb_attrs_get_ulong(attrs,
-                                opts->user_map[SDAP_AT_USER_UID].sys_name,
-                                &l);
+    ret = sysdb_attrs_get_uint32_t(attrs,
+                                   opts->user_map[SDAP_AT_USER_UID].sys_name,
+                                   &uid);
     if (ret != EOK) {
         DEBUG(1, ("no uid provided for [%s] in domain [%s].\n",
                   name, dom->name));
         ret = EINVAL;
         goto fail;
     }
-    uid = l;
 
     /* check that the uid is valid for this domain */
     if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
@@ -109,16 +107,15 @@ static int sdap_save_user(TALLOC_CTX *memctx,
         goto fail;
     }
 
-    ret = sysdb_attrs_get_ulong(attrs,
-                                opts->user_map[SDAP_AT_USER_GID].sys_name,
-                                &l);
+    ret = sysdb_attrs_get_uint32_t(attrs,
+                                   opts->user_map[SDAP_AT_USER_GID].sys_name,
+                                   &gid);
     if (ret != EOK) {
         DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
                   name, dom->name));
         ret = EINVAL;
         goto fail;
     }
-    gid = l;
 
     /* check that the gid is valid for this domain */
     if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
@@ -609,7 +606,6 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     struct ldb_message_element *el;
     struct sysdb_attrs *group_attrs;
     const char *name = NULL;
-    unsigned long l;
     gid_t gid;
     int ret;
     char *timestamp = NULL;
@@ -623,16 +619,15 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     }
     name = (const char *)el->values[0].data;
 
-    ret = sysdb_attrs_get_ulong(attrs,
-                                opts->group_map[SDAP_AT_GROUP_GID].sys_name,
-                                &l);
+    ret = sysdb_attrs_get_uint32_t(attrs,
+                                   opts->group_map[SDAP_AT_GROUP_GID].sys_name,
+                                   &gid);
     if (ret != EOK) {
         DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
                   name, dom->name));
         ret = EINVAL;
         goto fail;
     }
-    gid = l;
 
     /* check that the gid is valid for this domain */
     if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
@@ -1792,9 +1787,9 @@ static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
             }
 
             if (strcmp(name, missing[i]) == 0) {
-                ret = sysdb_attrs_get_ulong(ldap_groups[ai],
-                                            SYSDB_GIDNUM,
-                                            (unsigned long *) &gid);
+                ret = sysdb_attrs_get_uint32_t(ldap_groups[ai],
+                                               SYSDB_GIDNUM,
+                                               &gid);
                 if (ret) {
                     DEBUG(1, ("The GID attribute is missing or malformed\n"));
                     goto fail;
diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index ff3ddf8..35fc9c4 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -22,6 +22,7 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include "util/strtonum.h"
 #include "providers/proxy/proxy.h"
 
 /* =Getpwnam-wrapper======================================================*/
@@ -1077,8 +1078,7 @@ void proxy_get_account_info(struct be_req *breq)
                                    EINVAL, "Invalid attr type");
             } else {
                 char *endptr;
-                errno = 0;
-                uid = (uid_t) strtoul(ar->filter_value, &endptr, 0);
+                uid = (uid_t) strtouint32(ar->filter_value, &endptr, 0);
                 if (errno || *endptr || (ar->filter_value == endptr)) {
                     return proxy_reply(breq, DP_ERR_FATAL,
                                        EINVAL, "Invalid attr type");
@@ -1107,8 +1107,7 @@ void proxy_get_account_info(struct be_req *breq)
                                    EINVAL, "Invalid attr type");
             } else {
                 char *endptr;
-                errno = 0;
-                gid = (gid_t) strtoul(ar->filter_value, &endptr, 0);
+                gid = (gid_t) strtouint32(ar->filter_value, &endptr, 0);
                 if (errno || *endptr || (ar->filter_value == endptr)) {
                     return proxy_reply(breq, DP_ERR_FATAL,
                                        EINVAL, "Invalid attr type");
diff --git a/src/tests/strtonum-tests.c b/src/tests/strtonum-tests.c
index 6c26018..94fa0b9 100644
--- a/src/tests/strtonum-tests.c
+++ b/src/tests/strtonum-tests.c
@@ -44,9 +44,9 @@
 
 #define CHECK_ERRNO(expected, actual) \
     do { \
-        fail_unless(error == ERANGE, "Expected errno %d[%s], got %d[%s]", \
-                                     ERANGE, strerror(ERANGE), \
-                                     error, strerror(ERANGE)); \
+        fail_unless(error == expected, "Expected errno %d[%s], got %d[%s]", \
+                                        expected, strerror(ERANGE), \
+                                        error, strerror(ERANGE)); \
     } while(0)
 
 #define CHECK_ENDPTR(expected, actual) \
@@ -265,14 +265,14 @@ START_TEST (test_strtouint32_neg_integer_base_10)
 {
     uint32_t result;
     const char *input = "-123";
-    uint32_t expected = -123;
+    uint32_t expected = UINT32_MAX;
     char *endptr;
     errno_t error;
 
     result = strtouint32(input, &endptr, 10);
     error = errno;
 
-    EXPECT_UNSET_ERRNO(error);
+    CHECK_ERRNO(ERANGE, error);
     CHECK_ZERO_ENDPTR(endptr);
     CHECK_RESULT(expected, result);
 }
diff --git a/src/util/find_uid.c b/src/util/find_uid.c
index 0937c66..e4d4ca8 100644
--- a/src/util/find_uid.c
+++ b/src/util/find_uid.c
@@ -38,6 +38,7 @@
 
 #include "dhash.h"
 #include "util/util.h"
+#include "util/strtonum.h"
 
 #define INITIAL_TABLE_SIZE 64
 #define PATHLEN (NAME_MAX + 14)
@@ -63,7 +64,7 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid)
     char *p;
     char *e;
     char *endptr;
-    unsigned long num=0;
+    uint32_t num=0;
     errno_t error;
 
     ret = snprintf(path, PATHLEN, "/proc/%d/status", pid);
@@ -131,8 +132,7 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid)
         } else {
             *e = '\0';
         }
-        errno = 0;
-        num = strtoul(p, &endptr, 10);
+        num = strtouint32(p, &endptr, 10);
         error = errno;
         if (error != 0) {
             DEBUG(1, ("strtol failed [%s].\n", strerror(error)));
diff --git a/src/util/strtonum.c b/src/util/strtonum.c
index 744e0f7..bf1b21a 100644
--- a/src/util/strtonum.c
+++ b/src/util/strtonum.c
@@ -51,7 +51,7 @@ int32_t strtoint32(const char *nptr, char **endptr, int base)
 /* strtouint32 */
 uint32_t strtouint32(const char *nptr, char **endptr, int base)
 {
-    long long ret = 0;
+    unsigned long long ret = 0;
     errno = 0;
     ret = strtoull(nptr, endptr, base);
 
-- 
1.7.2.3

