Samba NIS problem and solution
Gerald Carter
gcarter at valinux.com
Wed Oct 18 15:49:00 GMT 2000
Brian M Hoy wrote:
>
> Hi Jerry,
>
> We have recently upgraded from Samba 2.0.5a to 2.0.7 (both
> using Solaris 2.6 on an Ultra-1). Everything was fine,
> except that our NIS server was now idling at between
> 5-10%, instead of the prior 0.3-0.5%.
>
> Anyway, to cut a long story short, when Samba checks to see
> if a user is in a group (lib/username.c:user_in_group_list)
> it iterates through every group (think setgrent,
> getgrent, endgrent) looking for the group in question.
> When you have lots of users and 320+ groups, and
> regularly perform this _linear_ search and wrap each iteration
> up in RPC calls to NIS you are going to take a CPU hit.
Uugghhh...I just checked 2.0.7 and you are correct. That's
a horrible way to do it!
> The solution to this problem is conveniently located in
> the old 2.0.5a code! Simply call getgrnam() once - one RPC
> call and the NIS server can search efficiently (think
> hashes), and suddenly the loading on ypserv drops fifteen
> fold.
>
> There are no hints in the release notes or source code
> about this change. I am puzzled as to why the change was
> made. Any ideas? Perhaps getgrnam() does not work on
> some platforms?
>
> Perhaps the developers might like to reinstate the old
> code unless they now of a good reason for keeping it.
>
> BTW I note that Samba 2.2 alpha 0 has the same
> user_in_group_list() code as 2.0.7 (ie. not very NIS
> friendly), with one exception! It is missing the setgrent()
> before the getgrent()s and endgrent(). This looks like a
> bug to me. Comments anyone.
Although it is in 2.2alpha0, it is not in the
SAMBA_2_2 CVS tree. From lib/username.c (I
removed the DEBUG statements)
{
check to see if the group is the user's
primary group;
if yes then return true;
check to see if the group is one of the user's
secondary groups;
if yes then return true;
return false;
}
......................
static BOOL user_in_unix_group_list(char *user,char *gname)
{
struct group *gptr;
char **member;
struct passwd *pass = Get_Pwnam(user,False);
/*
* We need to check the users primary group as this
* group is implicit and often not listed in the
* group database.
*/
if (pass) {
gptr = getgrgid(pass->pw_gid);
if (gptr && strequal(gptr->gr_name,gname)) {
return True;
}
}
if ((gptr = (struct group *)getgrnam(gname)) == NULL) {
return False;
}
member = gptr->gr_mem;
while (member && *member) {
if (strequal(*member,user)) {
return(True);
}
member++;
}
return False;
}
----------------------------------------------------------------------
/\ Gerald (Jerry) Carter Professional Services
\/ http://www.valinux.com/ VA Linux Systems gcarter at valinux.com
http://www.samba.org/ SAMBA Team jerry at samba.org
http://www.plainjoe.org/ jerry at plainjoe.org
"...a hundred billion castaways looking for a home."
- Sting "Message in a Bottle" ( 1979 )
More information about the samba-ntdom
mailing list