This patch cleans up the ident stuff in inetd. The code which has
been patched so many times it was a bit of a mess. There are style, code and man page cleanups. The following are the functional changes: The RFC only permits the returning of 4 possible error codes, make sure we only return these (PR 27636). Use MAXLOGNAME to determine the longest usernames. Add a -i flag, which returns the uid instead of the username (this is from a PR 25787, which also contained alot of the cleanups in this patch). PR: 25787, 27636 Partially Submitted by: Arne.Dag.Fidjestol@idi.ntnu.no Reviewed by: Arne.Dag.Fidjestol@idi.ntnu.no, green MFC after: 3 weeks
This commit is contained in:
parent
0becf102d7
commit
9a0b3389d5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=77684
@ -306,15 +306,21 @@ echo_stream(s, sep) /* Echo service -- echo data back */
|
|||||||
* support.
|
* support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* RFC 1413 says the following are the only errors you can return. */
|
||||||
|
#define ID_INVALID "INVALID-PORT" /* Port number improperly specified. */
|
||||||
|
#define ID_NOUSER "NO-USER" /* Port not in use/not identifable. */
|
||||||
|
#define ID_HIDDEN "HIDDEN-USER" /* Hiden at user's request. */
|
||||||
|
#define ID_UNKNOWN "UNKNOWN-ERROR" /* Everything else. */
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
iderror(lport, fport, s, er) /* Generic ident_stream error-sending func */
|
iderror(lport, fport, s, er) /* Generic ident_stream error-sending func */
|
||||||
int lport, fport, s, er;
|
int lport, fport, s;
|
||||||
|
char *er;
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
asprintf(&p, "%d , %d : ERROR : %s\r\n", lport, fport,
|
asprintf(&p, "%d , %d : ERROR : %s\r\n", lport, fport, er);
|
||||||
er == -1 ? "HIDDEN-USER" : er ? strerror(er) : "UNKNOWN-ERROR");
|
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
syslog(LOG_ERR, "asprintf: %m");
|
syslog(LOG_ERR, "asprintf: %m");
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
@ -345,13 +351,13 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
}, to;
|
}, to;
|
||||||
struct passwd *pw = NULL;
|
struct passwd *pw = NULL;
|
||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
char buf[BUFSIZE], *cp = NULL, *p, **av, *osname = NULL, garbage[7], e;
|
char buf[BUFSIZE], *p, **av, *osname = NULL, e;
|
||||||
char *fallback = NULL;
|
char idbuf[MAXLOGNAME] = ""; /* Big enough to hold uid in decimal. */
|
||||||
socklen_t socklen;
|
socklen_t socklen;
|
||||||
ssize_t ssize;
|
ssize_t ssize;
|
||||||
size_t size, bufsiz;
|
size_t size, bufsiz;
|
||||||
int c, fflag = 0, nflag = 0, rflag = 0, argc = 0, usedfallback = 0;
|
int c, fflag = 0, nflag = 0, rflag = 0, argc = 0;
|
||||||
int gflag = 0, Fflag = 0, getcredfail = 0, onreadlen;
|
int gflag = 0, iflag = 0, Fflag = 0, getcredfail = 0, onreadlen;
|
||||||
u_short lport, fport;
|
u_short lport, fport;
|
||||||
|
|
||||||
inetd_setproctitle(sep->se_service, s);
|
inetd_setproctitle(sep->se_service, s);
|
||||||
@ -373,10 +379,11 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
size_t i;
|
size_t i;
|
||||||
u_int32_t random;
|
u_int32_t random;
|
||||||
|
|
||||||
while ((c = getopt(argc, sep->se_argv, "d:fFgno:rt:")) != -1)
|
while ((c = getopt(argc, sep->se_argv, "d:fFgino:rt:")) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'd':
|
case 'd':
|
||||||
fallback = optarg;
|
if (!gflag)
|
||||||
|
strlcpy(idbuf, optarg, sizeof(idbuf));
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
fflag = 1;
|
fflag = 1;
|
||||||
@ -394,21 +401,22 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
* gives a more optimal way to reload the
|
* gives a more optimal way to reload the
|
||||||
* random number only when necessary.
|
* random number only when necessary.
|
||||||
*
|
*
|
||||||
* I'm using base-36, so I need at least 6
|
* 32 bits from arc4random corrisponds to
|
||||||
* bits; round it up to 8 bits to make it
|
* about 6 base-36 digits, so we reseed evey 6.
|
||||||
* easier.
|
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < sizeof(garbage) - 1; i++) {
|
for (i = 0; i < sizeof(idbuf) - 1; i++) {
|
||||||
const char *const base36 =
|
static const char *const base36 =
|
||||||
"0123456789"
|
"0123456789"
|
||||||
"abcdefghijklmnopqrstuvwxyz";
|
"abcdefghijklmnopqrstuvwxyz";
|
||||||
if (i % (sizeof(random) * 8 / 8) == 0)
|
if (i % 6 == 0)
|
||||||
random = arc4random();
|
random = arc4random();
|
||||||
garbage[i] =
|
idbuf[i] = base36[random % 36];
|
||||||
base36[(random & 0xff) % 36];
|
random /= 36;
|
||||||
random >>= 8;
|
|
||||||
}
|
}
|
||||||
garbage[i] = '\0';
|
idbuf[i] = '\0';
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
iflag = 1;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
nflag = 1;
|
nflag = 1;
|
||||||
@ -423,6 +431,7 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
switch (sscanf(optarg, "%d.%d", &sec, &usec)) {
|
switch (sscanf(optarg, "%d.%d", &sec, &usec)) {
|
||||||
case 2:
|
case 2:
|
||||||
tv.tv_usec = usec;
|
tv.tv_usec = usec;
|
||||||
|
/* FALLTHROUGH */
|
||||||
case 1:
|
case 1:
|
||||||
tv.tv_sec = sec;
|
tv.tv_sec = sec;
|
||||||
break;
|
break;
|
||||||
@ -438,15 +447,10 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
}
|
}
|
||||||
if (osname == NULL) {
|
if (osname == NULL) {
|
||||||
if (uname(&un) == -1)
|
if (uname(&un) == -1)
|
||||||
iderror(0, 0, s, errno);
|
iderror(0, 0, s, ID_UNKNOWN);
|
||||||
osname = un.sysname;
|
osname = un.sysname;
|
||||||
}
|
}
|
||||||
socklen = sizeof(ss[0]);
|
|
||||||
if (getsockname(s, (struct sockaddr *)&ss[0], &socklen) == -1)
|
|
||||||
iderror(0, 0, s, errno);
|
|
||||||
socklen = sizeof(ss[1]);
|
|
||||||
if (getpeername(s, (struct sockaddr *)&ss[1], &socklen) == -1)
|
|
||||||
iderror(0, 0, s, errno);
|
|
||||||
/*
|
/*
|
||||||
* We're going to prepare for and execute reception of a
|
* We're going to prepare for and execute reception of a
|
||||||
* packet of data from the user. The data is in the format
|
* packet of data from the user. The data is in the format
|
||||||
@ -476,14 +480,14 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
break;
|
break;
|
||||||
FD_SET(s, &fdset);
|
FD_SET(s, &fdset);
|
||||||
if (select(s + 1, &fdset, NULL, NULL, &tv) == -1)
|
if (select(s + 1, &fdset, NULL, NULL, &tv) == -1)
|
||||||
iderror(0, 0, s, errno);
|
iderror(0, 0, s, ID_UNKNOWN);
|
||||||
if (ioctl(s, FIONREAD, &onreadlen) == -1)
|
if (ioctl(s, FIONREAD, &onreadlen) == -1)
|
||||||
iderror(0, 0, s, errno);
|
iderror(0, 0, s, ID_UNKNOWN);
|
||||||
if (onreadlen > bufsiz)
|
if (onreadlen > bufsiz)
|
||||||
onreadlen = bufsiz;
|
onreadlen = bufsiz;
|
||||||
ssize = read(s, &buf[size], (size_t)onreadlen);
|
ssize = read(s, &buf[size], (size_t)onreadlen);
|
||||||
if (ssize == -1)
|
if (ssize == -1)
|
||||||
iderror(0, 0, s, errno);
|
iderror(0, 0, s, ID_UNKNOWN);
|
||||||
else if (ssize == 0)
|
else if (ssize == 0)
|
||||||
break;
|
break;
|
||||||
bufsiz -= ssize;
|
bufsiz -= ssize;
|
||||||
@ -494,37 +498,38 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
buf[size] = '\0';
|
buf[size] = '\0';
|
||||||
/* Read two characters, and check for a delimiting character */
|
/* Read two characters, and check for a delimiting character */
|
||||||
if (sscanf(buf, "%hu , %hu%c", &lport, &fport, &e) != 3 || isdigit(e))
|
if (sscanf(buf, "%hu , %hu%c", &lport, &fport, &e) != 3 || isdigit(e))
|
||||||
iderror(0, 0, s, 0);
|
iderror(0, 0, s, ID_INVALID);
|
||||||
if (gflag) {
|
|
||||||
cp = garbage;
|
/* Send garbage? */
|
||||||
|
if (gflag)
|
||||||
goto printit;
|
goto printit;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If not "real" (-r), send a HIDDEN-USER error for everything.
|
* If not "real" (-r), send a HIDDEN-USER error for everything.
|
||||||
* If -d is used to set a fallback username, this is used to
|
* If -d is used to set a fallback username, this is used to
|
||||||
* override it, and the fallback is returned instead.
|
* override it, and the fallback is returned instead.
|
||||||
*/
|
*/
|
||||||
if (!rflag) {
|
if (!rflag) {
|
||||||
if (fallback == NULL)
|
if (*idbuf == '\0')
|
||||||
iderror(lport, fport, s, -1);
|
iderror(lport, fport, s, ID_HIDDEN);
|
||||||
else {
|
goto printit;
|
||||||
cp = fallback;
|
|
||||||
goto printit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We take the input and construct an array of two sockaddr_ins
|
* We take the input and construct an array of two sockaddr_ins
|
||||||
* which contain the local address information and foreign
|
* which contain the local address information and foreign
|
||||||
* address information, respectively, used to look up the
|
* address information, respectively, used to look up the
|
||||||
* credentials for the socket (which are returned by the
|
* credentials for the socket (which are returned by the
|
||||||
* sysctl "net.inet.tcp.getcred" when we call it.) The
|
* sysctl "net.inet.tcp.getcred" when we call it.)
|
||||||
* arrays have been filled in above via get{peer,sock}name(),
|
|
||||||
* so right here we are only setting the ports.
|
|
||||||
*/
|
*/
|
||||||
|
socklen = sizeof(ss[0]);
|
||||||
|
if (getsockname(s, (struct sockaddr *)&ss[0], &socklen) == -1)
|
||||||
|
iderror(lport, fport, s, ID_UNKNOWN);
|
||||||
|
socklen = sizeof(ss[1]);
|
||||||
|
if (getpeername(s, (struct sockaddr *)&ss[1], &socklen) == -1)
|
||||||
|
iderror(lport, fport, s, ID_UNKNOWN);
|
||||||
if (ss[0].ss_family != ss[1].ss_family)
|
if (ss[0].ss_family != ss[1].ss_family)
|
||||||
iderror(lport, fport, s, EINVAL);
|
iderror(lport, fport, s, ID_UNKNOWN);
|
||||||
size = sizeof(uc);
|
size = sizeof(uc);
|
||||||
switch (ss[0].ss_family) {
|
switch (ss[0].ss_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
@ -552,48 +557,54 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (getcredfail != 0) {
|
if (getcredfail != 0) {
|
||||||
if (fallback == NULL) /* Use a default, if asked to */
|
if (*idbuf == '\0')
|
||||||
iderror(lport, fport, s, getcredfail);
|
iderror(lport, fport, s,
|
||||||
usedfallback = 1;
|
getcredfail == ENOENT ? ID_NOUSER : ID_UNKNOWN);
|
||||||
} else {
|
goto printit;
|
||||||
/* Look up the pw to get the username */
|
|
||||||
errno = 0;
|
|
||||||
pw = getpwuid(uc.cr_uid);
|
|
||||||
}
|
}
|
||||||
if (pw == NULL && !usedfallback) /* No such user... */
|
|
||||||
iderror(lport, fport, s, errno != 0 ? errno : ENOENT);
|
/* Look up the pw to get the username and home directory*/
|
||||||
|
errno = 0;
|
||||||
|
pw = getpwuid(uc.cr_uid);
|
||||||
|
if (pw == NULL)
|
||||||
|
iderror(lport, fport, s, errno == 0 ? ID_NOUSER : ID_UNKNOWN);
|
||||||
|
|
||||||
|
if (iflag)
|
||||||
|
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned)pw->pw_uid);
|
||||||
|
else
|
||||||
|
strlcpy(idbuf, pw->pw_name, sizeof(idbuf));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If enabled, we check for a file named ".noident" in the user's
|
* If enabled, we check for a file named ".noident" in the user's
|
||||||
* home directory. If found, we return HIDDEN-USER.
|
* home directory. If found, we return HIDDEN-USER.
|
||||||
*/
|
*/
|
||||||
if (nflag && !usedfallback) {
|
if (nflag) {
|
||||||
if (asprintf(&p, "%s/.noident", pw->pw_dir) == -1)
|
if (asprintf(&p, "%s/.noident", pw->pw_dir) == -1)
|
||||||
iderror(lport, fport, s, errno);
|
iderror(lport, fport, s, ID_UNKNOWN);
|
||||||
if (lstat(p, &sb) == 0) {
|
if (lstat(p, &sb) == 0) {
|
||||||
free(p);
|
free(p);
|
||||||
iderror(lport, fport, s, -1);
|
iderror(lport, fport, s, ID_HIDDEN);
|
||||||
}
|
}
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here, if enabled, we read a user's ".fakeid" file in their
|
* Here, if enabled, we read a user's ".fakeid" file in their
|
||||||
* home directory. It consists of a line containing the name
|
* home directory. It consists of a line containing the name
|
||||||
* they want.
|
* they want.
|
||||||
*/
|
*/
|
||||||
if (fflag && !usedfallback) {
|
if (fflag) {
|
||||||
FILE *fakeid = NULL;
|
|
||||||
int fakeid_fd;
|
int fakeid_fd;
|
||||||
|
|
||||||
if (asprintf(&p, "%s/.fakeid", pw->pw_dir) == -1)
|
|
||||||
iderror(lport, fport, s, errno);
|
|
||||||
/*
|
/*
|
||||||
* Here we set ourself to effectively be the user, so we don't
|
* Here we set ourself to effectively be the user, so we don't
|
||||||
* open any files we have no permission to open, especially
|
* open any files we have no permission to open, especially
|
||||||
* symbolic links to sensitive root-owned files or devices.
|
* symbolic links to sensitive root-owned files or devices.
|
||||||
*/
|
*/
|
||||||
if (initgroups(pw->pw_name, pw->pw_gid) == -1)
|
if (initgroups(pw->pw_name, pw->pw_gid) == -1)
|
||||||
iderror(lport, fport, s, errno);
|
iderror(lport, fport, s, ID_UNKNOWN);
|
||||||
seteuid(pw->pw_uid);
|
if (seteuid(pw->pw_uid) == -1)
|
||||||
|
iderror(lport, fport, s, ID_UNKNOWN);
|
||||||
/*
|
/*
|
||||||
* We can't stat() here since that would be a race
|
* We can't stat() here since that would be a race
|
||||||
* condition.
|
* condition.
|
||||||
@ -601,60 +612,58 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
|||||||
* and if it's not a regular file, we close it and end up
|
* and if it's not a regular file, we close it and end up
|
||||||
* returning the user's real username.
|
* returning the user's real username.
|
||||||
*/
|
*/
|
||||||
|
if (asprintf(&p, "%s/.fakeid", pw->pw_dir) == -1)
|
||||||
|
iderror(lport, fport, s, ID_UNKNOWN);
|
||||||
fakeid_fd = open(p, O_RDONLY | O_NONBLOCK);
|
fakeid_fd = open(p, O_RDONLY | O_NONBLOCK);
|
||||||
free(p);
|
free(p);
|
||||||
if (fakeid_fd != -1 && fstat(fakeid_fd, &sb) != -1 &&
|
if (fakeid_fd == -1 || fstat(fakeid_fd, &sb) == -1 ||
|
||||||
S_ISREG(sb.st_mode) &&
|
!S_ISREG(sb.st_mode))
|
||||||
(fakeid = fdopen(fakeid_fd, "r")) != NULL) {
|
goto fakeid_fail;
|
||||||
buf[sizeof(buf) - 1] = '\0';
|
|
||||||
if (fgets(buf, sizeof(buf), fakeid) == NULL) {
|
if ((ssize = read(fakeid_fd, buf, sizeof(buf) - 1)) < 0)
|
||||||
cp = pw->pw_name;
|
goto fakeid_fail;
|
||||||
fclose(fakeid);
|
buf[ssize] = '\0';
|
||||||
goto printit;
|
|
||||||
|
/*
|
||||||
|
* Usually, the file will have the desired identity
|
||||||
|
* in the form "identity\n". Allow for leading white
|
||||||
|
* space and trailing white space/end of line.
|
||||||
|
*/
|
||||||
|
p = buf;
|
||||||
|
p += strspn(p, " \t");
|
||||||
|
p[strcspn(p, " \t\r\n")] = '\0';
|
||||||
|
if (strlen(p) > MAXLOGNAME - 1) /* Too long (including nul)? */
|
||||||
|
p[MAXLOGNAME - 1] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the name is a zero-length string or matches it
|
||||||
|
* the id or name of another user (unless permitted by -F)
|
||||||
|
* then it is invalid.
|
||||||
|
*/
|
||||||
|
if (*p == '\0')
|
||||||
|
goto fakeid_fail;
|
||||||
|
if (!Fflag) {
|
||||||
|
if (iflag) {
|
||||||
|
if (p[strspn(p, "0123456789")] == '\0' &&
|
||||||
|
getpwuid(atoi(p)) != NULL)
|
||||||
|
goto fakeid_fail;
|
||||||
|
} else {
|
||||||
|
if (getpwnam(p) != NULL)
|
||||||
|
goto fakeid_fail;
|
||||||
}
|
}
|
||||||
/*
|
}
|
||||||
* Usually, the file will have the desired identity
|
|
||||||
* in the form "identity\n", so we use strcspn() to
|
strlcpy(idbuf, p, sizeof(idbuf));
|
||||||
* end the string (which fgets() doesn't do.)
|
|
||||||
*/
|
fakeid_fail:
|
||||||
buf[strcspn(buf, "\r\n")] = '\0';
|
if (fakeid_fd != -1)
|
||||||
cp = buf;
|
|
||||||
/* Allow for beginning white space... */
|
|
||||||
while (isspace(*cp))
|
|
||||||
cp++;
|
|
||||||
/* ...and ending white space. */
|
|
||||||
cp[strcspn(cp, " \t")] = '\0';
|
|
||||||
/* User names of >16 characters are invalid */
|
|
||||||
if (strlen(cp) > 16)
|
|
||||||
cp[16] = '\0';
|
|
||||||
/*
|
|
||||||
* If the name is a zero-length string or matches
|
|
||||||
* the name of another user, it's invalid, so
|
|
||||||
* we will return their real identity instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!*cp || (!Fflag && getpwnam(cp))) {
|
|
||||||
errno = 0;
|
|
||||||
pw = getpwuid(uc.cr_uid);
|
|
||||||
if (pw == NULL)
|
|
||||||
iderror(lport, fport, s,
|
|
||||||
errno != 0 ? errno : ENOENT);
|
|
||||||
cp = pw->pw_name;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
cp = pw->pw_name;
|
|
||||||
if (fakeid != NULL)
|
|
||||||
fclose(fakeid);
|
|
||||||
else if (fakeid_fd != -1)
|
|
||||||
close(fakeid_fd);
|
close(fakeid_fd);
|
||||||
} else if (!usedfallback)
|
}
|
||||||
cp = pw->pw_name;
|
|
||||||
else
|
|
||||||
cp = fallback;
|
|
||||||
printit:
|
printit:
|
||||||
/* Finally, we make and send the reply. */
|
/* Finally, we make and send the reply. */
|
||||||
if (asprintf(&p, "%d , %d : USERID : %s : %s\r\n", lport, fport, osname,
|
if (asprintf(&p, "%d , %d : USERID : %s : %s\r\n", lport, fport, osname,
|
||||||
cp) == -1) {
|
idbuf) == -1) {
|
||||||
syslog(LOG_ERR, "asprintf: %m");
|
syslog(LOG_ERR, "asprintf: %m");
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
|
@ -455,6 +455,21 @@ If the real
|
|||||||
service is disabled,
|
service is disabled,
|
||||||
return this username for every request.
|
return this username for every request.
|
||||||
This is primarily useful when running this service on a NAT machine.
|
This is primarily useful when running this service on a NAT machine.
|
||||||
|
.It Fl g
|
||||||
|
Instead of returning
|
||||||
|
the user's name to the ident requester,
|
||||||
|
report a
|
||||||
|
username made up of random alphanumeric characters,
|
||||||
|
e.g.
|
||||||
|
.Dq c0c993 .
|
||||||
|
The
|
||||||
|
.Fl g
|
||||||
|
flag overrides not only the user names,
|
||||||
|
but also any fallback name,
|
||||||
|
.Pa .fakeid
|
||||||
|
or
|
||||||
|
.Pa .noident
|
||||||
|
files.
|
||||||
.It Fl t Xo
|
.It Fl t Xo
|
||||||
.Ar sec Ns Op . Ns Ar usec
|
.Ar sec Ns Op . Ns Ar usec
|
||||||
.Xc
|
.Xc
|
||||||
@ -465,6 +480,8 @@ Offer a real
|
|||||||
.Dq auth
|
.Dq auth
|
||||||
service, as per RFC 1413.
|
service, as per RFC 1413.
|
||||||
All the remaining flags apply only in this case.
|
All the remaining flags apply only in this case.
|
||||||
|
.It Fl i
|
||||||
|
Return numeric user IDs instead of usernames.
|
||||||
.It Fl f
|
.It Fl f
|
||||||
If the file
|
If the file
|
||||||
.Pa .fakeid
|
.Pa .fakeid
|
||||||
@ -474,29 +491,25 @@ If the the username found in
|
|||||||
.Pa .fakeid
|
.Pa .fakeid
|
||||||
is that of an existing user,
|
is that of an existing user,
|
||||||
then the real username is reported.
|
then the real username is reported.
|
||||||
|
If the
|
||||||
|
.Fl i
|
||||||
|
flag is also given then the username in
|
||||||
|
.Pa .fakeid
|
||||||
|
is checked against existing user IDs instead.
|
||||||
.It Fl F
|
.It Fl F
|
||||||
same as
|
same as
|
||||||
.Fl f
|
.Fl f
|
||||||
but without the restriction that the username in
|
but without the restriction that the username in
|
||||||
.Pa .fakeid
|
.Pa .fakeid
|
||||||
must not match an existing user.
|
must not match an existing user.
|
||||||
.It Fl g
|
|
||||||
Instead of returning the user's name to the ident requester, report a
|
|
||||||
username made up of random alphanumeric characters, e.g.
|
|
||||||
.Dq c0c993 .
|
|
||||||
The
|
|
||||||
.Fl g
|
|
||||||
flag overrides not only the user names, but also any
|
|
||||||
.Pa .fakeid
|
|
||||||
or
|
|
||||||
.Pa .noident
|
|
||||||
files.
|
|
||||||
.It Fl n
|
.It Fl n
|
||||||
If the file
|
If the file
|
||||||
.Pa .noident
|
.Pa .noident
|
||||||
exists in the home directory of the identified user, return
|
exists in the home directory of the identified user, return
|
||||||
.Dq ERROR\ : HIDDEN-USER .
|
.Dq ERROR\ : HIDDEN-USER .
|
||||||
instead.
|
This overrides any
|
||||||
|
.Pa fakeid
|
||||||
|
file which might exist.
|
||||||
.It Fl o Ar osname
|
.It Fl o Ar osname
|
||||||
Use
|
Use
|
||||||
.Ar osname
|
.Ar osname
|
||||||
|
@ -122,7 +122,7 @@ void endconfig __P((void));
|
|||||||
struct servtab *enter __P((struct servtab *));
|
struct servtab *enter __P((struct servtab *));
|
||||||
void freeconfig __P((struct servtab *));
|
void freeconfig __P((struct servtab *));
|
||||||
struct servtab *getconfigent __P((void));
|
struct servtab *getconfigent __P((void));
|
||||||
void iderror __P((int, int, int, int));
|
void iderror __P((int, int, int, char *));
|
||||||
void ident_stream __P((int, struct servtab *));
|
void ident_stream __P((int, struct servtab *));
|
||||||
void machtime_dg __P((int, struct servtab *));
|
void machtime_dg __P((int, struct servtab *));
|
||||||
void machtime_stream __P((int, struct servtab *));
|
void machtime_stream __P((int, struct servtab *));
|
||||||
|
Loading…
Reference in New Issue
Block a user