/* PIPServer - A deamon for finger protocol v2
*
* Copyright (C) 1999 Michael Baumer <baumi@vis.ethz.ch>
*
* 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 <config.h>
#include <pwd.h>
#include <sys/types.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif /* HAVE_STRINGS_H */
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif /* HAVE_PATHS_H */
#include <stdlib.h>
#include <ctype.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1