diff options
Diffstat (limited to 'source/lib/system.c')
-rw-r--r-- | source/lib/system.c | 142 |
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); } |