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