GNU libc ignores malformed entries (those which don't parse correctly), so we should do that for entries we find using LDAP, upstream bug #248. diff -uNr nss_ldap-263/aix_authmeth.c nss_ldap-264/aix_authmeth.c --- nss_ldap-263/aix_authmeth.c 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/aix_authmeth.c 2008-10-30 16:50:15.000000000 -0400 @@ -381,7 +381,12 @@ LA_INIT (a); LA_TYPE (a) = LA_TYPE_NUMBER; - LA_NUMBER (a) = atol(vals[0]); + stat = _nss_ldap_parse_long (vals[0], 0, &(LA_NUMBER(a))); + if (stat != NSS_SUCCESS) + { + ldap_value_free (vals); + return stat; + } attrs[0] = ATM (LM_GROUP, cn); attrs[1] = NULL; @@ -543,9 +548,11 @@ return NSS_NOTFOUND; } - av->attr_un.au_int = atoi (vals[0]); + stat = _nss_ldap_parse_int(vals[0], 0, &av->attr_un.au_int); + ldap_value_free (vals); - return NSS_SUCCESS; + + return stat; } /* @@ -869,12 +876,12 @@ return NSS_NOTFOUND; } - *uid = atoi(vals[0]); + stat = _nss_ldap_parse_uid_t (vals[0], 0, uid); ldap_value_free (vals); ldap_msgfree (res); - return NSS_SUCCESS; + return stat; } /* diff -uNr nss_ldap-263/config.h.in nss_ldap-264/config.h.in --- nss_ldap-263/config.h.in 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/config.h.in 2008-10-30 16:50:15.000000000 -0400 @@ -328,6 +328,18 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* The size of a `gid_t', as computed by sizeof. */ +#undef SIZEOF_GID_T + +/* The size of a `uid_t', as computed by sizeof. */ +#undef SIZEOF_UID_T + +/* The size of a `unsigned int', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_INT + +/* The size of a `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff -uNr nss_ldap-263/configure.in nss_ldap-264/configure.in --- nss_ldap-263/configure.in 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/configure.in 2008-10-30 16:50:15.000000000 -0400 @@ -278,6 +278,11 @@ with_ldap_lib=auto fi +AC_CHECK_SIZEOF([unsigned int]) +AC_CHECK_SIZEOF([unsigned long]) +AC_CHECK_SIZEOF([uid_t],,[#include <pwd.h>]) +AC_CHECK_SIZEOF([gid_t],,[#include <grp.h>]) + AC_CHECK_LIB(dl, dlopen,[LIBS="-ldl $LIBS"],,$LIBS) dnl AC_CHECK_LIB(db, main,[LIBS="-ldb $LIBS"],,$LIBS) diff -uNr nss_ldap-263/ldap-nss.c nss_ldap-264/ldap-nss.c --- nss_ldap-263/ldap-nss.c 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/ldap-nss.c 2008-10-30 16:50:15.000000000 -0400 @@ -3823,22 +3827,36 @@ } #ifdef HAVE_SHADOW_H -int -_nss_ldap_shadow_date (const char *val) +NSS_STATUS +_nss_ldap_shadow_date (const char *val, long default_date, long *value) { int date; + char *p; + long long ll; + if (val == NULL || strlen(val) == 0) + { + *value = default_date; + return NSS_NOTFOUND; + } + ll = strtoll(val, &p, 10); + if (p == NULL || p == val || *p != '\0') + { + *value = default_date; + return NSS_NOTFOUND; + } if (__config->ldc_shadow_type == LS_AD_SHADOW) { - date = atoll (val) / 864000000000LL - 134774LL; + date = ll / 864000000000LL - 134774LL; date = (date > 99999) ? 99999 : date; } else { - date = atol (val); + date = ll; } - return date; + *value = date; + return NSS_SUCCESS; } void diff -uNr nss_ldap-263/ldap-nss.h nss_ldap-264/ldap-nss.h --- nss_ldap-263/ldap-nss.h 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/ldap-nss.h 2008-10-30 16:50:15.000000000 -0400 @@ -865,11 +865,11 @@ NSS_STATUS _nss_ldap_oc_check (LDAPMessage * e, const char *oc); +NSS_STATUS _nss_ldap_shadow_date(const char *val, long default_date, + long *value); #if defined(HAVE_SHADOW_H) -int _nss_ldap_shadow_date(const char *val); void _nss_ldap_shadow_handle_flag(struct spwd *sp); #else -#define _nss_ldap_shadow_date(_v) atol((_v)) #define _nss_ldap_shadow_handle_flag(_sp) do { /* nothing */ } while (0) #endif /* HAVE_SHADOW_H */ diff -uNr nss_ldap-263/ldap-pwd.c nss_ldap-264/ldap-pwd.c --- nss_ldap-263/ldap-pwd.c 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/ldap-pwd.c 2008-10-30 16:50:15.000000000 -0400 @@ -122,7 +122,15 @@ _nss_ldap_assign_attrval (e, AT (uidNumber), &uid, &tmp, &tmplen); if (stat != NSS_SUCCESS) return stat; - pw->pw_uid = (*uid == '\0') ? UID_NOBODY : (uid_t) atol (uid); + if (*uid == '\0') + pw->pw_uid = UID_NOBODY; + else + { + stat = + _nss_ldap_parse_uid_t (uid, UID_NOBODY, &pw->pw_uid); + if (stat != NSS_SUCCESS) + return stat; + } tmp = tmpbuf; tmplen = sizeof (tmpbuf); @@ -131,7 +139,15 @@ &tmplen); if (stat != NSS_SUCCESS) return stat; - pw->pw_gid = (*gid == '\0') ? GID_NOBODY : (gid_t) atol (gid); + if (*gid == '\0') + pw->pw_gid = GID_NOBODY; + else + { + stat = + _nss_ldap_parse_gid_t (gid, GID_NOBODY, &pw->pw_gid); + if (stat != NSS_SUCCESS) + return stat; + } stat = _nss_ldap_assign_attrval (e, AT (gecos), &pw->pw_gecos, &buffer, @@ -176,16 +192,29 @@ tmp = NULL; stat = _nss_ldap_assign_attrval (e, AT (shadowMax), &tmp, &buffer, &buflen); - pw->pw_change = (stat == NSS_SUCCESS) ? atol(tmp) * (24*60*60) : 0; + if (stat == NSS_SUCCESS) + _nss_ldap_parse_long (tmp, 0, &pw->pw_change); + else + pw->pw_change = 0; if (pw->pw_change > 0) { + long sp_change; tmp = NULL; stat = _nss_ldap_assign_attrval (e, AT (shadowLastChange), &tmp, &buffer, &buflen); if (stat == NSS_SUCCESS) - pw->pw_change += atol(tmp); + { + stat = _nss_ldap_parse_long(tmp, 0, &sp_change); + if (stat == NSS_SUCCESS) + { + pw->pw_change += sp_change; + pw->pw_change *= (24 * 60 * 60); + } + else + pw->pw_change = 0; + } else pw->pw_change = 0; } @@ -195,7 +224,13 @@ tmp = NULL; stat = _nss_ldap_assign_attrval (e, AT (shadowExpire), &tmp, &buffer, &buflen); - pw->pw_expire = (stat == NSS_SUCCESS) ? atol(tmp) * (24*60*60) : 0; + if (stat == NSS_SUCCESS) + { + _nss_ldap_parse_long (tmp, 0, &pw->pw_expire); + pw->pw_expire *= (24 * 60 * 60); + } + else + pw->pw_expire = 0; #endif /* HAVE_PASSWD_PW_EXPIRE */ return NSS_SUCCESS; diff -uNr nss_ldap-263/ldap-rpc.c nss_ldap-264/ldap-rpc.c --- nss_ldap-263/ldap-rpc.c 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/ldap-rpc.c 2008-10-30 16:50:15.000000000 -0400 @@ -95,7 +95,10 @@ if (stat != NSS_SUCCESS) return stat; - rpc->r_number = atol (number); + stat = + _nss_ldap_parse_int (number, 0, &rpc->r_number); + if (stat != NSS_SUCCESS) + return stat; stat = _nss_ldap_assign_attrvals (e, ATM (LM_RPC, cn), rpc->r_name, diff -uNr nss_ldap-263/ldap-service.c nss_ldap-264/ldap-service.c --- nss_ldap-263/ldap-service.c 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/ldap-service.c 2008-10-30 16:50:15.000000000 -0400 @@ -77,7 +77,8 @@ void *result, char *buffer, size_t buflen) { struct servent *service = (struct servent *) result; - char *port; + char *portstr; + int port; NSS_STATUS stat = NSS_SUCCESS; /* this is complicated and ugly, because some git (me) specified that service @@ -175,14 +176,20 @@ } stat = - _nss_ldap_assign_attrval (e, AT (ipServicePort), &port, &buffer, + _nss_ldap_assign_attrval (e, AT (ipServicePort), &portstr, &buffer, &buflen); if (stat != NSS_SUCCESS) { return stat; } - service->s_port = htons (atoi (port)); + stat = _nss_ldap_parse_int (portstr, 0, &port); + if (stat != NSS_SUCCESS) + { + return stat; + } + + service->s_port = htons(port); return NSS_SUCCESS; } diff -uNr nss_ldap-263/ldap-spwd.c nss_ldap-264/ldap-spwd.c --- nss_ldap-263/ldap-spwd.c 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/ldap-spwd.c 2008-10-30 16:50:15.000000000 -0400 @@ -51,6 +51,7 @@ #include "ldap-nss.h" #include "ldap-spwd.h" +#include "util.h" #ifdef HAVE_PORT_AFTER_H #include <port_after.h> @@ -86,34 +87,55 @@ stat = _nss_ldap_assign_attrval (e, AT (shadowLastChange), &tmp, &buffer, &buflen); - sp->sp_lstchg = (stat == NSS_SUCCESS) ? _nss_ldap_shadow_date (tmp) : -1; + if (stat == NSS_SUCCESS) + _nss_ldap_shadow_date (tmp, -1, &sp->sp_lstchg); + else + sp->sp_lstchg = -1; stat = _nss_ldap_assign_attrval (e, AT (shadowMax), &tmp, &buffer, &buflen); - sp->sp_max = (stat == NSS_SUCCESS) ? atol (tmp) : -1; + if (stat == NSS_SUCCESS) + _nss_ldap_parse_long (tmp, -1, &sp->sp_max); + else + sp->sp_max = -1; stat = _nss_ldap_assign_attrval (e, AT (shadowMin), &tmp, &buffer, &buflen); - sp->sp_min = (stat == NSS_SUCCESS) ? atol (tmp) : -1; + if (stat == NSS_SUCCESS) + _nss_ldap_parse_long (tmp, -1, &sp->sp_min); + else + sp->sp_min = -1; stat = _nss_ldap_assign_attrval (e, AT (shadowWarning), &tmp, &buffer, &buflen); - sp->sp_warn = (stat == NSS_SUCCESS) ? atol (tmp) : -1; + if (stat == NSS_SUCCESS) + _nss_ldap_parse_long (tmp, -1, &sp->sp_warn); + else + sp->sp_warn = -1; stat = _nss_ldap_assign_attrval (e, AT (shadowInactive), &tmp, &buffer, &buflen); - sp->sp_inact = (stat == NSS_SUCCESS) ? atol (tmp) : -1; + if (stat == NSS_SUCCESS) + _nss_ldap_parse_long (tmp, -1, &sp->sp_inact); + else + sp->sp_inact = -1; stat = _nss_ldap_assign_attrval (e, AT (shadowExpire), &tmp, &buffer, &buflen); - sp->sp_expire = (stat == NSS_SUCCESS) ? _nss_ldap_shadow_date (tmp) : -1; + if (stat == NSS_SUCCESS) + _nss_ldap_shadow_date (tmp, -1, &sp->sp_expire); + else + sp->sp_expire = -1; stat = _nss_ldap_assign_attrval (e, AT (shadowFlag), &tmp, &buffer, &buflen); - sp->sp_flag = (stat == NSS_SUCCESS) ? atol (tmp) : 0; + if (stat == NSS_SUCCESS) + _nss_ldap_parse_ulong (tmp, -1, &sp->sp_flag); + else + sp->sp_flag = -1; _nss_ldap_shadow_handle_flag(sp); diff -uNr nss_ldap-263/util.c nss_ldap-264/util.c --- nss_ldap-263/util.c 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/util.c 2008-10-30 16:50:15.000000000 -0400 @@ -1634,3 +1634,148 @@ return NSS_SUCCESS; } +/* + * Parse a text string into a long integer. If we fail for + * any reason, store the passed-in default value and return + * an error. + */ +NSS_STATUS +_nss_ldap_parse_long (const char *text, long default_value, long *value) +{ + char *p; + long l; + + if (text == NULL || strlen(text) == 0) + { + *value = default_value; + return NSS_NOTFOUND; + } + + l = strtol(text, &p, 10); + if (p == NULL || p == text || *p != '\0') + { + *value = default_value; + return NSS_NOTFOUND; + } + + *value = l; + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_parse_ulong (const char *text, unsigned long default_value, + unsigned long *value) +{ + char *p; + unsigned long l; + + if (text == NULL || strlen(text) == 0) + { + *value = default_value; + return NSS_NOTFOUND; + } + + l = strtoul(text, &p, 10); + if (p == NULL || p == text || *p != '\0') + { + *value = default_value; + return NSS_NOTFOUND; + } + + *value = l; + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_parse_int (const char *text, int default_value, int *value) +{ + char *p; + long l; + + if (text == NULL || strlen(text) == 0) + { + *value = default_value; + return NSS_NOTFOUND; + } + + l = strtol(text, &p, 10); + if (p == NULL || p == text || *p != '\0') + { + *value = default_value; + return NSS_NOTFOUND; + } + + if (l < INT_MIN || l > INT_MAX) + { + *value = default_value; + return NSS_NOTFOUND; + } + + *value = l; + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_parse_uid_t (const char *text, uid_t default_value, uid_t *value) +{ + char *p; + unsigned long l; + + if (text == NULL || strlen(text) == 0) + { + *value = default_value; + return NSS_NOTFOUND; + } + + l = strtoul(text, &p, 10); + if (p == NULL || p == text || *p != '\0') + { + *value = default_value; + return NSS_NOTFOUND; + } +#if SIZEOF_UID_T == SIZEOF_UNSIGNED_INT + if (l > UINT_MAX) + { + *value = default_value; + return NSS_NOTFOUND; + } +#endif + + *value = l; + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_parse_gid_t (const char *text, gid_t default_value, gid_t *value) +{ + char *p; + unsigned long l; + + if (text == NULL || strlen(text) == 0) + { + *value = default_value; + return NSS_NOTFOUND; + } + + l = strtoul(text, &p, 10); + if (p == NULL || p == text || *p != '\0') + { + *value = default_value; + return NSS_NOTFOUND; + } +#if SIZEOF_GID_T == SIZEOF_UNSIGNED_INT + if (l > UINT_MAX) + { + *value = default_value; + return NSS_NOTFOUND; + } +#endif + + *value = l; + + return NSS_SUCCESS; +} diff -uNr nss_ldap-263/util.h nss_ldap-264/util.h --- nss_ldap-263/util.h 2008-10-15 09:30:45.000000000 -0400 +++ nss_ldap-264/util.h 2008-10-30 16:50:15.000000000 -0400 @@ -224,4 +224,16 @@ ldap_map_selector_t _nss_ldap_str2selector (const char *key); +NSS_STATUS +_nss_ldap_parse_long (const char *text, long default_value, long *value); +NSS_STATUS +_nss_ldap_parse_ulong (const char *text, unsigned long default_value, + unsigned long *value); +NSS_STATUS +_nss_ldap_parse_int (const char *text, int default_value, int *value); +NSS_STATUS +_nss_ldap_parse_uid_t (const char *text, uid_t default_value, uid_t *value); +NSS_STATUS +_nss_ldap_parse_gid_t (const char *text, gid_t default_value, gid_t *value); + #endif /* _LDAP_NSS_LDAP_UTIL_H */