/* PIPServer - A deamon for finger protocol v2 * * Copyright (C) 1999 Michael Baumer * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include #ifdef HAVE_STRINGS_H #include #endif /* HAVE_STRINGS_H */ #ifdef HAVE_PATHS_H #include #endif /* HAVE_PATHS_H */ #include #include #include "finger.h" #include "log.h" #include "statusdb.h" #include "local_user.h" void gecos_realname(finger_userinfo *finfo, char *gecos); /* return a list of possible passwd entries of the user * * Note: We do not make case insensitive compares * this allows explicit search for a Real Name that happens to be * the same as some login * * logelvel: * 0: do not print errors (user for 'finger @host' and statusdb) * 1: log errors (like nofinger exists) */ finger_userinfo * pwd_search_login(char *username, int loglevel) { struct passwd *pwd; static finger_userinfo finfo; /* rewind passwd file */ setpwent(); while ((pwd = getpwent())) { if (!strcmp(username, pwd->pw_name)) { /* don't check system logins */ if (pwd->pw_uid < config.first_uid) { /* But report them */ if (loglevel) log(LOG_WARNING, "attempted to finger %s", username); continue; } finfo.pw_name = pwd->pw_name; finfo.homedir = pwd->pw_dir; /* check if user doesn't want to be fingered */ if (findUserFile(&finfo, "nofinger")) { if (loglevel) log(LOG_WARNING, "attempted to finger %s, but user has 'nofinger' file", username); continue; } gecos_realname(&finfo, pwd->pw_gecos); return &finfo; } } return NULL; } finger_userinfo * pwd_search_realname(char *username) { struct passwd *pwd; char *idx; char *sidx; static finger_userinfo finfo; while ((pwd = getpwent())) { /* don't check system logins */ if (pwd->pw_uid < config.first_uid) continue; /* search beginning of realname */ sidx = pwd->pw_gecos; while(*sidx && !isalnum(*sidx)) sidx++; /* only check if username is not larger than realname */ if (strlen(sidx) < strlen(username)) continue; /* store end of realname */ idx = index(pwd->pw_gecos, ','); if (idx) *idx='\0'; while (1) { if (!strncasecmp(sidx, username, strlen(username))) { finfo.pw_name = pwd->pw_name; finfo.homedir = pwd->pw_dir; gecos_realname(&finfo, pwd->pw_gecos); /* Permission checks */ if (findUserFile(&finfo, "nofinger")) return NULL; return &finfo; } sidx=index(sidx, ' '); if (!sidx) break; while(*sidx && !isalnum(*sidx)) sidx++; } /* restore end of realname */ if (idx) *idx=','; } return NULL; } #ifndef HAVE_STRSEP char *strsep(char **stringp, const char *delim) { /* Unfortunately Solaris does not have this... */ char *s, *tmp; s = *stringp; while(*s && (*s != *delim)) s++; if (*s) { *s = '\0'; tmp = *stringp; *stringp = ++s; return tmp; } return NULL; } #endif /* HAVE_STRSEP */ /* Parse the gecos field and return the values in the * finger_userinfo structure. * * Gecos = Realname [, Office [, Office Phone [, Home Phone [, system]]]] */ void gecos_realname(finger_userinfo *finfo, char *gecos) { char *token = gecos; finfo->office = NULL; finfo->office_phone = NULL; finfo->home_phone = NULL; finfo->pw_realname = strsep(&token, ","); if (!finfo->pw_realname) { finfo->pw_realname = token; return; } if (!strlen(finfo->pw_realname)) finfo->pw_realname = ""; finfo->office = strsep(&token, ","); if (!finfo->office) { finfo->office = token; return; } if (!strlen(finfo->office)) finfo->office = NULL; finfo->office_phone = strsep(&token, ","); if (!finfo->office_phone) { finfo->office_phone = token; return; } if (!strlen(finfo->office_phone)) finfo->office_phone = NULL; finfo->home_phone = strsep(&token, ","); if (!finfo->home_phone) { finfo->home_phone = token; return; } if (!strlen(finfo->home_phone)) finfo->home_phone = NULL; }