2 * auth_pass.c ( $Revision: 6141 $ )
6 * This module is the complete source for a sample "authinfo generic"
7 * program. This program takes a user's login name and password
8 * (supplied either as arguments or as responses to prompts) and
9 * validates them against the contents of the password database.
11 * If the user properly authenticates themselves, a nnrp.auth style
12 * record indicating the user's authenticated login and permitting
13 * reading and posting to all groups is output on stderr (for reading by
14 * nnrpd) and the program exits with a 0 status. If the user fails to
15 * authenticate, then a record with the attempted login name and no
16 * access is output on stderr and a non-zero exit status is returned.
19 * 0 Successfully authenticated.
20 * 1 getpeername() failed, returned a bad address family, or
21 * gethostbyaddr() failed.
22 * 2 Entry not found in password file.
23 * 3 No permission to read passwords, or password field is '*'.
24 * 4 Bad password match.
27 * Run by nnrpd with stdin/stdout connected to the reader and stderr
28 * connected back to nnrpd. This program will need to be run as suid
29 * root on systems where passwords are stored in a file readable only by
32 * Written 1996 July 6 by Douglas Wade Needham (dneedham@oucsace.cs.ohiou.edu).
38 #include "portable/socket.h"
43 main(int argc, char** argv)
46 * Main routine of the program, implementing all prompting, validation,
50 * argc Argument count.
51 * argv Null terminated argument vector.
54 * Exits according to program status values.
57 * hp Pointer to host entry.
58 * length General integer variable
59 * password Password given by user.
60 * peername Hostname of the peer.
61 * pwd Pointer to entry from passwd file.
62 * sin Socket address structure.
63 * username User's login name.
71 struct sockaddr_in sin;
75 * Get the user name and password if needed.
78 fprintf(stdout, "Username: "); fflush(stdout);
79 fgets(username, sizeof(username), stdin);
81 strlcpy(username, argv[1], sizeof(username));
84 fprintf(stdout, "Password: "); fflush(stdout);
85 fgets(password, sizeof(password), stdin);
87 strlcpy(password, argv[2], sizeof(password));
91 * Strip CR's and NL's from the end.
93 length = strlen(username)-1;
94 while (username[length] == '\r' || username[length] == '\n') {
95 username[length--] = '\0';
97 length = strlen(password)-1;
98 while (password[length] == '\r' || password[length] == '\n') {
99 password[length--] = '\0';
103 * Get the hostname of the peer.
105 length = sizeof(sin);
106 if (getpeername(0, (struct sockaddr *)&sin, &length) < 0) {
108 fprintf(stderr, "cant getpeername()::%s:+:!*\n", username);
111 strlcpy(peername, "stdin", sizeof(peername));
112 } else if (sin.sin_family != AF_INET) {
113 fprintf(stderr, "Bad address family %ld::%s:+:!*\n",
114 (long)sin.sin_family, username);
116 } else if ((hp = gethostbyaddr((char *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET)) == NULL) {
117 strlcpy(peername, inet_ntoa(sin.sin_addr), sizeof(peername));
119 strlcpy(peername, hp->h_name, sizeof(peername));
123 * Get the user name in the passwd file.
125 if ((pwd = getpwnam(username)) == NULL) {
128 * No entry in the passwd file.
130 fprintf(stderr, "%s::%s:+:!*\n", peername, username);
135 * Make sure we managed to read in the password.
137 if (strcmp(pwd->pw_passwd, "*")==0) {
140 * No permission to read passwords.
142 fprintf(stderr, "%s::%s:+:!*\n", peername, username);
147 * Verify the password.
149 if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd))!=0) {
152 * Password was invalid.
154 fprintf(stderr, "%s::%s:+:!*\n", peername, username);
159 * We managed to authenticate the user.
161 fprintf(stderr, "%s:RP:%s:+:*\n", peername, username);