-AC_INIT([nss_nonlocal], [1.9], [andersk@mit.edu])
+AC_INIT([nss_nonlocal], [1.10], [andersk@mit.edu])
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AC_PREFIX_DEFAULT([/])
AC_DISABLE_STATIC
struct group gbuf;
int old_errno = errno;
- int buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+ size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
char *buf = malloc(buflen);
if (buf == NULL) {
*errnop = ENOMEM;
return status;
}
+enum nss_status
+check_nonlocal_group(const char *user, struct group *grp, int *errnop)
+{
+ enum nss_status status = NSS_STATUS_SUCCESS;
+ int old_errno = errno;
+ char *end;
+ unsigned long gid;
+
+ errno = 0;
+ gid = strtoul(grp->gr_name, &end, 10);
+ if (errno == 0 && *end == '\0' && (gid_t)gid == gid)
+ status = check_nonlocal_gid(user, gid, errnop);
+ errno = old_errno;
+ if (status != NSS_STATUS_SUCCESS)
+ return status;
+
+ return check_nonlocal_gid(user, grp->gr_gid, errnop);
+}
+
enum nss_status
get_local_group(const char *name, struct group *grp, char **buffer, int *errnop)
{
do
status = DL_CALL_FCT(grent_fct.l, (grp, buffer, buflen, errnop));
while (status == NSS_STATUS_SUCCESS &&
- check_nonlocal_gid("(unknown)", grp->gr_gid, &nonlocal_errno) != NSS_STATUS_SUCCESS);
+ check_nonlocal_group("(unknown)", grp, &nonlocal_errno) != NSS_STATUS_SUCCESS);
}
if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
return status;
if (status != NSS_STATUS_SUCCESS)
return status;
- return check_nonlocal_gid(name, grp->gr_gid, errnop);
+ if (strcmp(name, grp->gr_name) != 0) {
+ syslog(LOG_ERR, "nss_nonlocal: discarding group %s from lookup for group %s\n", grp->gr_name, name);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ return check_nonlocal_group(name, grp, errnop);
}
enum nss_status
if (status != NSS_STATUS_SUCCESS)
return status;
- return check_nonlocal_gid(grp->gr_name, grp->gr_gid, errnop);
+ return check_nonlocal_group(grp->gr_name, grp, errnop);
}
enum nss_status
gid_t local_users_gid, gid;
int is_local = 0;
char *buffer;
+ int old_errno;
+ int in, out, i;
/* Check that the user is a nonlocal user before adding any groups. */
status = check_nonlocal_user(user, errnop);
else if (status != NSS_STATUS_SUCCESS)
is_local = 1;
- int old_errno = errno;
+ old_errno = errno;
status = get_local_group(MAGIC_LOCAL_GROUPNAME,
&local_users_group, &buffer, errnop);
if (is_local)
return NSS_STATUS_SUCCESS;
- int in = *start, out = *start, i;
+ in = out = *start;
nip = nss_group_nonlocal_database();
if (nip == NULL)
struct passwd pwbuf;
int old_errno = errno;
- int buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+ size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
char *buf = malloc(buflen);
if (buf == NULL) {
*errnop = ENOMEM;
return status;
}
+enum nss_status
+check_nonlocal_passwd(const char *user, struct passwd *pwd, int *errnop)
+{
+ enum nss_status status = NSS_STATUS_SUCCESS;
+ int old_errno = errno;
+ char *end;
+ unsigned long uid;
+
+ errno = 0;
+ uid = strtoul(pwd->pw_name, &end, 10);
+ if (errno == 0 && *end == '\0' && (uid_t)uid == uid)
+ status = check_nonlocal_uid(user, uid, errnop);
+ errno = old_errno;
+ if (status != NSS_STATUS_SUCCESS)
+ return status;
+
+ return check_nonlocal_uid(user, pwd->pw_uid, errnop);
+}
+
enum nss_status
check_nonlocal_user(const char *user, int *errnop)
{
struct passwd pwbuf;
int old_errno = errno;
- int buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+ size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
char *buf = malloc(buflen);
if (buf == NULL) {
*errnop = ENOMEM;
do
status = DL_CALL_FCT(pwent_fct.l, (pwd, buffer, buflen, errnop));
while (status == NSS_STATUS_SUCCESS &&
- check_nonlocal_uid(pwd->pw_name, pwd->pw_uid, &nonlocal_errno) != NSS_STATUS_SUCCESS);
+ check_nonlocal_passwd(pwd->pw_name, pwd, &nonlocal_errno) != NSS_STATUS_SUCCESS);
}
if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
return status;
if (status != NSS_STATUS_SUCCESS)
return status;
- status = check_nonlocal_uid(name, pwd->pw_uid, errnop);
+ if (strcmp(name, pwd->pw_name) != 0) {
+ syslog(LOG_ERR, "nss_nonlocal: discarding user %s from lookup for user %s\n", pwd->pw_name, name);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ status = check_nonlocal_passwd(name, pwd, errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
if (status != NSS_STATUS_SUCCESS)
return status;
- status = check_nonlocal_uid(pwd->pw_name, pwd->pw_uid, errnop);
+ status = check_nonlocal_passwd(pwd->pw_name, pwd, errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
#include <string.h>
#include <dlfcn.h>
#include <stdio.h>
+#include <syslog.h>
#include <errno.h>
#include <shadow.h>
#include <nss.h>
if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
break;
} while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
- return status;
+ if (status != NSS_STATUS_SUCCESS)
+ return status;
+
+ if (strcmp(name, pwd->sp_namp) != 0) {
+ syslog(LOG_ERR, "nss_nonlocal: discarding shadow %s from lookup for shadow %s\n", pwd->sp_namp, name);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ return NSS_STATUS_SUCCESS;
}