Subject: Re: pkg/32988: Bug in databases/nss_ldap
To: None <drochner@netbsd.org, gnats-admin@netbsd.org,>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: pkgsrc-bugs
Date: 03/15/2006 14:40:03
The following reply was made to PR pkg/32988; it has been noted by GNATS.

From: Matthias Drochner <M.Drochner@fz-juelich.de>
To: thesing@cs.uni-sb.de
Cc: gnats-bugs@netbsd.org
Subject: Re: pkg/32988: Bug in databases/nss_ldap
Date: Wed, 15 Mar 2006 15:39:56 +0100

 This is a multipart MIME message.
 
 --==_Exmh_12444497264550
 Content-Type: text/plain; charset=us-ascii
 
 
 > fails to copy the already present gid_t's
 
 Ah yes, sorry. Never tested this, obviously...
 
 > always puts the primary gid_t of the user in slot 0
 
 This shouldn't be too bad - every getgroupmembership
 backend puts it into the first slot. This means: if
 there is anything in the array before, the primary
 group is already there -- there is also no strict
 need to check for duplicates.
 What should be done is to check all added memberships
 for duplicates. At least the implementations in libc
 do so.
 
 So I've aligned the implementation more to the
 backends in libc. Can you give the appended patch a try?
 (Can't test myself atm. I've managed to corrupt my
 LDAP database.)
 
 best regards
 Matthias
 
 
 
 --==_Exmh_12444497264550
 Content-Type: text/plain ; name="nssldap.txt"; charset=us-ascii
 Content-Description: nssldap.txt
 Content-Disposition: attachment; filename="nssldap.txt"
 
 diff -r 5efa09c5b5c9 databases/nss_ldap/files/netbsd.c
 --- a/databases/nss_ldap/files/netbsd.c	Wed Mar 15 12:37:15 2006 +0100
 +++ b/databases/nss_ldap/files/netbsd.c	Wed Mar 15 15:21:18 2006 +0100
 @@ -5,6 +5,7 @@
  #include <grp.h>
  #include <nsswitch.h>
  #include <stdarg.h>
 +#include <stdlib.h>
  #include <string.h>
  
  #include "netbsd.h"
 @@ -440,6 +441,28 @@ netbsd_getgrgid_r(void *rv, void *cb_dat
  	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)
  {
 @@ -453,32 +476,24 @@ netbsd_getgroupmembership(void *rv, void
  	int *size = va_arg(ap, int*);
  	gid_t *tmpgroups;
  	long int lstart, lsize;
 -	int origsize = *size;
 +	int i;
  
  	tmpgroups = malloc(limit * sizeof(gid_t));
  	if (!tmpgroups)
  		return NS_TRYAGAIN;
  	/* insert primary membership */
 -	if (*size < limit) {
 -		tmpgroups[0] = group;
 -		(*size)++;
 -	}
 -	lstart = *size;
 +	__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) {
 -		if (lstart > limit) {
 -			memcpy(groups, tmpgroups, limit * sizeof(gid_t));
 -			*retval = -1;
 -		} else {
 -			memcpy(groups, tmpgroups, lstart * sizeof(gid_t));
 -			*retval = 0;
 -		}
 -		*size = lstart;
 +		for (i = 0; i < lstart; i++)
 +			if (! __gr_addgid(tmpgroups[i], groups, limit, size))
 +				*retval = -1;
  		s = NSS_STATUS_NOTFOUND;
 -	} else
 -		*size = origsize;
 +	}
  	free(tmpgroups);
  		
  	return nss2netbsderr[s];
 
 --==_Exmh_12444497264550--