[10333] in Athena Bugs
the athena fingerd
daemon@ATHENA.MIT.EDU (Jonathan I. Kamens)
Mon Mar 1 13:11:18 1993
Date: Mon, 1 Mar 93 13:11:48 -0500
From: "Jonathan I. Kamens" <jik@GZA.COM>
To: marc@MIT.EDU
Cc: bugs@Athena.MIT.EDU, warlord@Athena.MIT.EDU
Cc: postmaster@Athena.MIT.EDU
In-Reply-To: Marc Horowitz's message of Sat, 27 Feb 93 17:15:37 EST <9302272215.AA22597@oliver.MIT.EDU>
Date: Sat, 27 Feb 93 17:15:37 EST
From: Marc Horowitz <marc@Athena.MIT.EDU>
The ATHENA.MIT.EDU fingerd isn't in the standard release, so problems
with it shouldn't be sent to "bugs". "Postmaster" would have been a
better choice.
It seems to use only the first word and last word in the real-name
field. IMHO, this is an unreasonable limitation, and confusing at
times.
You're right. The patch below fixes several things:
*) The first five words in the user's full name that are more than one
character long and do not end in a period are indexed.
*) Furthermore, if there are fewer than five indexed words in the
user's full name, the user's nickname is indexed as well.
*) The fingerd output no longer puts extra spaces at the end of each
line.
*) Names longer than 19 characters will no longer confuse the
software. Instead, lookups will be based on the first 19
characters of the name.
I don't know when the postmaster's will have time to apply this patch,
but here it is....
(Brought to you courtesy of Geer Zolot Associates :-)
*** 1.2 1989/02/03 14:29:04
--- Makefile 1993/03/01 17:43:00
***************
*** 1,7 ****
OLD_DB_FILE= /site/lookup/passwd
NEW_DB_FILE= /site/lookup/passwd.new
PASSWD_FILE= /site/lookup/passwd
! CFLAGS= -O -DPASSWD_FILE=\"$(PASSWD_FILE)\" -DEMAIL
BUILDFLAGS= -DDB_FILE=\"$(NEW_DB_FILE)\"
LOOKUPFLAGS= -DDB_FILE=\"$(OLD_DB_FILE)\"
FINGERFLAGS= -DDB_FILE=\"$(OLD_DB_FILE)\"
--- 1,10 ----
OLD_DB_FILE= /site/lookup/passwd
NEW_DB_FILE= /site/lookup/passwd.new
PASSWD_FILE= /site/lookup/passwd
! CDEBUGFLAGS= -g
! CFLAGS= $(CDEBUGFLAGS) -DPASSWD_FILE=\"$(PASSWD_FILE)\" \
! -DEMAIL -DNICKNAME
!
BUILDFLAGS= -DDB_FILE=\"$(NEW_DB_FILE)\"
LOOKUPFLAGS= -DDB_FILE=\"$(OLD_DB_FILE)\"
FINGERFLAGS= -DDB_FILE=\"$(OLD_DB_FILE)\"
*** 1.3 1989/02/06 14:39:11
--- db.h 1993/03/01 18:05:55
***************
*** 22,36 ****
/* last name, or username */
#define MAX_KEY_LEN 20 /* maximum length of key */
/* (first name, last name */
! /* or username) */
#define MAX_PASSWD_LEN 512 /* maximum length of a */
/* passwd file line */
#define MAX_USERNAME 9
struct my_passwd {
char file_ent[MAX_PASSWD_LEN];
! char first_name[MAX_KEY_LEN];
! char last_name[MAX_KEY_LEN];
char user_name[MAX_KEY_LEN];
int uid;
};
--- 22,37 ----
/* last name, or username */
#define MAX_KEY_LEN 20 /* maximum length of key */
/* (first name, last name */
! /* or username), including */
! /* the NULL */
#define MAX_PASSWD_LEN 512 /* maximum length of a */
/* passwd file line */
#define MAX_USERNAME 9
+ #define MAX_NAMES 5
struct my_passwd {
char file_ent[MAX_PASSWD_LEN];
! char names[MAX_NAMES][MAX_KEY_LEN];
char user_name[MAX_KEY_LEN];
int uid;
};
*** 1.3 1989/01/31 04:38:17
--- db_build.c 1993/03/01 18:05:18
***************
*** 149,161 ****
DBM *db;
struct my_passwd *pass;
{
! int status = 0;
! if (*pass->first_name)
! status |= add_name(db, 'F', pass->first_name, pass->uid);
! if (*pass->last_name)
! status |= add_name(db, 'L', pass->last_name, pass->uid);
if (*pass->user_name)
! status |= add_name(db, 'U', pass->user_name, pass->uid);
return(status);
}
--- 149,164 ----
DBM *db;
struct my_passwd *pass;
{
! int status = 0, i;
!
! for (i = 0; i < MAX_NAMES; i++) {
! if (! *pass->names[i]) {
! break;
! }
! status |= add_name(db, pass->names[i], pass->uid);
! }
if (*pass->user_name)
! status |= add_name(db, pass->user_name, pass->uid);
return(status);
}
***************
*** 164,172 ****
! add_name(db, type, name, uid)
DBM *db;
- char type;
char *name;
int uid;
{
--- 167,174 ----
! add_name(db, name, uid)
DBM *db;
char *name;
int uid;
{
***************
*** 173,185 ****
datum key, entry;
int data[MAX_MATCH];
int size;
! char key_string[MAX_KEY_LEN];
int status;
! if (strlen(name) > MAX_KEY_LEN - 2)
! name[MAX_KEY_LEN - 2] = '\0';
! *key_string = type;
! strcpy(key_string + 1, name);
key.dptr = key_string;
key.dsize = strlen(key.dptr) + 1;
--- 175,186 ----
datum key, entry;
int data[MAX_MATCH];
int size;
! char key_string[MAX_KEY_LEN+1];
int status;
! *key_string = 'N';
! strncpy(key_string + 1, name, MAX_KEY_LEN - 1);
! key_string[MAX_KEY_LEN] = '\0';
key.dptr = key_string;
key.dsize = strlen(key.dptr) + 1;
***************
*** 238,244 ****
int status;
key.dptr = key_string;
! *key.dptr = 'N';
bcopy((char *) &pass_ent->uid, key.dptr + 1, sizeof(int));
key.dptr[sizeof(int) + 1] = '\0';
key.dsize = sizeof(int) + 2;
--- 239,245 ----
int status;
key.dptr = key_string;
! *key.dptr = '#';
bcopy((char *) &pass_ent->uid, key.dptr + 1, sizeof(int));
key.dptr[sizeof(int) + 1] = '\0';
key.dsize = sizeof(int) + 2;
***************
*** 315,322 ****
*result = '\0';
get_uid(entry.file_ent, &entry.uid);
! get_firstname(entry.file_ent, entry.first_name);
! get_lastname(entry.file_ent, entry.last_name);
get_username(entry.file_ent, entry.user_name);
return(&entry);
--- 316,322 ----
*result = '\0';
get_uid(entry.file_ent, &entry.uid);
! get_names(entry.file_ent, entry.names);
get_username(entry.file_ent, entry.user_name);
return(&entry);
***************
*** 377,394 ****
/*
! * The first name is the stuff between the fourth colon and either
! * the first space following it or the first comma following it,
! * whichever comes first.
*/
! get_firstname(pass_ent, firstname)
! char *pass_ent, *firstname;
{
! char *ptr, *space_ptr, *comma_ptr, *to_ptr;
! int i;
! to_ptr = firstname;
! *to_ptr = '\0';
ptr = pass_ent;
for (i = 4; i; i--) { /* skip four colons; if they aren't */
--- 377,399 ----
/*
! * Take the field after the fourth colon and before the first comma or
! * colon after the fourth colon, and split it up into a maximum of
! * MAX_NAMES space-separated fields. Don't index any words that are
! * only one character long or that end in periods.
! *
! * Also, if NICKNAME is defined, index the nickname, which is between
! * the first and second commas after the fourth colon.
*/
! get_names(pass_ent, names)
! char *pass_ent, names[MAX_NAMES][MAX_KEY_LEN];
{
! char *ptr, *comma_ptr, *to_ptr;
! int i, j;
! for (i = 0; i < MAX_NAMES; i++) {
! *names[i] = '\0';
! }
ptr = pass_ent;
for (i = 4; i; i--) { /* skip four colons; if they aren't */
***************
*** 397,457 ****
return(0);
}
! space_ptr = index(ptr, ' ');
! comma_ptr = index(ptr, ',');
!
! for ( ; ((ptr != space_ptr) && (ptr != comma_ptr)); ptr++, to_ptr++)
! if (isupper(*ptr))
! *to_ptr = tolower(*ptr);
! else
! *to_ptr = *ptr;
!
! *to_ptr = '\0';
!
! return(0);
! }
!
!
!
! /*
! * The last name is the stuff before the first comma in the GECOS
! * field, but after the last space in the GECOS field.
! */
! get_lastname(pass_ent, lastname)
! char *pass_ent, *lastname;
! {
! char *ptr, *to_ptr, *space_ptr, *end_ptr;
! int i;
!
! to_ptr = lastname;
! *to_ptr = '\0';
!
! ptr = pass_ent;
! for (i = 4; i; i--) { /* skip four colons */
! ptr = index(ptr, ':');
! if (! ptr++)
! return(0);
}
-
- end_ptr = index(ptr, ',');
- if (! end_ptr) /* there's no GECOS field separator; how strange! */
- return(0);
-
- for (space_ptr = end_ptr; ((space_ptr > ptr) && (*space_ptr != ' '));
- space_ptr--);
-
- if ((space_ptr == ptr) && (*space_ptr != ' '))
- return(0);
-
- ptr = space_ptr + 1;
- for ( ; ptr < end_ptr; ptr++, to_ptr++)
- if (isupper(*ptr))
- *to_ptr = tolower(*ptr);
- else
- *to_ptr = *ptr;
-
- *to_ptr = '\0';
return(0);
}
--- 402,442 ----
return(0);
}
! #ifdef NICKNAME
! ((comma_ptr = index(ptr, ',')) && (comma_ptr = index(comma_ptr + 1, ',')))
! || (comma_ptr = index(ptr, ':')) || (comma_ptr = index(ptr, '\0'));
! #else
! (comma_ptr = index(ptr, ',')) || (comma_ptr = index(ptr, ':')) ||
! (comma_ptr = index(ptr, '\0'));
! #endif
! for (i = 0; (i < MAX_NAMES) && *ptr && (ptr < comma_ptr); i++, ptr++) {
! to_ptr = names[i];
! for (j = 0; j < MAX_KEY_LEN-1; j++) {
! if ((! *ptr) || (*ptr == ' ') || (*ptr == ',') ||
! (ptr >= comma_ptr)) {
! break;
! }
! if (isupper(*ptr)) {
! to_ptr[j] = tolower(*ptr);
! }
! else {
! to_ptr[j] = *ptr;
! }
! ptr++;
! }
! /* For names that are longer than the maximum length, skip */
! /* over the extra. */
! while (*ptr && (*ptr != ' ') && (*ptr != ',') && (ptr < comma_ptr)) {
! ptr++;
! }
! to_ptr[j] = '\0';
! if ((j < 2) || (to_ptr[j-1] == '.')) {
! *names[i] = '\0';
! i--;
! continue;
! }
}
return(0);
}
*** 1.8 1991/01/01 04:43:58
--- db_finger.c 1993/03/01 18:06:28
***************
*** 69,76 ****
usage()
{
! printf("Usage: finger firstname@athena.mit.edu\n");
! printf(" or finger lastname@athena.mit.edu\n");
printf(" or finger username@athena.mit.edu\n");
return(0);
}
--- 69,75 ----
usage()
{
! printf("Usage: finger name@athena.mit.edu\n");
printf(" or finger username@athena.mit.edu\n");
return(0);
}
***************
*** 98,121 ****
sizeof(int) * size);
total += size;
}
! uids = lookup_name(db, name, 'F', &size);
if (uids) {
bcopy((char *) uids, (char *) (all_uids + total),
sizeof(int) * size);
total += size;
}
- uids = lookup_name(db, name, 'L', &size);
- if (uids) {
- bcopy((char *) uids, (char *) (all_uids + total),
- sizeof(int) * size);
- total += size;
- }
total = unique(all_uids, total);
if (total)
print_uids(db, all_uids, total);
else
! printf("No users with first name, last name or user name %s.\n",
name);
return(0);
}
--- 97,114 ----
sizeof(int) * size);
total += size;
}
! uids = lookup_name(db, name, 'N', &size);
if (uids) {
bcopy((char *) uids, (char *) (all_uids + total),
sizeof(int) * size);
total += size;
}
total = unique(all_uids, total);
if (total)
print_uids(db, all_uids, total);
else
! printf("No users with name or user name %s.\n",
name);
return(0);
}
***************
*** 152,164 ****
int *size; /* RETURN */
{
datum key, entry;
! char key_string[MAX_KEY_LEN];
static data_array[MAX_MATCH];
key.dptr = key_string;
*key.dptr = type;
! strncpy(key.dptr + 1, name, MAX_KEY_LEN - 2);
! key.dptr[MAX_KEY_LEN - 1] = '\0';
key.dsize = strlen(key.dptr) + 1;
entry = dbm_fetch(db, key);
--- 145,157 ----
int *size; /* RETURN */
{
datum key, entry;
! char key_string[MAX_KEY_LEN+1];
static data_array[MAX_MATCH];
key.dptr = key_string;
*key.dptr = type;
! strncpy(key.dptr + 1, name, MAX_KEY_LEN - 1);
! key.dptr[MAX_KEY_LEN] = '\0';
key.dsize = strlen(key.dptr) + 1;
entry = dbm_fetch(db, key);
***************
*** 186,192 ****
char key_string[sizeof(int) + 2];
key.dptr = key_string;
! *key.dptr = 'N';
key.dsize = sizeof(int) + 2;
for (i = 0; i < size; i++) {
--- 179,185 ----
char key_string[sizeof(int) + 2];
key.dptr = key_string;
! *key.dptr = '#';
key.dsize = sizeof(int) + 2;
for (i = 0; i < size; i++) {
***************
*** 239,254 ****
get_office_phone(user, office_phone, sizeof(office_phone));
printf("Login name: %-28s", username);
! printf("In real life: %-26s\n", real_name);
#ifdef NICKNAME
printf("Nickname: %-30s", nickname);
#endif
! printf("Home phone: %-28s\n", home_phone);
printf("Office: %-32s", office);
! printf("Office phone: %-26s\n", office_phone);
#ifdef HOMEDIR_AND_SHELL
printf("Directory: %-29s", home_dir);
! printf("Shell: %-33s\n", shell);
#endif
#ifdef EMAIL
printf("Electronic mail address: %s@ATHENA.MIT.EDU\n", username);
--- 232,247 ----
get_office_phone(user, office_phone, sizeof(office_phone));
printf("Login name: %-28s", username);
! printf("In real life: %s\n", real_name);
#ifdef NICKNAME
printf("Nickname: %-30s", nickname);
#endif
! printf("Home phone: %s\n", home_phone);
printf("Office: %-32s", office);
! printf("Office phone: %s\n", office_phone);
#ifdef HOMEDIR_AND_SHELL
printf("Directory: %-29s", home_dir);
! printf("Shell: %s\n", shell);
#endif
#ifdef EMAIL
printf("Electronic mail address: %s@ATHENA.MIT.EDU\n", username);
*** 1.2 1989/01/31 04:38:53
--- db_lookup.c 1993/03/01 18:03:10
***************
*** 53,60 ****
if (! db_file)
db_file = DB_FILE;
! if ((type != 0) && (type != 'U') && (type != 'F') && (type != 'L')) {
! fprintf(stderr, "%s: incorrect lookup type: must be U, F, or L\n",
whoami);
usage();
exit(1);
--- 53,60 ----
if (! db_file)
db_file = DB_FILE;
! if ((type != 0) && (type != 'U') && (type != 'N')) {
! fprintf(stderr, "%s: incorrect lookup type: must be U or N\n",
whoami);
usage();
exit(1);
***************
*** 112,134 ****
printf("\n\n");
}
}
! if ((type == 0) || (type == 'F')) {
! uids = lookup_name(db, name, 'F', &size);
if (uids) {
! printf("Matching first names:\n\n");
print_uids(db, uids, size);
printf("\n\n");
}
}
- if ((type == 0) || (type == 'L')) {
- uids = lookup_name(db, name, 'L', &size);
- if (uids) {
- printf("Matching last names:\n\n");
- print_uids(db, uids, size);
- printf("\n\n");
- }
- }
-
return(0);
}
--- 112,125 ----
printf("\n\n");
}
}
! if ((type == 0) || (type == 'N')) {
! uids = lookup_name(db, name, 'N', &size);
if (uids) {
! printf("Matching names:\n\n");
print_uids(db, uids, size);
printf("\n\n");
}
}
return(0);
}
***************
*** 141,153 ****
int *size; /* RETURN */
{
datum key, entry;
! char key_string[MAX_KEY_LEN];
static data_array[MAX_MATCH];
key.dptr = key_string;
*key.dptr = type;
! strncpy(key.dptr + 1, name, MAX_KEY_LEN - 2);
! key.dptr[MAX_KEY_LEN - 1] = '\0';
key.dsize = strlen(key.dptr) + 1;
entry = dbm_fetch(db, key);
--- 132,144 ----
int *size; /* RETURN */
{
datum key, entry;
! char key_string[MAX_KEY_LEN+1];
static data_array[MAX_MATCH];
key.dptr = key_string;
*key.dptr = type;
! strncpy(key.dptr + 1, name, MAX_KEY_LEN - 1);
! key.dptr[MAX_KEY_LEN] = '\0';
key.dsize = strlen(key.dptr) + 1;
entry = dbm_fetch(db, key);
***************
*** 175,181 ****
char key_string[sizeof(int) + 2];
key.dptr = key_string;
! *key.dptr = 'N';
key.dsize = sizeof(int) + 2;
for (i = 0; i < size; i++) {
--- 166,172 ----
char key_string[sizeof(int) + 2];
key.dptr = key_string;
! *key.dptr = '#';
key.dsize = sizeof(int) + 2;
for (i = 0; i < size; i++) {
Jonathan Kamens Geer Zolot Associates jik@GZA.COM