Subject: Re: port-i386/33974
To: None <gnats-bugs@NetBSD.org>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: netbsd-bugs
Date: 07/13/2006 10:19:54
This is a multipart MIME message.

--==_Exmh_18628298481600
Content-Type: text/plain; charset=us-ascii


elekktretterr@exemail.com.au said:
>  The patch doesnt come in cleanly.
>  here is reject information: 
> [...]

Hmm - the patch was against the clean CVS version.
Did you have already local modifications in the file?
Anyway, I'm sending the whole file now.

I'll be traveling from tomorrow until friday next
week. I'll not be able to do much in that time.

best regards
Matthias



--==_Exmh_18628298481600
Content-Type: text/plain ; name="netbsd.c"; charset=us-ascii
Content-Description: netbsd.c
Content-Disposition: attachment; filename="netbsd.c"

/* $NetBSD: netbsd.c,v 1.5 2006/03/15 19:23:47 drochner Exp $ */

#include <sys/param.h>
#include <pwd.h>
#include <grp.h>
#include <nsswitch.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>
#include <stdio.h>

#include "netbsd.h"
typedef enum nss_status NSS_STATUS;

extern NSS_STATUS _nss_ldap_setpwent(void);
static int netbsd_setpwent(void *, void *, va_list);
static int netbsd_setpassent(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_endpwent(void);
static int netbsd_endpwent(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_getpwent_r(struct passwd *,
				       char *, size_t, int *);
static int netbsd_getpwent(void *, void *, va_list);
static int netbsd_getpwent_r(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_getpwnam_r(const char *, struct passwd *,
				       char *, size_t, int *);
static int netbsd_getpwnam(void *, void *, va_list);
static int netbsd_getpwnam_r(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_getpwuid_r(uid_t, struct passwd *,
				       char *, size_t, int *);
static int netbsd_getpwuid(void *, void *, va_list);
static int netbsd_getpwuid_r(void *, void *, va_list);

extern NSS_STATUS _nss_ldap_setgrent(void);
static int netbsd_setgrent(void *, void *, va_list);
static int netbsd_setgroupent(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_endgrent(void);
static int netbsd_endgrent(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_getgrent_r(struct group *,
				       char *, size_t, int *);
static int netbsd_getgrent(void *, void *, va_list);
static int netbsd_getgrent_r(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_getgrnam_r(const char *, struct group *,
				       char *, size_t, int *);
static int netbsd_getgrnam(void *, void *, va_list);
static int netbsd_getgrnam_r(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_getgrgid_r(gid_t, struct group *,
				       char *, size_t, int *);
static int netbsd_getgrgid(void *, void *, va_list);
static int netbsd_getgrgid_r(void *, void *, va_list);
extern NSS_STATUS _nss_ldap_initgroups_dyn(const char *, gid_t, long int *,
	long int *, gid_t **, long int, int *);
static int netbsd_getgroupmembership(void *, void *, va_list);

static int nss2netbsderr[] = {
	NS_SUCCESS, NS_NOTFOUND, NS_UNAVAIL, NS_TRYAGAIN, NS_RETURN
};
static struct passwd rpw;
static struct group rg;
static char pwbuf[1024];
static char *grpbuf;
static size_t grpbuflen;

static ns_mtab methods[] = {
	{ NSDB_PASSWD, "setpwent", netbsd_setpwent, 0 },
	{ NSDB_PASSWD, "setpassent", netbsd_setpassent, 0 },
	{ NSDB_PASSWD, "endpwent", netbsd_endpwent, 0 },
	{ NSDB_PASSWD, "getpwent", netbsd_getpwent, 0 },
	{ NSDB_PASSWD, "getpwent_r", netbsd_getpwent_r, 0 },
	{ NSDB_PASSWD, "getpwnam", netbsd_getpwnam, 0 },
	{ NSDB_PASSWD, "getpwnam_r", netbsd_getpwnam_r, 0 },
	{ NSDB_PASSWD, "getpwuid", netbsd_getpwuid, 0 },
	{ NSDB_PASSWD, "getpwuid_r", netbsd_getpwuid_r, 0 },

	{ NSDB_GROUP, "setgrent", netbsd_setgrent, 0 },
	{ NSDB_GROUP, "setgroupent", netbsd_setgroupent, 0 },
	{ NSDB_GROUP, "endgrent", netbsd_endgrent, 0 },
	{ NSDB_GROUP, "getgrent", netbsd_getgrent, 0 },
	{ NSDB_GROUP, "getgrent_r", netbsd_getgrent_r, 0 },
	{ NSDB_GROUP, "getgrnam", netbsd_getgrnam, 0 },
	{ NSDB_GROUP, "getgrnam_r", netbsd_getgrnam_r, 0 },
	{ NSDB_GROUP, "getgrgid", netbsd_getgrgid, 0 },
	{ NSDB_GROUP, "getgrgid_r", netbsd_getgrgid_r, 0 },
	{ NSDB_GROUP, "getgroupmembership", netbsd_getgroupmembership, 0 },
};

static int
netbsd_setpwent(void *rv, void *cb_data, va_list ap)
{
	NSS_STATUS s;

	s = _nss_ldap_setpwent();

	return nss2netbsderr[s];
}

static int
netbsd_setpassent(void *rv, void *cb_data, va_list ap)
{
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	int stayopen = va_arg(ap, int);

	/* XXX stayopen ignored */
	s = _nss_ldap_setpwent();

	if (s == NSS_STATUS_SUCCESS)
		*retval = 1;
	else
		*retval = 0;

	return nss2netbsderr[s];
}

static int
netbsd_endpwent(void *rv, void *cb_data, va_list ap)
{
	NSS_STATUS s;

	s = _nss_ldap_endpwent();

	return nss2netbsderr[s];
}

static int
netbsd_getpwent(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	struct passwd **retval = va_arg(ap, struct passwd **);

	memset(&rpw, 0, sizeof(rpw));
	s = _nss_ldap_getpwent_r(&rpw, pwbuf, sizeof(pwbuf), &err);

	if (s == NSS_STATUS_SUCCESS) {
		rpw.pw_class = ""; /* XXX */
		*retval = &rpw;
	} else
		*retval = 0;

	return nss2netbsderr[s];
}

static int
netbsd_getpwent_r(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	struct passwd *pw = va_arg(ap, struct passwd *);
	char *buf = va_arg(ap, char *);
	size_t buflen = va_arg(ap, size_t);
	struct passwd **result = va_arg(ap, struct passwd **);

	memset(pw, 0, sizeof(*pw));
	s = _nss_ldap_getpwent_r(pw, buf, buflen, &err);

	if (s == NSS_STATUS_SUCCESS) {
		pw->pw_class = ""; /* XXX */
		*result = pw;
	} else
		*result = 0;

	if (s == NSS_STATUS_SUCCESS || s == NSS_STATUS_NOTFOUND)
		*retval = 0;
	else
		*retval = 1;

	return nss2netbsderr[s];
}

static int
netbsd_getpwnam(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	struct passwd **retval = va_arg(ap, struct passwd **);
	const char *name = va_arg(ap, const char *);

	memset(&rpw, 0, sizeof(rpw));
	s = _nss_ldap_getpwnam_r(name, &rpw, pwbuf, sizeof(pwbuf), &err);

	if (s == NSS_STATUS_SUCCESS) {
		rpw.pw_class = ""; /* XXX */
		*retval = &rpw;
	} else
		*retval = 0;

	return nss2netbsderr[s];
}

static int
netbsd_getpwnam_r(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	const char *name = va_arg(ap, const char *);
	struct passwd *pw = va_arg(ap, struct passwd *);
	char *buf = va_arg(ap, char *);
	size_t buflen = va_arg(ap, size_t);
	struct passwd **result = va_arg(ap, struct passwd **);

	memset(pw, 0, sizeof(*pw));
	s = _nss_ldap_getpwnam_r(name, pw, buf, buflen, &err);

	if (s == NSS_STATUS_SUCCESS) {
		pw->pw_class = ""; /* XXX */
		*result = pw;
	} else
		*result = 0;

	if (s == NSS_STATUS_SUCCESS || s == NSS_STATUS_NOTFOUND)
		*retval = 0;
	else
		*retval = 1;

	return nss2netbsderr[s];
}

static int
netbsd_getpwuid(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	struct passwd **retval = va_arg(ap, struct passwd **);
	uid_t uid = va_arg(ap, uid_t);

	memset(&rpw, 0, sizeof(rpw));
	s = _nss_ldap_getpwuid_r(uid, &rpw, pwbuf, sizeof(pwbuf), &err);

	if (s == NSS_STATUS_SUCCESS) {
		rpw.pw_class = ""; /* XXX */
		*retval = &rpw;
	} else
		*retval = 0;

	return nss2netbsderr[s];
}

static int
netbsd_getpwuid_r(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	uid_t uid = va_arg(ap, uid_t);
	struct passwd *pw = va_arg(ap, struct passwd *);
	char *buf = va_arg(ap, char *);
	size_t buflen = va_arg(ap, size_t);
	struct passwd **result = va_arg(ap, struct passwd **);

	memset(pw, 0, sizeof(*pw));
	s = _nss_ldap_getpwuid_r(uid, pw, buf, buflen, &err);

	if (s == NSS_STATUS_SUCCESS) {
		pw->pw_class = ""; /* XXX */
		*result = pw;
	} else
		*result = 0;

	if (s == NSS_STATUS_SUCCESS || s == NSS_STATUS_NOTFOUND)
		*retval = 0;
	else
		*retval = 1;

	return nss2netbsderr[s];
}

static int
resize_grpbuf()
{

	if (grpbuflen > 50000) /* safety guard */
		return (-1);
	grpbuflen += 1024;
	if (grpbuf)
		free(grpbuf);
	grpbuf = malloc(grpbuflen);
	if (!grpbuf)
		return (-1);
	printf("resize_grpbuf: now %d\n", grpbuflen);
	return (0);
}

static int
netbsd_setgrent(void *rv, void *cb_data, va_list ap)
{
	NSS_STATUS s;

	s = _nss_ldap_setgrent();

	return nss2netbsderr[s];
}

static int
netbsd_setgroupent(void *rv, void *cb_data, va_list ap)
{
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	int stayopen = va_arg(ap, int);

	/* XXX stayopen ignored */
	s = _nss_ldap_setgrent();

	if (s == NSS_STATUS_SUCCESS)
		*retval = 1;
	else
		*retval = 0;

	return nss2netbsderr[s];
}

static int
netbsd_endgrent(void *rv, void *cb_data, va_list ap)
{
	NSS_STATUS s;

	s = _nss_ldap_endgrent();

	return nss2netbsderr[s];
}

static int
netbsd_getgrent(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	struct group **retval = va_arg(ap, struct group **);

tryagain:
	memset(&rg, 0, sizeof(rg));
	s = _nss_ldap_getgrent_r(&rg, grpbuf, grpbuflen, &err);

	if (s == NSS_STATUS_SUCCESS)
		*retval = &rg;
	else if ((s == NSS_STATUS_TRYAGAIN) && (err == ERANGE)
		 && (resize_grpbuf() == 0))
		goto tryagain;
	else
		*retval = 0;

	return nss2netbsderr[s];
}

static int
netbsd_getgrent_r(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	struct group *grp = va_arg(ap, struct group *);
	char *buf = va_arg(ap, char *);
	size_t buflen = va_arg(ap, size_t);
	struct group **result = va_arg(ap, struct group **);

	memset(grp, 0, sizeof(*grp));
	s = _nss_ldap_getgrent_r(grp, buf, buflen, &err);

	if (s == NSS_STATUS_SUCCESS)
		*result = grp;
	else
		*result = 0;

	if (s == NSS_STATUS_SUCCESS || s == NSS_STATUS_NOTFOUND)
		*retval = 0;
	else
		*retval = 1;

	return nss2netbsderr[s];
}

static int
netbsd_getgrnam(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	struct group **retval = va_arg(ap, struct group **);
	const char *name = va_arg(ap, const char *);

tryagain:
	memset(&rg, 0, sizeof(rg));
	s = _nss_ldap_getgrnam_r(name, &rg, grpbuf, grpbuflen, &err);

	if (s == NSS_STATUS_SUCCESS)
		*retval = &rg;
	else if ((s == NSS_STATUS_TRYAGAIN) && (err == ERANGE)
		 && (resize_grpbuf() == 0))
		goto tryagain;
	else {
		printf("netbsd_getgrnam: %d/%d\n", s, err);
		*retval = 0;
	}

	return nss2netbsderr[s];
}

static int
netbsd_getgrnam_r(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	const char *name = va_arg(ap, const char *);
	struct group *grp = va_arg(ap, struct group *);
	char *buf = va_arg(ap, char *);
	size_t buflen = va_arg(ap, size_t);
	struct group **result = va_arg(ap, struct group **);

	memset(grp, 0, sizeof(*grp));
	s = _nss_ldap_getgrnam_r(name, grp, buf, buflen, &err);

	if (s == NSS_STATUS_SUCCESS)
		*result = grp;
	else
		*result = 0;

	if (s == NSS_STATUS_SUCCESS || s == NSS_STATUS_NOTFOUND)
		*retval = 0;
	else
		*retval = 1;

	return nss2netbsderr[s];
}

static int
netbsd_getgrgid(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	struct group **retval = va_arg(ap, struct group **);
	gid_t gid = va_arg(ap, gid_t);

tryagain:
	memset(&rg, 0, sizeof(rg));
	s = _nss_ldap_getgrgid_r(gid, &rg, grpbuf, grpbuflen, &err);

	if (s == NSS_STATUS_SUCCESS)
		*retval = &rg;
	else if ((s == NSS_STATUS_TRYAGAIN) && (err == ERANGE)
		 && (resize_grpbuf() == 0))
		goto tryagain;
	else {
		printf("netbsd_getgrgid: %d/%d\n", s, err);
		*retval = 0;
	}

	return nss2netbsderr[s];
}

static int
netbsd_getgrgid_r(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	gid_t gid = va_arg(ap, gid_t);
	struct group *grp = va_arg(ap, struct group *);
	char *buf = va_arg(ap, char *);
	size_t buflen = va_arg(ap, size_t);
	struct group **result = va_arg(ap, struct group **);

	memset(grp, 0, sizeof(*grp));
	s = _nss_ldap_getgrgid_r(gid, grp, buf, buflen, &err);

	if (s == NSS_STATUS_SUCCESS)
		*result = grp;
	else
		*result = 0;

	if (s == NSS_STATUS_SUCCESS || s == NSS_STATUS_NOTFOUND)
		*retval = 0;
	else
		*retval = 1;

	return nss2netbsderr[s];
}

/* addgid helper from NetBSD's getgroupmembership.c */
static int
__gr_addgid(gid_t gid, gid_t *groups, int maxgrp, int *groupc)
{
	int	ret, dupc;

						/* skip duplicates */
	for (dupc = 0; dupc < MIN(maxgrp, *groupc); dupc++) {
		if (groups[dupc] == gid)
			return 1;
	}

	ret = 1;
	if (*groupc < maxgrp)			/* add this gid */
		groups[*groupc] = gid;
	else
		ret = 0;
	(*groupc)++;
	return ret;
}


static int
netbsd_getgroupmembership(void *rv, void *cb_data, va_list ap)
{
	int err;
	NSS_STATUS s;
	int *retval = va_arg(ap, int *);
	const char *user = va_arg(ap, const char *);
	gid_t group = va_arg(ap, gid_t);
	gid_t *groups = va_arg(ap, gid_t *);
	int limit = va_arg(ap, int);
	int *size = va_arg(ap, int*);
	gid_t *tmpgroups;
	long int lstart, lsize;
	int i;

	tmpgroups = malloc(limit * sizeof(gid_t));
	if (!tmpgroups)
		return NS_TRYAGAIN;
	/* insert primary membership */
	__gr_addgid(group, groups, limit, size);

	lstart = 0;
	lsize = limit;
	s = _nss_ldap_initgroups_dyn(user, group, &lstart, &lsize,
		&tmpgroups, 0, &err);
	if (s == NSS_STATUS_SUCCESS) {
		for (i = 0; i < lstart; i++)
			if (! __gr_addgid(tmpgroups[i], groups, limit, size))
				*retval = -1;
		s = NSS_STATUS_NOTFOUND;
	}
	free(tmpgroups);
		
	return nss2netbsderr[s];
}

ns_mtab *
nss_module_register(const char *source, unsigned int *mtabsize,
		    nss_module_unregister_fn *unreg)
{
	*mtabsize = sizeof(methods)/sizeof(methods[0]);
	*unreg = NULL;

	if (resize_grpbuf())
		return 0;

	return (methods);
}

--==_Exmh_18628298481600--