summaryrefslogtreecommitdiffstats
path: root/source/lib/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/lib/system.c')
-rw-r--r--source/lib/system.c142
1 files changed, 110 insertions, 32 deletions
diff --git a/source/lib/system.c b/source/lib/system.c
index 873b8737d50..a449600b21f 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba system utilities
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1998-2002
@@ -486,7 +487,7 @@ struct hostent *sys_gethostbyname(const char *name)
/* Does this name have any dots in it? If so, make no change */
- if (strchr_m(name, '.'))
+ if (strchr(name, '.'))
return(gethostbyname(name));
/* Get my hostname, which should have domain name
@@ -496,7 +497,7 @@ struct hostent *sys_gethostbyname(const char *name)
gethostname(hostname, sizeof(hostname) - 1);
hostname[sizeof(hostname) - 1] = 0;
- if ((domain = strchr_m(hostname, '.')) == NULL)
+ if ((domain = strchr(hostname, '.')) == NULL)
return(gethostbyname(name));
/* Attach domain name to query and do modified query.
@@ -744,47 +745,131 @@ int sys_setgroups(int setlen, gid_t *gidset)
#endif /* HAVE_SETGROUPS */
+/*
+ * We only wrap pw_name and pw_passwd for now as these
+ * are the only potentially modified fields.
+ */
+
+/**************************************************************************
+ Helper function for getpwnam/getpwuid wrappers.
+****************************************************************************/
+
+struct saved_pw {
+ fstring pw_name;
+ fstring pw_passwd;
+ fstring pw_gecos;
+ pstring pw_dir;
+ pstring pw_shell;
+ struct passwd pass;
+};
+
+static struct saved_pw pw_mod; /* This is the structure returned - can be modified. */
+static struct saved_pw pw_cache; /* This is the structure saved - used to check cache. */
+
+static int num_lookups; /* Counter so we don't always use cache. */
+#ifndef PW_RET_CACHE_MAX_LOOKUPS
+#define PW_RET_CACHE_MAX_LOOKUPS 100
+#endif
+
+static void copy_pwent(struct saved_pw *dst, struct passwd *pass)
+{
+ memcpy((char *)&dst->pass, pass, sizeof(struct passwd));
+
+ fstrcpy(dst->pw_name, pass->pw_name);
+ dst->pass.pw_name = dst->pw_name;
+
+ fstrcpy(dst->pw_passwd, pass->pw_passwd);
+ dst->pass.pw_passwd = dst->pw_passwd;
+
+ fstrcpy(dst->pw_gecos, pass->pw_gecos);
+ dst->pass.pw_gecos = dst->pw_gecos;
+
+ pstrcpy(dst->pw_dir, pass->pw_dir);
+ dst->pass.pw_dir = dst->pw_dir;
+
+ pstrcpy(dst->pw_shell, pass->pw_shell);
+ dst->pass.pw_shell = dst->pw_shell;
+}
+
+static struct passwd *setup_pwret(struct passwd *pass)
+{
+ if (pass == NULL) {
+ /* Clear the caches. */
+ memset(&pw_cache, '\0', sizeof(struct saved_pw));
+ memset(&pw_mod, '\0', sizeof(struct saved_pw));
+ num_lookups = 0;
+ return NULL;
+ }
+
+ copy_pwent( &pw_mod, pass);
+
+ if (pass != &pw_cache.pass) {
+
+ /* If it's a cache miss we must also refill the cache. */
+
+ copy_pwent( &pw_cache, pass);
+ num_lookups = 1;
+
+ } else {
+
+ /* Cache hit. */
+
+ num_lookups++;
+ num_lookups = (num_lookups % PW_RET_CACHE_MAX_LOOKUPS);
+ }
+
+ return &pw_mod.pass;
+}
+
/**************************************************************************
Wrappers for setpwent(), getpwent() and endpwent()
****************************************************************************/
void sys_setpwent(void)
{
+ setup_pwret(NULL); /* Clear cache. */
setpwent();
}
struct passwd *sys_getpwent(void)
{
- return getpwent();
+ return setup_pwret(getpwent());
}
void sys_endpwent(void)
{
+ setup_pwret(NULL); /* Clear cache. */
endpwent();
}
/**************************************************************************
- Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
+ Wrapper for getpwnam(). Always returns a static that can be modified.
****************************************************************************/
struct passwd *sys_getpwnam(const char *name)
{
- return getpwnam(name);
-}
+ if (!name || !name[0])
+ return NULL;
-struct passwd *sys_getpwuid(uid_t uid)
-{
- return getpwuid(uid);
-}
+ /* check for a cache hit first */
+ if (num_lookups && pw_cache.pass.pw_name && !strcmp(name, pw_cache.pass.pw_name)) {
+ return setup_pwret(&pw_cache.pass);
+ }
-struct group *sys_getgrnam(const char *name)
-{
- return getgrnam(name);
+ return setup_pwret(getpwnam(name));
}
-struct group *sys_getgrgid(gid_t gid)
+/**************************************************************************
+ Wrapper for getpwuid(). Always returns a static that can be modified.
+****************************************************************************/
+
+struct passwd *sys_getpwuid(uid_t uid)
{
- return getgrgid(gid);
+ if (num_lookups && pw_cache.pass.pw_name && (uid == pw_cache.pass.pw_uid)) {
+ return setup_pwret(&pw_cache.pass);
+ }
+
+ return setup_pwret(getpwuid(uid));
}
#if 0 /* NOT CURRENTLY USED - JRA */
@@ -1219,37 +1304,30 @@ const char *sys_dlerror(void)
#endif
}
-int sys_dup2(int oldfd, int newfd)
-{
-#if defined(HAVE_DUP2)
- return dup2(oldfd, newfd);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
/**************************************************************************
Wrapper for Admin Logs.
****************************************************************************/
-void sys_adminlog(int priority, char *format_str, ...)
+void sys_adminlog(int priority, const char *format_str, ...)
{
va_list ap;
int ret;
- char *msgbuf = NULL;
+ char **msgbuf = NULL;
+
+ if (!lp_admin_log())
+ return;
va_start( ap, format_str );
- ret = vasprintf( &msgbuf, format_str, ap );
+ ret = vasprintf( msgbuf, format_str, ap );
va_end( ap );
if (ret == -1)
return;
#if defined(HAVE_SYSLOG)
- syslog( priority, "%s", msgbuf );
+ syslog( priority, "%s", *msgbuf );
#else
- DEBUG(0,("%s", msgbuf ));
+ DEBUG(0,("%s", *msgbuf ));
#endif
- SAFE_FREE(msgbuf);
+ SAFE_FREE(*msgbuf);
}