Subject: initgroups call in src/osdep/unix/log_std.c

From: Steve Barber <[email-masked]>
Date: Tue, 30 Sep 2003 18:08:03 -0400

In tracking down why one of our servers was hammering an NIS
server, I found that it was nearly continuously enumerating
the groups map, which is fairly large.

I believe this is because of the initgroups call in
src/osdep/unix/log_std.c.  This call makes sense in an IMAP
context but I can't see a need for it in a POP context,
and of course POP connections are far more frequent.

(a) am I missing something, and
(b) assuming I want to get rid of it in the POP server, is there an
    elegant way to patch this so I don't have to do two separate builds
    (one for pop, one for imap)?

Thanks -
Steve
-- 
------------------------------------------------------------------
 For information about this mailing list, and its archives, see: 
 http://www.washington.edu/imap/c-client-list.html
------------------------------------------------------------------

---

From: Mark Crispin <[email-masked]>
Date: Tue, 30 Sep 2003 17:35:16 -0700 (Pacific Daylight Time)

Steve -

You're not the only person who has experienced a performance problem due
to initgroups(); similar problems have been reported by people who
authenticate via SQL.

There is currently no mechanism to disable the initgroups() call for the
POP server only.  As you've noted, it's very definitely necessary for the
IMAP server.  It shouldn't be too difficult to put in such a feature if it
turns out that's the only feasible solution.

However, IMHO disabling initgroups() for POP is just a band-aid for the
real problem, which is the performance problem in initgroups()  when used
with NIS.  This is something that should be taken up with your NIS vendor.
The problem isn't going to go away and will get worse, even with the
band-aid.

-- Mark --

http://staff.washington.edu/mrc
Science does not emerge from voting, party politics, or public debate.
Si vis pacem, para bellum.

---

From: Steve Barber <[email-masked]>
Date: Tue, 30 Sep 2003 20:51:36 -0400

> turns out that's the only feasible solution.

Hi Mark,

I'd be very interested in such a feature.  I'm even willing to take a first
crack at it if you can give me some hints as to how, in that code segment,
I might cleanly be able to determine whether it's being used from ipop3d.

> The problem isn't going to go away and will get worse, even with the

I agree, however a band-aid is all I need here and I'm stuck with NIS for
the time being.  This mail server (and surrounding infrastructure) only
has a finite lifetime, but it's long enough that I'd like to make it work
better in the meantime.

Thanks,
Steve

---

From: Mark Crispin <[email-masked]>
Date: Tue, 30 Sep 2003 18:02:20 -0700 (Pacific Daylight Time)

> I might cleanly be able to determine whether it's being used from ipop3d.

I suggest something getting the service name and skipping the initgroups
call if it is pop, e.g.:

long loginpw (struct passwd *pw,int argc,char *argv[])
{
  uid_t uid = pw->pw_uid;
  char *name = cpystr (pw->pw_name);
  char *service = (char *) mail_parameters (NIL,GET_SERVICENAME,NIL);
  long ret = !(setgid (pw->pw_gid) ||
	       (strcmp (service,"pop") ? initgroups (name,pw->pw_gid) : T) ||
	       setuid (uid));
  fs_give ((void **) &name);
  return ret;
}

-- Mark --

---

From: Steve Barber <[email-masked]>
Date: Wed, 1 Oct 2003 14:37:46 -0400

>   fs_give ((void **) &name);

Thanks Mark.  That was almost it.  This appears to work for me:

--- ./src/osdep/unix/log_std.c~ 2000-10-24 19:40:53.000000000 -0400
+++ ./src/osdep/unix/log_std.c  2003-09-30 22:29:26.340847000 -0400
@@ -29,7 +29,9 @@
 {
   uid_t uid = pw->pw_uid;
   char *name = cpystr (pw->pw_name);
-  long ret = !(setgid (pw->pw_gid) || initgroups (name,pw->pw_gid) ||
+  char *service = (char *) mail_parameters (NIL,GET_SERVICENAME,NIL);
+  long ret = !(setgid (pw->pw_gid) ||
+	       (strcmp (service,"pop") ? initgroups (name,pw->pw_gid) : NIL) ||
	       setuid (uid));
   fs_give ((void **) &name);
   return ret;

Steve