summaryrefslogtreecommitdiff
path: root/debian/patches/02-518559-nsswitch-sources.patch
blob: 95f9c38e336305645b049d5f5140013a47770b58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=518559

Doesn't work with a non-iterable nsswitch source

Currently, "finger tabbott" works by iterating through the list of users 
on the system using getpwent and checking if any of them match "tabbott".  

Some nsswitch backends (including Hesiod and LDAP[1]) do not support 
iterating through the complete list of users.  These nsswitch backends 
instead only fully support looking up a user's information by username or 
uid.

So, if tabbott is a user whose nsswitch information comes from LDAP, then 
"finger tabbott" will incorrectly report "finger: tabbott: no such user."  
"finger -m tabbott" does work correctly, however, because it looks up the 
matching username using getpwnam.
                                                                                    
A fix for this is to always look up an argument to finger for a username 
match, and having -m only control whether finger searches the entire user 
database for real name matches.  Patch attached.

This patch has the advantageous side effect that if there are some real 
name matches and a username match, finger will always display the username 
match first (rather than in some random place in the list).

    -Tim Abbott

[1] with LDAP, it is typically the case that one can iterate through only 
the first 100 results from a query.

Tim Abbott <tabbott@MIT.EDU>

commit ab0b4e09b1281a11587fd0f9797e612cfb08ef57
Author: Timothy G Abbott <tabbott@mit.edu>
Date:   Fri Mar 6 22:30:00 2009 -0500

    Add support for non-iterable nsswitch sources.
    
    Signed-off-by: Timothy G Abbott <tabbott@mit.edu>

diff --git a/finger/finger.c b/finger/finger.c
index 7b96d3c..5737782 100644
--- a/finger/finger.c
+++ b/finger/finger.c
@@ -241,28 +241,35 @@ static void do_local(int argc, char *argv[], int *used) {
 	int i;
 	struct passwd *pw;
 
+	for (i = 0; i < argc; i++) {
+		if (used[i] >= 0 && (pw = getpwnam(argv[i]))) {
+			if (!check_nofinger(pw)) {
+				enter_person(pw);
+				used[i] = 1;
+			}
+		}
+	}
 	/*
-	 * traverse the list of possible login names and check the login name
-	 * and real name against the name specified by the user.
+	 * Traverse the list of users and check the real name against
+	 * the name specified by the user.
+	 *
+	 * Since we've already entered users whose usernames match,
+	 * ignore them when doing real name matching.
 	 */
-	if (mflag) {
-		for (i = 0; i < argc; i++)
-			if (used[i] >= 0 && (pw = getpwnam(argv[i]))) {
-				if (!check_nofinger(pw)) {
-					enter_person(pw);
-					used[i] = 1;
-				}
-			}
-	} else for (pw = getpwent(); pw; pw = getpwent())
-		for (i = 0; i < argc; i++)
-			if (used[i] >= 0 &&
-			    (!strcasecmp(pw->pw_name, argv[i]) ||
-			    match(pw, argv[i]))) {
-				if (!check_nofinger(pw)) {
-					enter_person(pw);
-					used[i] = 1;
+	if (!mflag) {
+		for (pw = getpwent(); pw; pw = getpwent()) {
+			for (i = 0; i < argc; i++) {
+				if (used[i] >= 0 &&
+				    strcasecmp(pw->pw_name, argv[i]) &&
+				    match(pw, argv[i])) {
+					if (!check_nofinger(pw)) {
+						enter_person(pw);
+						used[i] = 1;
+					}
 				}
 			}
+		}
+	}
 
 	/* list errors */
 	for (i = 0; i < argc; i++)