/* Copyright 2000, 2001, 2002, 2003, 2004 Laurent Wacrenier This file is part of libhome libhome is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. libhome is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libhome; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" static char const rcsid[] UNUSED = "$Id: libhome-preload.c,v 1.9 2005/09/14 08:57:00 lwa Exp $"; #define getpwnam system_getpwnam #define passwd system_passwd #if HAVE_GETSPNAM #define getspwnam system_getspwnam #endif #define setpassent system_setpassent #define setpwent system_setpwent #define endpwent system_endpwent #define getpwuid system_getpwuid #include #include #if HAVE_SHADOW_H #include #endif #undef getpwnam #undef passwd #undef setpassent #undef setpwent #undef endpwent #undef getpwuid #if HAVE_GETSPNAM #undef getspwnam #endif #include #include #define HOME_DONT_SUBSTITUTE_SYSTEM #include "hpwd.h" #include "hparam.h" #include static int init_preload(void) { extern int hparam_done; extern struct param home_param; if (hparam_done==0) { if (home_init(NULL)==NULL) { return -1; } else { home_param.real_getpwnam = dlsym(RTLD_NEXT, "getpwnam"); home_param.real_getpwuid = dlsym(RTLD_NEXT, "getpwuid"); #if HAVE_GETSPNAM home_param.real_getspwnam = dlsym(RTLD_NEXT, "getspwnam"); #endif home_param.real_endpwent = dlsym(RTLD_NEXT, "endpwent"); #if HAVE_SETPASSENT home_param.real_setpassent = dlsym(RTLD_NEXT, "setpassent"); #endif } } return 0; } static char *last_login = NULL; static struct system_passwd returned_passwd; static struct system_passwd *return_getpw(struct passwd *pwd) { if (pwd) { memset(&returned_passwd, 0, sizeof(struct system_passwd)); returned_passwd.pw_name = pwd->pw_name; returned_passwd.pw_passwd = pwd->pw_passwd; returned_passwd.pw_uid = pwd->pw_uid; returned_passwd.pw_gid = pwd->pw_gid; returned_passwd.pw_gecos = pwd->pw_gecos; returned_passwd.pw_dir = pwd->pw_dir; returned_passwd.pw_shell = pwd->pw_shell; #if HAVE_STRUCT_PASSWD_PW_CLASS #ifdef HAS_PW_CLASS returned_passwd.pw_class = pwd->pw_class; #else returned_passwd.pw_class = ""; #endif #endif #if HAVE_STRUCT_PASSWD_PW_EXPIRE #ifdef HAS_PW_EXPIRE returned_passwd.pw_expire = pwd->pw_expire; #else returned_passwd.pw_expire = 0; #endif #endif #if HAVE_STRUCT_PASSWD_PW_CHANGE #ifdef HAS_PW_CHANGE returned_passwd.pw_change = pwd->pw_change; #else returned_passwd.pw_change = 0; #endif #endif return &returned_passwd; } else { return NULL; } } struct system_passwd *getpwnam(char *login) { struct passwd *pwd; if (init_preload() == -1) { home_getpwnam_return(NULL); return NULL; } if (last_login && strcmp(login, last_login) == 0) return &returned_passwd; pwd = home_getpwnam(login); if (pwd) { last_login = login; return return_getpw(pwd); } last_login = NULL; return NULL; } struct system_passwd *getpwuid(uid_t uid) { if (last_login && returned_passwd.pw_uid == uid) return &returned_passwd; return return_getpw(home_getpwuid(uid)); } int setpassent(int stayopen) { if (init_preload() == -1) return 0; return home_setpassent(stayopen); } void setpwent(void) { if (init_preload() == -1) return; return home_setpwent(); } void endpwent(void) { if (init_preload() == -1) return; return home_endpwent(); }