FoolProofing getpwxxx() cache patch

Richard Bollinger rabollinger at home.com
Tue Jan 30 14:51:41 GMT 2001


Relative to today's CVS source for 2_2, here's the clean up patch for
getpwxxx caching.

It does the following:

1) fixes interaction between setpwent(), getpwent() endpwent(), getpwnam()
and getpwuid(), such that the cache pointer is invalidated when appropriate.
This required adding wrappers for set/get/endpwent().

2) restores the rule that the buffer created and updated by setup_pwret is
disposable (it is _not_ the cache).  This made the code in getpwnam/uid a
bit shorter and simpler.

Thanks, Rich Bollinger

--- ../source/include/proto.h Mon Jan 29 07:15:18 2001
+++ ./include/proto.h Tue Jan 30 09:05:07 2001
@@ -307,6 +307,9 @@
 int groups_max(void);
 int sys_getgroups(int setlen, gid_t *gidset);
 int sys_setgroups(int setlen, gid_t *gidset);
+void sys_setpwent();
+struct passwd *sys_getpwent();
+void sys_endpwent();
 struct passwd *sys_getpwnam(const char *name);
 struct passwd *sys_getpwuid(uid_t uid);
 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
--- ../source/rpc_server/srv_samr.c Tue Jan 16 07:45:43 2001
+++ ./rpc_server/srv_samr.c Tue Jan 30 09:07:48 2001
@@ -215,7 +215,7 @@
  if (pw_buf == NULL) return False;

  if (current_idx == 0) {
-  setpwent();
+  sys_setpwent();
  }

  /* These two cases are inefficient, but should be called very rarely */
@@ -228,7 +228,7 @@
    char *unmap_name;

    if(!orig_done) {
-    if ((pwd = getpwent()) == NULL) break;
+    if ((pwd = sys_getpwent()) == NULL) break;
     current_idx++;
     orig_done = True;
    }
@@ -246,8 +246,8 @@
   }
  } else if (start_idx < current_idx) {
   /* We are already too far; start over and advance to start_idx */
-  endpwent();
-  setpwent();
+  sys_endpwent();
+  sys_setpwent();
   current_idx = 0;
   mapped_idx = 0;
   orig_done = False;
@@ -255,7 +255,7 @@
    char *unmap_name;

    if(!orig_done) {
-    if ((pwd = getpwent()) == NULL) break;
+    if ((pwd = sys_getpwent()) == NULL) break;
     current_idx++;
     orig_done = True;
    }
@@ -282,7 +282,7 @@

   /* This does the original UNIX user itself */
   if(!orig_done) {
-   if ((pwd = getpwent()) == NULL) break;
+   if ((pwd = sys_getpwent()) == NULL) break;

    /* Don't enumerate winbind users as they are not local */

@@ -337,7 +337,7 @@

  if (pwd == NULL) {
   /* totally done, reset everything */
-  endpwent();
+  sys_endpwent();
   current_idx = 0;
   mapped_idx = 0;
  }
--- ../source/lib/system.c Thu Jan 25 07:45:13 2001
+++ ./lib/system.c Tue Jan 30 09:04:57 2001
@@ -618,13 +618,19 @@
 #endif

 /**************************************************************************
+ Wrappers for setpwent(), getpwent() and endpwent().
+***************************************************************************
*/
+
+void sys_setpwent() { sv_pw_ret = NULL; setpwent(); };
+struct passwd *sys_getpwent() { return sv_pw_ret = getpwent(); };
+void sys_endpwent() { sv_pw_ret = NULL; endpwent(); };
+
+/**************************************************************************
  Wrapper for getpwnam(). Always returns a static that can be modified.

****************************************************************************
/

 struct passwd *sys_getpwnam(const char *name)
 {
- struct passwd *pw_ret;
-
  if (!name || !name[0])
   return NULL;

@@ -634,17 +640,13 @@
   DEBUG(2,("getpwnam(%s) avoided - using cached results\n",name));
   num_lookups++;
   num_lookups = (num_lookups % PW_RET_CACHE_MAX_LOOKUPS);
-  return sv_pw_ret;
+  return setup_pwret(sv_pw_ret);
  }

  /* no cache hit--use old lookup instead */
  DEBUG(2,("getpwnam(%s) called\n",name));
- if (!(pw_ret = getpwnam(name)))
-  return NULL;
-
  num_lookups = 1;
-
- return (sv_pw_ret = setup_pwret(pw_ret));
+ return setup_pwret(sv_pw_ret = getpwnam(name));
 }

 /**************************************************************************
@@ -653,8 +655,6 @@

 struct passwd *sys_getpwuid(uid_t uid)
 {
- struct passwd *pw_ret;
-
  if (num_lookups && sv_pw_ret && (uid == sv_pw_ret->pw_uid))
  {
   DEBUG(2,("getpwuid(%d) avoided - using cached results\n",uid));
@@ -664,12 +664,8 @@
  }

  DEBUG(2,("getpwuid(%d) called\n",uid));
- if (!(pw_ret = getpwuid(uid)))
-  return NULL;
-
  num_lookups = 1;
-
-   return (sv_pw_ret = setup_pwret(pw_ret));
+ return setup_pwret(sv_pw_ret = getpwuid(uid));
 }

 /**************************************************************************






More information about the samba-technical mailing list